/*
	QAD - Qt ADvanced

	Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef BLOCKITEMPIN_H
#define BLOCKITEMPIN_H

#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsObject>
#include <QGraphicsEllipseItem>
#include <QGraphicsSceneHoverEvent>
#include <QGraphicsSceneMouseEvent>
#include <QStack>
#include <QDebug>
#include <QPropertyAnimation>
#include <qmath.h>
#include "blockbase.h"
#include "alignedtextitem.h"


class BlockItem;
class BlockBusItem;


class QAD_EXPORT BlockItemPin: public QGraphicsObject, public PropertyStorage
{
	friend class BlockView;
	friend class BlockItem;
	Q_OBJECT
	Q_PROPERTY(double pinSize READ pinSize WRITE resizePin DESIGNABLE false SCRIPTABLE false)
public:
	BlockItemPin(Qt::Alignment a = Qt::AlignLeft, int bus_type = 0, const QString & text_ = QString(), QGraphicsObject * parent_ = 0);

	enum State {
		Disconnected,
		Connected,
		Hover,
		Drop,
		Accept,
		Reject
	};

	enum Direction {
		None = 0x0,
		Input = 0x1,
		Output = 0x2,
		InputOutput = 0x3
	};

	void setPen(const QPen & p) {ell_item.setPen(p);}
	QPen pen() const {return ell_item.pen();}
	void setBrush(const QBrush & b) {ell_item.setBrush(b);}
	QBrush brush() const {return ell_item.brush();}

	int busType() const {return bus_type;}
	Qt::Alignment alignment() const {return align;}
	Direction direction() const {return dir;}
	QString text() const {return text_item.text();}
	State state() const {return state_;}

	void setBusType(int type_) {bus_type = type_;}
	void setAlignment(Qt::Alignment a) {align = a; _init(true);}
	void setDirection(Direction d) {dir = d; _init(true);}
	void setText(const QString & t) {text_item.setText(t); _init(true);}
	void setState(State s);

	void saveState() {sstate_.push(state_);}
	bool restoreState() {if (sstate_.isEmpty()) return false; setState(sstate_.pop()); return true;}
	void clearStateStack() {sstate_.clear();}

	void enlargePin(bool enlarge);

	BlockItem * parent() const {return parent_;}
	QList<BlockBusItem * > connectedBuses() const {return buses_;}

	enum {Type = UserType + 3};

public slots:
	void animAccept();

protected:
	void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0) {}
	QRectF boundingRect() const {return ell_item.boundingRect().translated(ell_item.pos()) | text_item.boundingRect().translated(text_item.pos());}
	int type() const {return Type;}
	QVariant itemChange(GraphicsItemChange change, const QVariant & value);
	void hoverEnterEvent(QGraphicsSceneHoverEvent * e);
	void hoverLeaveEvent(QGraphicsSceneHoverEvent * e);
	void _init(bool affect_parent = false);
	void _reparent();
	QGraphicsView * _view() const;
	int bus_type;
	State state_;
	QGraphicsEllipseItem ell_item;
	QGraphicsSimpleTextItem text_item;
	QStack<State> sstate_;
	QList<BlockBusItem * > buses_;
	BlockItem * parent_;
	Qt::Alignment align;
	Direction dir;
	QBrush br[6];

private slots:
	void animationAccept();

private:
	void resizePin(double r);
	double pinSize() const;

	QPropertyAnimation anim_pin_size;
	QPropertyAnimation anim_accept;

};


#endif // BLOCKITEMPIN_H
