#include "marker.h"

Marker::Marker(QObject *parent) :
    QObject(parent)
{
    m_iDPMM = 40;
    m_listPolyline.clear();
    m_nProducts = 0;
    m_nActualMatchRegions = 0;
    m_nMatchRegions = 0;
    m_strProductCode = "";
}
Marker::~Marker()
{
}

Marker::Marker(const Marker &a): QObject()
{
    m_iDPMM = a.m_iDPMM;
    m_listPolyline.clear();
    m_listPolyline.append(a.m_listPolyline);
    m_nProducts = a.m_nProducts;
    m_nActualMatchRegions = a.m_nActualMatchRegions;
    m_nMatchRegions = a.m_nMatchRegions;
    m_strProductCode = a.m_strProductCode;
}

Marker Marker::operator=(const Marker &a)
{
    m_iDPMM = a.m_iDPMM;
    m_listPolyline.clear();
    m_listPolyline.append(a.m_listPolyline);
    m_nProducts = a.m_nProducts;
    m_nActualMatchRegions = a.m_nActualMatchRegions;
    m_nMatchRegions = a.m_nMatchRegions;
    m_strProductCode = a.m_strProductCode;
    return *this;
}

void Marker::Initialize()
{
    m_iDPMM = 40;
    m_listPolyline.clear();
    m_nProducts = 0;
    m_nActualMatchRegions = 0;
    m_nMatchRegions = 0;
    m_strProductCode = "";
}

QRect Marker::GetRect()
{
    QRect rect;

    CRPPolyline RPPolyline;
    rect.setRect(0,0,0,0);

    for(int i = 0; i < m_listPolyline.size(); i++)
    {
        RPPolyline = m_listPolyline.at(i);
        if (RPPolyline.m_nDrawingType == 0)
        {
            rect |= RectofPolyline(RPPolyline.m_listPoint);
        }
        else if (RPPolyline.m_nDrawingType == 3)
        {
            rect |= QRect(RPPolyline.m_text.m_ptPostLU,RPPolyline.m_text.m_ptPostRD);
        }
        else if (RPPolyline.m_nDrawingType == 1)
        {
            rect |= QRect(RPPolyline.m_bitmapInfo.m_ptAbPostLU,RPPolyline.m_bitmapInfo.m_ptAbPostRD);
        }
    }

    return  rect;
}

QRect Marker::RectofPolyline(const QList<QPoint> &listPoint)
{
    if(listPoint.empty())
    {
        return QRect(0,0,0,0);
    }
    int iXMin = INT_MAX;
    int iXMax = INT_MIN;
    int iYMin = INT_MAX;
    int iYMax = INT_MIN;

    int iValueX;
    int iValueY;

    int iPointCount = listPoint.size();
    for(int i = 0 ;i < iPointCount; i++)
    {
        iValueX = listPoint.at(i).x();
        iValueY = listPoint.at(i).y();

        if( iValueX > iXMax )
        {
            iXMax = iValueX;
        }

        if(iValueX < iXMin )
        {
            iXMin = iValueX;
        }

        if( iValueY > iYMax )
        {
            iYMax = iValueY;
        }

        if(iValueY < iYMin )
        {
            iYMin = iValueY;
        }
    }

    return QRect(QPoint(iXMin,iYMin),QPoint(iXMax,iYMax));
}


double CNotch::angle_2(int startx, int starty, int endx, int endy)
{
    //直线与X轴之间的夹角 X轴向量OE(1,0)
    double dAngle = 0;
    if((endx == startx) && (endy == starty))
    {
        return dAngle;
    }
    //求直线的向量坐标
    double dX = endx - startx;
    double dY = endy - starty;
    dAngle = qAcos((dX)/(qSqrt(dX*dX + dY*dY)));
    return dAngle;
}

void CNotch::CovertToOutputByOffset(int nOffSetX, int nOffsetY)
{
    double a = 0;
    double b = 0;
    double c = 0;
    //范围在[0,2pi)之间
    double dAngle = angle_2(m_ptStart.x(),m_ptStart.y(),m_ptEnd.x(),m_ptEnd.y());
    m_nAngle = dAngle*180.0/CONST_PI*100.0 + 0.5;
    //double dX = m_ptEnd.x - m_ptStart.x;
    //double dY = m_ptEnd.y - m_ptStart.y;
    //double dLen = sqrt(dX*dX + dY*dY);
    //m_ptCorrect.x = nOffSetY/dLen * dX + m_ptStart.x;
    //m_ptCorrect.y = nOffsetY/dLen * dY + m_ptStart.y;
    QPoint ptY;
    ptY.setX(nOffsetY*cos(dAngle) + m_ptStart.x() + 0.5);
    ptY.setY(nOffsetY*sin(dAngle) + m_ptStart.y() + 0.5);

    if (nOffSetX == 0)
    {
        m_ptCorrect.setX(ptY.x());
        m_ptCorrect.setY(ptY.y());
        return;
    }

    int nX = m_ptEnd.x() - m_ptStart.x();
    int nY = m_ptEnd.y() - m_ptStart.y();

    if (nX == 0)
    {
        a = 0;
        b = 1;
        c = -ptY.y();
    }
    if (nY == 0)
    {
        a = 1;
        b = 0;
        c = -ptY.x();
    }

    double k = double(m_ptStart.x() - m_ptEnd.x())/double(m_ptEnd.y() - m_ptStart.y());
    c = ptY.y() - k*ptY.x();
    a = k;
    b = -1;
    int nRadius = abs(nOffSetX);
    QPoint ptInter1;
    QPoint ptInter2;
    if (IntOfLineCircle(a,b,c,ptY.x(),ptY.y(),nRadius,ptInter1,ptInter2) == 2)
    {
        //向量
        int nYv = ptInter1.y() - ptY.y();
        int nXv = ptInter1.x() - ptY.x();
        //判断该点在起点到终点连线的哪一侧？>0 右侧
        if((nXv*nY -nYv*nX)>0)
        {
            if (nOffSetX > 0)//右侧
            {
                m_ptCorrect.setX(ptInter1.x());
                m_ptCorrect.setY(ptInter1.y());
            }
            else
            {
                m_ptCorrect.setX(ptInter2.x());
                m_ptCorrect.setY(ptInter2.y());
            }

        }
        else
        {
            if (nOffSetX < 0)//左侧
            {
                m_ptCorrect.setX(ptInter1.x());
                m_ptCorrect.setY(ptInter1.y());
            }
            else
            {
                m_ptCorrect.setX(ptInter2.x());
                m_ptCorrect.setY(ptInter2.y());
            }
        }
    }
}

int CNotch::IntOfLineCircle(double a, double b, double c, int xc, int yc, int nR, QPoint &lpptIntersection1, QPoint &lpptIntersection2)
{
    //点:(x0,y0)
    //线:Ax+By+C=0
    //①距离=ABS(A*x0+B*y0+C) / SQRT(A*A+B*B)
    double dis = 0;
    dis = abs(a*xc+b*yc+c)/sqrt(a*a+b*b);

    int rel = 0;
    if(dis < nR)
    {
        rel = 0;
    }
    else if(dis == nR)
    {
        rel = 1;
    }
    else if(dis > nR)
    {
        double k = -a/b;
        double b1 = 2*xc-2*k*(b-yc);
        double sval = (b1/100.0)*(b1/100.0)*10000.0-4*a*c;
        if(sval < 0)
        {
            qDebug()<<sval;
        }
        double tmp = sqrt(sval);
        double x1 = (b1+tmp)/(2*a);
        double y1 = k*x1+b;
        double x2 = (b1-tmp)/(2*a);
        double y2 = k*x2+b;

        lpptIntersection1.setX(x1);
        lpptIntersection1.setY(y1);

        lpptIntersection2.setX(x2);
        lpptIntersection2.setY(y2);

        rel = 2;
    }
    return rel;
}
