#ifndef BLOCKBUSITEM_H
#define BLOCKBUSITEM_H

#include "blockitem.h"


class BlockBusItem: public QGraphicsObject, public PropertyStorage {
	//Q_OBJECT
	Q_INTERFACES(QGraphicsItem)
	//Q_PROPERTY(double width READ width WRITE setWidth)
	friend class BlockView;
public:
	BlockBusItem(bool temp = false);
	BlockBusItem(const BlockBusItem & other);
	~BlockBusItem() {;}
	
	void setGridStep(double gs) {grid_step = gs;}
	void setEndpointsNumber(int num) {max_ep = num;}
	void setImages(const QImage & bus, const QImage & end = QImage()) {im_bus = bus; im_end = end;}
	void setBusType(int type_) {bus_type = type_;}
	void setBusName(const QString & name) {bus_name = name;}
	int busType() const {return bus_type;}
	QString busName() const {return bus_name;}
	void appendPoint(const QPointF & p);
	void appendPoint(qreal x, qreal y) {appendPoint(QPointF(x, y));}
	void testPoint(QPointF pos, int * sel_point, int * sel_segment);
	void clear();
	/*void setStart(const QPointF & p) {pol[0] = p; scene()->update();}
	void setStart(qreal x, qreal y) {setStart(QPointF(x, y));}
	void setFinish(const QPointF & p) {pol[pol.size() - 1] = p; scene()->update();}
	void setFinish(qreal x, qreal y) {setFinish(QPointF(x, y));}
	void setPoint(int index, const QPointF & p) {pol[index] = p; scene()->update();}
	void setPoint(int index, qreal x, qreal y) {setPoint(index, QPointF(x, y));}*/
	void setPen(const QPen & p) {p_ = p; update();}
	QPen pen() const {return p_;}
	void setBrush(const QBrush & b) {b_ = b; update();}
	QBrush brush() const {return b_;}
	//void disconnectBrick() {BrickBase::disconnect(brickFrom, portFrom, brickTo, portTo);}
	void movePolyline(const QPointF & dp) {pol.translate(dp); prepareGeometryChange();}
	void movePoint(int index, const QPointF & dp) {pol[index] += dp; prepareGeometryChange();}
	double width() const {return pen_width;}
	void setWidth(const double & w) {pen_width = w; update();}
	void setColor(const QColor & c) {pu.setColor(c); bu.setColor(c); update();}
	int addPoint(const QPointF & point, bool update = true);
	int segmentPointPair(int point) const;
	void removePoint(int index);
	void removeSegment(int index);
	void markAsInput();
	void markAsOutput();
	void unmark();
	void simplify();
	void adjustLine();
	int endpointCount() const;
	bool isBusSelected() const {return selSegment >= 0 || selPoint >= 0;}
	QList<BlockItem * > connectedBlocks() const;
	QList<BlockItemPin * > connectedPins() const;
	
	void setBusState(bool state);
	bool busState() const {return state_ > 0;}
	void clearBusState();
	
	QByteArray save() const;
	void load(const QByteArray & data);
	BlockBusItem * copy() const;
	
	enum {Type = UserType + 2};
	
protected:
	void _init();
	void reconnect();
	void updateGeometry();
	void checkDelete();
	void emitAction(BlockItemBase::Action a);
	QVector<int> endpoints() const;
	int pointSegments(int point) const;
	int type() const {return Type;}
	QRectF boundingRect() const;
	bool sceneEvent(QEvent * e);
	void hoverEnterEvent(QGraphicsSceneHoverEvent * e);
	void hoverMoveEvent(QGraphicsSceneHoverEvent * e);
	void hoverLeaveEvent(QGraphicsSceneHoverEvent * e);
	void mousePressEvent(QGraphicsSceneMouseEvent * e);
	void mouseMoveEvent(QGraphicsSceneMouseEvent * e);
	void mouseReleaseEvent(QGraphicsSceneMouseEvent * e);
	void paint(QPainter * p, const QStyleOptionGraphicsItem * o, QWidget * w = 0);
	
	QPointF lp, new_start, new_end, press_pos, qp;
	QPen p_, ph, pu, pa, pr, pn;
	QBrush b_, bh, bu, ba, br;
	QString tt, bus_name;
	QList<QPair<int, int> > segments, ends_ind;
	QMap<int, BlockItemPin * > connections_;
	QVector<int> ends;
	QImage im_bus, im_end;
	QPolygonF pol, bpol;
	Qt::KeyboardModifiers mm_mods;
	bool temp_;
	double pen_width, grid_step;
	int selPoint, selSegment, max_ep, bus_type, state_;
	bool moved, deleted, mark_in, mark_out, new_segment, mm_cancel, lm_point;
	
};


inline QDataStream & operator <<(QDataStream & s, const BlockBusItem * b) {s << b->save(); return s;}
inline QDataStream & operator >>(QDataStream & s, BlockBusItem *& b) {
	QByteArray ba; s >> ba;
	b = new BlockBusItem();
	b->load(ba);
	return s;
}


#endif // BLOCKBUSITEM_H
