#ifndef ARROW2_H
#define ARROW2_H

#include < QGraphicsItem >
#include <QPainter>
#include "diagramitem.h"
#include "math.h"

QT_BEGIN_NAMESPACE
class QGraphicsPolygonItem;
class QGraphicsLineItem;
class QGraphicsScene;
class QRectF;
class QGraphicsSceneMouseEvent;
class QPainterPath;
class QGraphicsEllipseItem;
class QPainter;
class QPointF;
QT_END_NAMESPACE

const int MIN_WIDTH = 5;
const int MIN_HEIGHT = 5;
const int MAX_WIDTH = 1135;
const int MAX_HEIGHT = 805;
const qreal widthRectangle = 200;
const qreal heighRectangle = 100;


class Arrow2 : public QGraphicsItem
{
public:
        enum { Type = UserType + 4 };   //это вроде как ID
        enum TypeIn{up, back, down, front};

        struct parametrsArc
        {
            QRectF rect;
            int startAngle;
            int spanAngle;
        };

        Arrow2(DiagramItem *startItem, DiagramItem *endItem, QPointF pEnd, QGraphicsItem * parent = 0, bool isFlying = false, TypeIn flyinTypeArrow=up)
        {
                myStartItem=startItem;
                myEndItem = endItem;
                mypEnd=pEnd;
				myType = flyinTypeArrow;
                widthPen=3;
                R=25;
                widthRectangle=200;
                heighRectangle=100;
                if(!isFlying)
                    type2=claculateTypeIn(mypEnd, myEndItem);
                else
                    type2=flyinTypeArrow;
                isFlyingArrow = isFlying;
                flyingType = flyinTypeArrow;
                setFlag(QGraphicsItem::ItemIsSelectable,true);
        }
        //Только для НЕВИСЯЧИХ стрплок.
        Arrow2(DiagramItem *startItem, DiagramItem *endItem, TypeIn typeArrow, QGraphicsItem * parent = 0)
        {
                myStartItem=startItem;
                myEndItem = endItem;
                myType = typeArrow;
                type2=typeArrow;
                widthPen=3;
                R=25;
                widthRectangle=200;
                heighRectangle=100;
                //на всякий случай
                mypEnd=QPointF(0,0);
                isFlyingArrow = false;
                flyingType = up;
                setFlag(QGraphicsItem::ItemIsSelectable,true);
        }
        QRectF boundingRect() const
        {
                qreal penWidth = 5;
                //QList<QPointF> points = calculate_points();
                //return QRectF(lines.at(0).p1(), lines.at(2).p2()).normalized();
                return QRectF(0,0,5000,5000) //QRectF(myStartItem->pos(), myEndItem->pos());
                .normalized()
                .adjusted(-penWidth, -penWidth, penWidth, penWidth);
        }
        QPainterPath shape() const
        {

            QPainterPath path;
            for(int i=0; i<lines.count()-2; i++)
            {
                if(lines[i].angle() == 0 || lines[i].angle() == 180)
                {
                    if(lines[i].x1() < lines[i].x2())
                    {
                        path.addRect(QRectF(lines[i].x1(),lines[i].y1()-3,   lines[i].x2()-lines[i].x1(), 7));
                    }
                    else
                    {
                        path.addRect(QRectF(lines[i].x2(),lines[i].y1()-3,   lines[i].x1()-lines[i].x2(), 7));
                    }
                }
                else
                {
                    if(lines[i].y1() < lines[i].y2())
                    {
                         path.addRect(QRectF( lines[i].x2()-3,lines[i].y1(),   7, lines[i].y2()-lines[i].y1() ));
                    }
                    else
                    {
                         path.addRect(QRectF( lines[i].x2()-3,lines[i].y2(),   7, lines[i].y1()-lines[i].y2() ));
                    }
                }
            }
            for(int i=0; i<arcs.count(); i++)
            {
                //path.arcMoveTo(arcs[i].rect,0);
                //path.arcTo(arcs[i].rect,arcs[i].startAngle,arcs[i].spanAngle);
            }
            return path;
        }

        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
        {
            QPen pen;
            pen.setWidth(widthPen);
            painter->setPen(pen);
            //отрисовали
            for(int i=0; i<lines.count(); i++)
                painter->drawLine(lines[i]);
            for(int i=0; i<arcs.count(); i++)
                painter->drawArc(arcs.at(i).rect,  arcs.at(i).startAngle, arcs.at(i).spanAngle);
            //выделения
            if(isSelected())
            {
                painter->setPen(QPen(myColor, 1, Qt::DashLine));
                //линии
                for(int i=0; i<lines.count()-2; i++)
                {
                    QLineF myLine=lines.at(i);
                    if(myLine.angle() == 0 || myLine.angle() == 180)
                    {
                        myLine.translate(0, -4.0);
                        painter->drawLine(myLine);
                        myLine.translate(0, 8.0);
                        painter->drawLine(myLine);
                    }
                    else
                    {
                        myLine.translate(-4.0, 0);
                        painter->drawLine(myLine);
                        myLine.translate(8.0, 0);
                        painter->drawLine(myLine);
                    }
                }
                //арки
                for(int i=0; i<arcs.count(); i++)
                {/*
                    painter->translate(4.0,-4.0);
                    painter->drawArc(arcs.at(i).rect,  arcs.at(i).startAngle, arcs.at(i).spanAngle);
                    painter->translate(-8.0,8.0);
                    painter->drawArc(arcs.at(i).rect,  arcs.at(i).startAngle, arcs.at(i).spanAngle);
                 */
                }
            }
        }


        QPointF          getStartCoordinates(DiagramItem * Item, int shiftPixels); //ВОЗВРАЩАЕТ: координаты точки-выхода на блоке
        QPointF          getEndCoordinates(DiagramItem * Item, enum TypeIn _type); //ВОЗВРАЩАЕТ: координаты точки-входа на блоке

        QList<QLineF>    calculate_points();   //возвращает массив линий

        enum TypeIn      claculateTypeIn(QPointF mypEnd, DiagramItem *myEndItem);  //ВОЗВРАЩАЕТ: тип стрелки

        int              countOneTypeArrows(enum TypeIn _type, DiagramItem *item); //ВОЗВРАЩАЕТ: количество стрелок типа "_type"



        //QList<QLineF>    ifBack(struct ParametrsForArrow paramArrow);



        int              countOneTypeArrows_myStartItem(enum TypeIn _type);         //ВОЗВРАЩАЕТ: количество ВХОДЯЩИХ стрелок у myStartItem с типом = "_type"

struct ParametrsForArrow calculate_paramArrow();

//ОБЩИЕ ФУНКЦИИ
/*+*/   QPointF    blockPoint1( DiagramItem *Item, enum TypeIn _type );   //ВОЗВРАЩАЕТ: точку,лежащую на блоке
/*+*/   QPointF    blockPoint2( DiagramItem *Item, enum TypeIn _type );   //ВОЗВРАЩАЕТ: точку, отдаленную от блока
        QPointF    numLength();     //ВОЗВРАЩАЕТ: доп. точку для удлиннения
        QPointF    firstY(QPointF currentP);
        QPointF    firstX(QPointF currentP);
        QPointF    secondX(QPointF currentP);
  QList<QLineF>    makeArrow(QLineF lastLine);
  QList<parametrsArc>    makeArk(QList<QLineF> &baseLines, qreal R);    //ВОЗВРАЩАЕТ: дуги
  QList<QLineF>    cutLines(QList<QLineF> &baseLines,qreal r);   //обрезает конци линий на значение радуиса R
  QList<QLineF>    calculate_FlyingArrows();    //висящие стрелки
//ТОЛЬКО ДЛЯ StartItem
/*+*/   int        countStartArrows();    //ВОЗВРАЩАЕТ: количество стрелок на выходе myStartItem
/*+*/   int        indexStartInMass();    //ВОЗВРАЩАЕТ: порядковый номер стрелки в массиве

//ТОЛЬКО ДЛЯ EndItem
/*+*/   int        getEndArrowIndexInMassive(enum TypeIn _type);      //ВОЗВРАЩАЕТ: порядковый номер стрелки в блоке

        void setColor(const QColor &color)
            { myColor = color; }
        DiagramItem *startItem() const
            { return myStartItem; }
        DiagramItem *endItem() const
            { return myEndItem; }
        void setID(int id)
            { ID=id; }
        int getID() const
            { return ID; }
		QPointF endPoint() const
			{ return mypEnd; }
		void setEndPoint(DiagramItem * Item, enum TypeIn _type)
		{
			mypEnd = getEndCoordinates(Item, _type);
		}
		TypeIn retType() const
			{ return myType;}
                int type() const
                {return Type;}
        enum TypeIn type2;
        QPointF mypEnd;     //координаты указателя мыши
        int widthPen;     //толщина кисти
        qreal R;  //радиус акругления
        qreal widthRectangle;   //габариты прямоугольника
        qreal heighRectangle;   //габариты прямоугольника
        QList<parametrsArc> arcs;
        bool       isFlyingArrow;
        TypeIn     flyingType;
public slots:
    void updatePosition();  //смысл тот же, что и в arrow, но с измененным телом метода
private:
        DiagramItem *myStartItem, *myEndItem;
        QList<QLineF> lines;
        int ID; //id стрелки
        //добавил для сходства с arrow (еще не реализовал)
        QColor myColor;
        QPolygonF arrowHead;
		TypeIn myType;


};


#endif
