#include "graphicsItem/graphicsRectItem.h"
#include "graphicsItem/itemControlHandle.h"

#include <QPainter>
#include <QStyleOption>

GraphicsRectItem::GraphicsRectItem(const QRect &rect, bool isRound, QGraphicsItem *parent)
    : GraphicsBaseItem(parent), m_bIsRound(isRound), m_dRatioX(1 / 10.0), m_dRatioY(1 / 10.0)
{
    m_pen = QPen(Qt::black);
    m_brush = QBrush(Qt::NoBrush);
    m_lastBoudingRect = rect;
    m_boundingRect = rect;
    m_dWidth = rect.width();
    m_dHeight = rect.height();

    if (m_bIsRound) //圆角矩形添加两个圆角大小控制点
    {
        //横轴X控制点
        ItemControlHandle* pHandle1 = new ItemControlHandle(this);
        pHandle1->setType(T_editShape);
        pHandle1->setTag(H_edit);
        m_vecHanle.push_back(pHandle1);
        //纵轴Y控制点
        ItemControlHandle* pHandle2 = new ItemControlHandle(this);
        pHandle2->setType(T_editShape);
        pHandle2->setTag(H_edit+1);
        m_vecHanle.push_back(pHandle2);
    }
}

GraphicsRectItem::~GraphicsRectItem()
{

}

QPainterPath GraphicsRectItem::shape()
{
    QPainterPath path;
    double dHandleX = 0.0;
    double dHandleY = 0.0;
    if(m_dRatioX>0)
        dHandleX = m_dWidth * m_dRatioX + 0.5;
    if(m_dRatioY>0)
        dHandleY = m_dHeight * m_dRatioY + 0.5;

    if(m_bIsRound)
        path.addRoundedRect(m_boundingRect, dHandleX, dHandleY);
    else
        path.addRect(m_boundingRect);

    return path;
}

void GraphicsRectItem::updateHandles()
{
    GraphicsBaseItem::updateHandles();
    if(m_bIsRound && m_vecHanle.size() == H_edit + 1)
    {
        const QRectF& boundingRect = this->boundingRect();
        //H_edit=9所以index号需要-1
        m_vecHanle[H_edit -1]->move(boundingRect.right() - boundingRect.width() * m_dRatioX, boundingRect.top());
        m_vecHanle[H_edit + 1 -1]->move(boundingRect.right(), boundingRect.top() + boundingRect.height() * m_dRatioY);
    }
}

void GraphicsRectItem::updateCoordinate() //当执行了resie和editShape函数后，boundingRect发生了变换，需要将item的原点(以中心点为原点)校准至boundingRect.center()
{
    if (!parentItem())
    {
        QPointF pt1, pt2, delta;
        pt1 = mapToScene(QPointF(0, 0));
        pt2 = mapToScene(m_boundingRect.center());
        delta = pt1 - pt2;

        prepareGeometryChange();
        //将boundingRect设置成中心点和原点（也是默认变换原点），这样三点重合，有助于简化计算
        m_boundingRect = QRectF(-m_dWidth / 2, -m_dHeight / 2, m_dWidth, m_dHeight);
        //setTransformOriginPoint(m_boundingRect.center()); //变换中心默认为item的(0,0)点，所以不执行这句话也没有问题
        //更新bouondingRect后重回会显示位置会有变化，需要做对应的移动
        moveBy(-delta.x(), -delta.y());
        updateHandles();
    }

    m_lastBoudingRect = m_boundingRect;
    //qDebug() << "itemPos:" << mapToParent(pos());
}

void GraphicsRectItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
    painter->setPen(m_pen);
    painter->setBrush(m_brush);

    if(m_bIsRound)
    {
        double dRadiusX = 0.0;
        double dRadiusY = 0.0;
        if(m_dRatioX>0)
            dRadiusX = m_dWidth * m_dRatioX + 0.5;
        if(m_dRatioY>0)
            dRadiusY = m_dHeight * m_dRatioY + 0.5;

        painter->drawRoundedRect(m_boundingRect, dRadiusX, dRadiusY);
    }
    else
        painter->drawRect(m_boundingRect);


    if (option->state & QStyle::State_Selected) //是选中状态,绘制选中框
    {
        int nPenWidth = 1;
        painter->setPen(QPen(QColor(70,70,70), nPenWidth, Qt::DashLine)); //蓝色的外框
        painter->setBrush(Qt::NoBrush);
        painter->drawRect(m_boundingRect_selected);

        //绘制变换原点
        QPointF originPoint = transformOriginPoint();
        //qDebug() << "originPoint:" << originPoint;
        painter->setBrush(Qt::red);
        painter->drawEllipse(originPoint, 4, 4);
    }
}

void GraphicsRectItem::resize(int nHandle,double dSX, double dSY, const QPointF& basePoint)
{
    //qDebug() << basePoint;
    switch (nHandle)
    {
    case H_left:
    case H_right:
        dSY = 1; //拖拽的是左点右点，为水平缩放，忽略垂直变化
        break;
    case H_top:
    case H_bottom:
        dSX = 1; //拖拽的是顶点底点，为垂直缩放，忽略水平变化
        break;
    default:
        break;
    }

    QTransform trans;
    //缩放是以图元原点（中心）位置为基准，所以每帧都先移动移动到想要的基准点，缩放之后再移回
    trans.translate(basePoint.x(), basePoint.y());
    trans.scale(dSX, dSY);
    trans.translate(-basePoint.x(), -basePoint.y());

    prepareGeometryChange();
    m_boundingRect = trans.mapRect(m_lastBoudingRect);
    m_dWidth = m_boundingRect.width();
    m_dHeight = m_boundingRect.height();
    updateHandles();
}

void GraphicsRectItem::move(const QPointF& point)
{
    moveBy(point.x(), point.y());
}

void GraphicsRectItem::editShape(int nHandle,const QPointF& ptMouse)
{
    QPointF ptOnItem = mapFromParent(ptMouse);
    switch (nHandle)
    {
    //横轴X控制点
    case H_edit:
    {
        double dMouseX = ptOnItem.x();
        if(dMouseX < m_boundingRect.center().x())
            dMouseX = m_boundingRect.center().x();
        else if(dMouseX > m_boundingRect.right())
            dMouseX = m_boundingRect.right();
        double dWidth = m_boundingRect.width();
        if(dWidth == 0.0)
            dWidth = 1.0;
        m_dRatioX = (m_boundingRect.right() - dMouseX) / dWidth;
    }
    break;
    //纵轴Y控制点
    case H_edit + 1:
    {
        double dMouseY = ptOnItem.y();
        if(dMouseY > m_boundingRect.center().y())
            dMouseY = m_boundingRect.center().y();
        else if(dMouseY < m_boundingRect.top())
            dMouseY = m_boundingRect.top();
        double dHeight = m_boundingRect.height();
        if(dHeight == 0.0)
            dHeight = 1.0;
        m_dRatioY = (dMouseY - m_boundingRect.top()) / dHeight;
    }
    break;
    default:
    break;
    }

    prepareGeometryChange();
    updateHandles();
}
