#include "cctrlmimgcontainer.h"
#include <QPainter>
#include <QTransform>
#include <QStylePainter>
#include <QSizeF>
#include "m_math.h"
#include <QMutexLocker>
#include "gui.h"
#include "logic.h"
#include "gui.h"
#include <QApplication>
#include "gui.h"
#include <QScreen>

#define SEL_MARK_LEN    16
static void resize_qrect_with_point(QRectF& qrectf,const QPointF& point)
{
    QPointF center= qrectf.center();
    QSizeF size=QSizeF(fabs(point.x()-center.x())*2,fabs(point.y()-center.y())*2);
    qrectf=QRectF(center.x()-size.width()/2,center.y()-size.height()/2,
                  size.width(),size.height());
}

void CCtrlMImgContainer::resizeEvent(QResizeEvent *)
{
    ZoomFit();
}
void CCtrlMImgContainer::paintEvent(QPaintEvent *pEvent)
{
    UNUSED(pEvent);
    //return;
    if(!m_pContainer){return;}
    int32_t  iImgWidth=m_pContainer->m_Image.m_width;
    int32_t  iImgHeight=m_pContainer->m_Image.m_height;
    if(!iImgWidth||!iImgHeight)
    {
        return;
    }
    QStylePainter painter(this);
    painter.drawPixmap(0,0,m_Pixmap);

    QRect thisRect=rect();
    QRect vRect= m_pVbar->rect();
    QRect hRect= m_pHbar->rect();
    if(!m_pVbar->isHidden())
    {
        m_pVbar->move(thisRect.width()-vRect.width(),0);
        if(m_pHbar->isHidden())
        {
            m_pVbar->setFixedHeight(thisRect.height());
        }
        else
        {
            m_pVbar->setFixedHeight(thisRect.height()-hRect.height());
        }
    }
    if(!m_pHbar->isHidden())
    {
        m_pHbar->move(0,thisRect.height()-hRect.height());
        if(m_pVbar->isHidden())
        {
            m_pHbar->setFixedWidth(thisRect.width());
        }
        else
        {
            m_pHbar->setFixedWidth(thisRect.width()-vRect.width());
        }
    }

}
CCtrlMImgContainer::CCtrlMImgContainer(QWidget *parent) : CMWidget(parent)
{
    m_pContainer=0;
    m_dcurScale=1;
    m_dmaxScale=4;
    m_dminScale=0.25;

    m_bCapture=false;

    m_imargin=0;

    setFocusPolicy(Qt::StrongFocus);
    setSizePolicy(QSizePolicy::Expanding,
                  QSizePolicy::Expanding);

    setAutoFillBackground(true);
    setBackgroundRole(QPalette::Dark);
    m_pVbar=new QScrollBar(Qt::Vertical,this);
    m_pHbar=new QScrollBar(Qt::Horizontal,this);

    connect(m_pVbar,SIGNAL(valueChanged(int)),this,SLOT(setImgVPos(int)));
    connect(m_pHbar,SIGNAL(valueChanged(int)),this,SLOT(setImgHPos(int)));

    m_pSelected_shape=0;

    m_hitType=0;
    m_pCam=0;
    m_bInited=false;
    m_bEnableMouseZoom=false;

    m_bContainerInside=true;
    m_bKeepFit=true;

    m_BKColor=QRgb(0x808080);

    m_iFPS=0;
    m_iFrame=0;

    m_contextMenu = new QMenu;
    QAction *savecontainer = new QAction(tr("save container"),this);
    QAction *saveimage = new QAction(tr("save image"),this);
    connect(savecontainer, SIGNAL(triggered()), this, SLOT(saveContainer()));
    connect(saveimage, SIGNAL(triggered()), this, SLOT(saveImage()));
    setContextMenuPolicy(Qt::CustomContextMenu);
}

CCtrlMImgContainer::~CCtrlMImgContainer()
{
    if(m_bContainerInside&&m_pContainer)
    {
        delete    m_pContainer;
    }
}


void CCtrlMImgContainer::wheelEvent(QWheelEvent *pEvent)
{
    if(m_bEnableMouseZoom)
    {
        UNUSED(pEvent);

        int numDegrees=pEvent->delta()/8;
        int numticks=numDegrees/15;
        if(numticks>0)
        {
            // ZoomOrginal();
            ZoomIn();
        }
        else if(numticks<0)
        {
            ZoomOut();
        }
    }
}

void CCtrlMImgContainer::mousePressEvent(QMouseEvent *pEvent)
{
    if(pEvent->button()==Qt::LeftButton)
    {
        QPointF pos(pEvent->pos());
        hittest_container_shapes(pos);
        if(is_hitted())
        {
            m_oldPoint=QPointF(pEvent->pos());
        }
        else
        {
            if(m_pCam)
            {
                QPointF pos1 =  m_trans_DP2LP.map(pos);
                int32_t pixelx=pos1.x();
                int32_t pixely=pos1.y();
                if(pixelx<0||pixelx>=m_pContainer->m_Image.m_width) return;
                if(pixely<0||pixely>=m_pContainer->m_Image.m_height) return;
                m_pContainer->clearString();
                m_pContainer->addString(QObject::trUtf8("pixel:x=%1,y=%2.")
                                        .arg(pixelx).arg(pixely));

                CMPointd posref= m_pCam->DPTOLP(CMPointd(pixelx,pixely));
#if FILPCAM_XY
                CMPointd ptConveterd(posref.tY, posref.tX);
                ptConveterd.tY = -ptConveterd.tY;

                posref = ptConveterd;
#endif
                m_pContainer->addString(QObject::trUtf8("real:x=%1mm,y=%2mm.")
                                        .arg(posref.tX,0,'f',3)
                                        .arg(posref.tY,0,'f',3));

                if( m_gSystem.m_bCamMove)
                {
                    V_MsgQueue msgqueue;
                    m_gSystem.relmove_xy_msg(-posref.tX, -posref.tY,msgqueue);
                    m_gSystem.start_test(SM_MAIN, msgqueue,false);
                }
            }
        }
    }
    if(pEvent->button()==Qt::RightButton&&!m_bEnableMouseZoom)
    {
        m_contextMenu->exec(pEvent->globalPos());
    }
}

void CCtrlMImgContainer::mouseMoveEvent(QMouseEvent *pEvent)
{
    if(is_hitted())
    {
        QPointF pos(pEvent->pos());
        resize_sel_shape(pos,m_oldPoint);
        m_oldPoint=QPointF(pEvent->pos());
    }
}

void CCtrlMImgContainer::mouseReleaseEvent(QMouseEvent *pEvent)
{
    if(m_bEnableMouseZoom)
    {
        if(pEvent->button()==Qt::RightButton)
        {
            ZoomOrginal();
        }
    }
}

void CCtrlMImgContainer::showEvent(QShowEvent *pEvent)
{

    ZoomFit();
    CMWidget::showEvent(pEvent);
}

void CCtrlMImgContainer::hideEvent(QHideEvent *event)
{
    CMWidget::hideEvent(event);
}
void CCtrlMImgContainer::MTimeFresh()
{

    if(m_bKeepFit)
    {
        ZoomFit();
    }
    refreshPixmap();

    if(m_pCam)
    {
        //int iSMID=m_pCam->m_iID==CAM2X? SM_CAMGRAB2X:SM_CAMGRAB6X;
		int iSMID= SM_CAMGRAB6X;
		switch(m_pCam->m_iID){
		case CAM2X:
			iSMID = SM_CAMGRAB2X;
			break;
		case CAM6X:
			iSMID = SM_CAMGRAB6X;
			break;
#ifdef __USE_THIRD_CAMERA__
		case CAMKerf:
			iSMID = SM_CAMGRAB4X;
			break;
#endif
		default:
			break;
		}

        V_State* m_pState = m_gSystem.FindSM(iSMID)->GetIdleState();
        if(m_pState->QueueSize()<100)
        {
            m_pState->pushback_Msg(VarMsg_Driver_ID,QObject::trUtf8("Grab Image"),
                                 QVariantList()
                                 <<CAM_DRIVER<<CCamDriver::GRAB
                                 <<m_pCam->m_iID,0);
        }

    }

}


void CCtrlMImgContainer::adjust_imgviewrect( )
{
    if(!m_pContainer) return;
    if(!isVisible()) return;
    QRectF rectFullView=get_clipRect();
    double dfullviewwidth=rectFullView.width();
    double dfullviewheight=rectFullView.height();
    double  iImgWidth=m_pContainer->m_Image.m_width;
    double  iImgHeight=m_pContainer->m_Image.m_height;
    if(DEQUAL0(iImgWidth)||DEQUAL0(iImgHeight)) return;
    QPointF imgViewCenter=m_rectImageView.center();
    double dimgviewwidth=iImgWidth*m_dcurScale;
    double dimgviewheight=iImgHeight*m_dcurScale;
    double dleft=0,dtop=0;
    if(dimgviewwidth<=dfullviewwidth)
    {
        dleft=rectFullView.center().x()-dimgviewwidth/2;
        m_pHbar->setValue(0);
        m_pHbar->hide();
    }
    else
    {
        dleft=imgViewCenter.x()-dimgviewwidth/2;
        m_pHbar->show();
        double range= dimgviewwidth-dfullviewwidth;
        m_pHbar->setRange(-range/2,range/2);
        m_pHbar->setPageStep(range/10);
        m_pHbar->setSingleStep(range/100);

    }
    if(dimgviewheight<=dfullviewheight)
    {
        dtop=rectFullView.center().y()-dimgviewheight/2;
        m_pVbar->setValue(0);
        m_pVbar->hide();
    }
    else
    {
        dtop=imgViewCenter.y()-dimgviewheight/2;
        m_pVbar->show();
        double range= dimgviewheight-dfullviewheight;
        m_pVbar->setRange(-range/2,range/2);
        m_pHbar->setPageStep(range/10);
        m_pHbar->setSingleStep(range/100);
    }

    m_rectImageView=QRectF(dleft,dtop,dimgviewwidth,dimgviewheight);
    QRectF rectImage(0,0,iImgWidth,iImgHeight);

    QPolygonF one,two;
    one.push_back(rectImage.topLeft());
    one.push_back(rectImage.topRight());
    one.push_back(rectImage.bottomRight());
    one.push_back(rectImage.bottomLeft());

    two.push_back(m_rectImageView.topLeft());
    two.push_back(m_rectImageView.topRight());
    two.push_back(m_rectImageView.bottomRight());
    two.push_back(m_rectImageView.bottomLeft());
    bool bsuccess= QTransform::quadToQuad(one,two,m_trans_LP2DP);
    Q_ASSERT(bsuccess);
    m_trans_DP2LP=m_trans_LP2DP.inverted(&bsuccess);
    Q_ASSERT(bsuccess);
}

void CCtrlMImgContainer::refreshPixmap()
{
    if(!isVisible()) return;
    if(!m_pContainer){return;}
    int32_t  iImgWidth=m_pContainer->m_Image.m_width;
    int32_t  iImgHeight=m_pContainer->m_Image.m_height;
    if(!iImgWidth||!iImgHeight)
    {
        return;
    }
    m_Pixmap=QPixmap(size());
    m_Pixmap.fill(m_BKColor); 

    QPainter painter(&m_Pixmap);
    painter.initFrom(this);

    painter.setClipRect(get_clipRect());
    QImage img(m_pContainer->m_Image.m_pRawImage,iImgWidth,iImgHeight,
               QImage::Format_Grayscale8);


    adjust_imgviewrect();
    painter.drawImage(m_rectImageView,img);

    draw_container_shapes( painter);
    painter.setPen(QPen(Qt::green,0));
    draw_container_strings( painter);
    draw_container_name( painter); 

    if(m_pCam)
    {

       // QMutexLocker locker(&m_pContainer->mutex);
        QRectF rectClip=m_rectImageView.intersected(get_clipRect());
        painter.setPen(QPen(Qt::green,0));
        painter.drawText(rectClip,
                         Qt::AlignBottom|Qt::AlignRight,
                         QObject::trUtf8("FPS:%1")
                         .arg(m_pCam->m_iFPS));
    }
    update();

}

QRectF CCtrlMImgContainer::get_clipRect()
{
    QRectF cliprect=rect();
    if(!m_pVbar->isHidden())
    {
        cliprect.adjust(0,0,-m_pVbar->width(),0);
    }
    if(!m_pHbar->isHidden())
    {
        cliprect.adjust(0,0,0,-m_pHbar->height());
    }
    return cliprect;
}

void CCtrlMImgContainer::ZoomIn()
{
    m_dcurScale=int32_t(m_dcurScale/0.25)*0.25*2;
    m_dcurScale=min(m_dmaxScale,m_dcurScale);
    m_dcurScale=max(m_dminScale,m_dcurScale);
}

void CCtrlMImgContainer::ZoomOut()
{
    m_dcurScale=int32_t(m_dcurScale/0.25)*0.25/2;
    m_dcurScale=min(m_dmaxScale,m_dcurScale);
    m_dcurScale=max(m_dminScale,m_dcurScale);

}

void CCtrlMImgContainer::ZoomFit()
{
    m_pVbar->setValue(0);
    m_pHbar->setValue(0);
    m_pHbar->hide();
    m_pVbar->hide();
    int32_t  iImgWidth=m_pContainer->m_Image.m_width;
    int32_t  iImgHeight=m_pContainer->m_Image.m_height;

    QRectF rectFullView=get_clipRect();
    double dfullviewwidth=rectFullView.width();
    double dfullviewheight=rectFullView.height();
    m_dcurScale=min(dfullviewwidth/(iImgWidth+1),
                    dfullviewheight/(iImgHeight+1));

}

void CCtrlMImgContainer::ZoomOrginal()
{
    m_dcurScale=1;
    m_pVbar->setValue(0);
    m_pHbar->setValue(0);
    QRectF rectFullView=get_clipRect();
    double centery=rectFullView.center().y();
    m_rectImageView.setTop(centery-m_rectImageView.height()/2);
    double centerx=rectFullView.center().x();
    m_rectImageView.setLeft(centerx-m_rectImageView.width()/2);
}

void CCtrlMImgContainer::MInit()
{
    if(m_bContainerInside)
    {
        m_pContainer=new CImageContainer();
        //      int iwidth=size().width();
        //      int iheight=size().height();
        //      m_pContainer->m_Image=CMImage(iwidth,iheight);
    }
    Q_ASSERT(m_pContainer);
    //    qDebug()<<m_pContainer->m_Image.m_height<<"--"<<m_pContainer->m_Image.m_width;
}

void CCtrlMImgContainer::setInsideImage(CMImage &Image)
{
    if(m_bContainerInside)
    {
        m_pContainer->SetImage(Image);
        ZoomFit();
        refreshPixmap();
    }
}

void CCtrlMImgContainer::MFresh()
{
    refreshPixmap();
}

void CCtrlMImgContainer::setImgVPos(int pos)
{
    QRectF rectFullView=get_clipRect();
    double centery=rectFullView.center().y()-pos;
    m_rectImageView.setTop(centery-m_rectImageView.height()/2);
    refreshPixmap();
}

void CCtrlMImgContainer::setImgHPos(int pos)
{
    QRectF rectFullView=get_clipRect();
    double centerx=rectFullView.center().x()-pos;
    m_rectImageView.setLeft(centerx-m_rectImageView.width()/2);
    refreshPixmap();
}

void CCtrlMImgContainer::saveImage()
{
    if(!m_pContainer) return;
    int32_t  iImgWidth=m_pContainer->m_Image.m_width;
    int32_t  iImgHeight=m_pContainer->m_Image.m_height;
    if(!iImgWidth||!iImgHeight)
    {
        return;
    }
    QString imagename=m_sName+"_RawImage_"+QDateTime::currentDateTime()
            .toString(QString::fromUtf8("yyyy_MM_dd_HH_mm_ss"));
    QString filepath=CMakePath::make_file_path(imagename+
                                               QString::fromUtf8("_%1"));
    QImage img(m_pContainer->m_Image.m_pRawImage,iImgWidth,iImgHeight,
               QImage::Format_Grayscale8);

    if(!img.save(filepath,"JPG",100))
    {
        m_gSystem.m_SysMsg.SetMsg(tr("Save image failed"));
    }
}

void CCtrlMImgContainer::saveContainer()
{
    QString filePathName = m_sName+"_ContainerImage_";

    filePathName += QDateTime::currentDateTime().toString("yyyy_MM_dd_hh_mm_ss");
    filePathName += ".jpg";
    QString filepath= CMakePath::make_file_path(filePathName);
    if(!m_Pixmap.save(filepath, "jpg", 100))
    {
        m_gSystem.m_SysMsg.SetMsg(tr("Save container failed"));
    }
}

void CCtrlMImgContainer::draw_container_shapes(QPainter& painter)
{
    Q_ASSERT(m_pContainer);
    QMutexLocker locker(&m_pContainer->mutex);

    QRectF rectClip=m_rectImageView.intersected(get_clipRect());
    painter.setClipRect(rectClip);

    for(SHAPELIST::iterator ii=m_pContainer->lstaticshapes.begin();
        ii!=m_pContainer->lstaticshapes.end();ii++)
    {
        draw_shape((*ii),painter);
    }

    for(SHAPELIST::iterator ii=m_pContainer->lstaticshapes_extra.begin();
        ii!=m_pContainer->lstaticshapes_extra.end();ii++)
    {
        draw_shape((*ii),painter);
    }

    for(SHAPELIST::iterator ii=m_pContainer->lactiveshapes.begin();
        ii!=m_pContainer->lactiveshapes.end();ii++)
    {
        if(!is_shape_selected(*ii))
        {
            draw_shape((*ii),painter);
        }
        else
        {
            painter.setPen(QPen(QBrush(QColor(255,0,0)),0));
            draw_sel_shape((*ii),painter);
        }
    }
    for(SHAPELIST::iterator ii=m_pContainer->lmarkshapes.begin();
        ii!=m_pContainer->lmarkshapes.end();ii++)
    {
        draw_shape((*ii),painter);
    }
}

void CCtrlMImgContainer::draw_container_strings(QPainter &painter)
{
    Q_ASSERT(m_pContainer);
    QMutexLocker locker(&m_pContainer->mutex);

    QRectF rectClip=m_rectImageView.intersected(get_clipRect());
    painter.setClipRect(rectClip);
    QString text;
    foreach (QString s, m_pContainer->lstrs)
    {
        text+=s+'\n';
    }
    painter.drawText(rectClip,text);
}

void CCtrlMImgContainer::draw_container_name(QPainter &painter)
{
    Q_ASSERT(m_pContainer);

    QMutexLocker locker(&m_pContainer->mutex);
    QRectF rectClip=m_rectImageView.intersected(get_clipRect());
    painter.setClipRect(rectClip);
    painter.drawText(rectClip,Qt::AlignRight|Qt::AlignTop,m_pContainer->name);
}

void CCtrlMImgContainer::draw_sel_shape(CShape *pshape, QPainter &painter)
{
    Q_ASSERT(pshape);
    switch(pshape->etype)
    {
    case CShape::RECT_DEVICE:
    {
        CRect* prect=(CRect*)pshape;
        QRectF rectf(prect->m_center.tX-prect->m_width/2,
                     prect->m_center.tY-prect->m_height/2,
                     prect->m_width,
                     prect->m_height);
        rectf=m_trans_LP2DP.mapRect(rectf);
        painter.drawRect(rectf);
        QRectF rectMark(0,0,SEL_MARK_LEN,SEL_MARK_LEN);
        rectMark.moveCenter(rectf.topLeft());
        painter.drawRect(rectMark);
        rectMark.moveCenter(rectf.topRight());
        painter.drawRect(rectMark);
        rectMark.moveCenter(rectf.bottomLeft());
        painter.drawRect(rectMark);
        rectMark.moveCenter(rectf.bottomRight());
        painter.drawRect(rectMark);

        rectMark.moveCenter((rectf.topLeft()+rectf.topRight())/2);
        painter.drawRect(rectMark);
        rectMark.moveCenter((rectf.topLeft()+rectf.bottomLeft())/2);
        painter.drawRect(rectMark);
        rectMark.moveCenter((rectf.bottomRight()+rectf.bottomLeft())/2);
        painter.drawRect(rectMark);
        rectMark.moveCenter((rectf.bottomRight()+rectf.topRight())/2);
        painter.drawRect(rectMark);

        painter.drawLine(rectf.center().rx()-SEL_MARK_LEN,
                         rectf.center().ry(),
                         rectf.center().rx()+SEL_MARK_LEN,
                         rectf.center().ry());
        painter.drawLine(rectf.center().rx(),
                         rectf.center().ry()-SEL_MARK_LEN,
                         rectf.center().rx(),
                         rectf.center().ry()+SEL_MARK_LEN);
        break;
    }
    case CShape::RECT_ROT:
    {
        CRectRot* prectrot=(CRectRot*)pshape;
        QRectF rectf(prectrot->m_center.tX-prectrot->m_width/2,
                     prectrot->m_center.tY-prectrot->m_height/2,
                     prectrot->m_width,
                     prectrot->m_height);
        rectf=m_trans_LP2DP.mapRect(rectf);
        QSizeF msize=rectf.size();
        painter.save();
        painter.translate(rectf.center());
        painter.rotate(-prectrot->m_angle);
        rectf=QRectF(-msize.width()/2,-msize.height()/2,
                     msize.width(),msize.height());
        painter.drawRect(rectf);
        painter.drawLine(rectf.center(),
                         QPointF(rectf.right(),rectf.top()+rectf.height()/2));

        QRectF rectMark(0,0,SEL_MARK_LEN,SEL_MARK_LEN);
        rectMark.moveCenter(rectf.topLeft());
        painter.drawRect(rectMark);
        rectMark.moveCenter(rectf.topRight());
        painter.drawRect(rectMark);
        rectMark.moveCenter(rectf.bottomLeft());
        painter.drawRect(rectMark);
        rectMark.moveCenter(rectf.bottomRight());
        painter.drawRect(rectMark);

        //      rectMark.moveCenter((rectf.topLeft()+rectf.topRight())/2);
        //      painter.drawRect(rectMark);
        //      rectMark.moveCenter((rectf.topLeft()+rectf.bottomLeft())/2);
        //      painter.drawRect(rectMark);
        //      rectMark.moveCenter((rectf.bottomRight()+rectf.bottomLeft())/2);
        //      painter.drawRect(rectMark);
        //      rectMark.moveCenter((rectf.bottomRight()+rectf.topRight())/2);
        //      painter.drawRect(rectMark);

        rectMark.moveCenter(QPointF(rectf.right(),rectf.top()+rectf.height()/2));
        painter.drawEllipse(rectMark);
        painter.restore();
        break;
    }
    case CShape::COELLIPSE:
    {
        CCoEllipse* pCoEllipse=(CCoEllipse*)pshape;
        QRectF rectf=QRect(pCoEllipse->m_center.tX-pCoEllipse->m_widthin/2,
                           pCoEllipse->m_center.tY-pCoEllipse->m_heightin/2,
                           pCoEllipse->m_widthin,
                           pCoEllipse->m_heightin);
        rectf=m_trans_LP2DP.mapRect(rectf);
        painter.drawEllipse(rectf);

        QRectF rectMark(0,0,SEL_MARK_LEN,SEL_MARK_LEN);
        rectMark.moveCenter((rectf.topLeft()+rectf.topRight())/2);
        painter.drawRect(rectMark);
        rectMark.moveCenter((rectf.topLeft()+rectf.bottomLeft())/2);
        painter.drawRect(rectMark);
        rectMark.moveCenter((rectf.bottomRight()+rectf.bottomLeft())/2);
        painter.drawRect(rectMark);
        rectMark.moveCenter((rectf.bottomRight()+rectf.topRight())/2);
        painter.drawRect(rectMark);

        rectf=QRect(pCoEllipse->m_center.tX-pCoEllipse->m_widthout/2,
                    pCoEllipse->m_center.tY-pCoEllipse->m_heightout/2,
                    pCoEllipse->m_widthout,
                    pCoEllipse->m_heightout);
        rectf=m_trans_LP2DP.mapRect(rectf);
        painter.drawEllipse(rectf);

        rectMark.moveCenter((rectf.topLeft()+rectf.topRight())/2);
        painter.drawRect(rectMark);
        rectMark.moveCenter((rectf.topLeft()+rectf.bottomLeft())/2);
        painter.drawRect(rectMark);
        rectMark.moveCenter((rectf.bottomRight()+rectf.bottomLeft())/2);
        painter.drawRect(rectMark);
        rectMark.moveCenter((rectf.bottomRight()+rectf.topRight())/2);
        painter.drawRect(rectMark);
        break;
    }
    default:
        Q_ASSERT(0);
        break;
    }
}

void CCtrlMImgContainer::draw_shape(CShape *pshape,QPainter& painter)
{
    Q_ASSERT(pshape);
    int iconfig=pshape->m_iConfig;
    Qt::GlobalColor color=(Qt::GlobalColor)(iconfig&0xFF);
    QPen pen(color);
    iconfig&=0xFF00;
    if(iconfig==shape_dash)
    {
        pen.setStyle(Qt::DashLine);
    }
    painter.setPen(pen);
    switch(pshape->etype)
    {
    case CShape::LINE:
    {
        CLine* pline=(CLine*)pshape;
        QLineF linef(QPointF(pline->m_pt1.tX,pline->m_pt1.tY),
                     QPointF(pline->m_pt2.tX,pline->m_pt2.tY));
        linef=m_trans_LP2DP.map(linef);
        painter.drawLine(linef);
        break;
    }
    case CShape::ELLIPSE:
    {
        CEllipse* pEllipse=(CEllipse*)pshape;
        QRectF rectf(pEllipse->m_center.tX-pEllipse->m_width/2,
                     pEllipse->m_center.tY-pEllipse->m_height/2,
                     pEllipse->m_width,
                     pEllipse->m_height);
        rectf=m_trans_LP2DP.mapRect(rectf);
        painter.drawEllipse(rectf);
        break;
    }
    case CShape::ARC:
    {
        CArc* pArc=(CArc*)pshape;
        QRectF rectf(pArc->m_center.tX-pArc->m_width/2,
                     pArc->m_center.tY-pArc->m_height/2,
                     pArc->m_width,
                     pArc->m_height);
        rectf=m_trans_LP2DP.mapRect(rectf);
        double dspan=pArc->m_spanAngle;
        //   painter.drawRect(rectf);
        painter.drawArc(rectf,pArc->m_startAngle*16,dspan*16);
        break;
    }
    case CShape::RECT_DEVICE:
    {
        CRect* prect=(CRect*)pshape;
        QRectF rectf(prect->m_center.tX-prect->m_width/2,
                     prect->m_center.tY-prect->m_height/2,
                     prect->m_width,
                     prect->m_height);
        rectf=m_trans_LP2DP.mapRect(rectf);
        painter.drawRect(rectf);
        if(iconfig==shape_fill)
        {
            painter.fillRect(rectf,QBrush(color,Qt::BDiagPattern));
        }
        break;
    }
    case CShape::COELLIPSE:
    {
        CCoEllipse* pCoEllipse=(CCoEllipse*)pshape;
        QRectF rectf=QRect(pCoEllipse->m_center.tX-pCoEllipse->m_widthin/2,
                           pCoEllipse->m_center.tY-pCoEllipse->m_heightin/2,
                           pCoEllipse->m_widthin,
                           pCoEllipse->m_heightin);
        rectf=m_trans_LP2DP.mapRect(rectf);
        painter.drawEllipse(rectf);
        rectf=QRect(pCoEllipse->m_center.tX-pCoEllipse->m_widthout/2,
                    pCoEllipse->m_center.tY-pCoEllipse->m_heightout/2,
                    pCoEllipse->m_widthout,
                    pCoEllipse->m_heightout);
        rectf=m_trans_LP2DP.mapRect(rectf);
        painter.drawEllipse(rectf);
        break;
    }
    case CShape::CROSS:
    {
        CCross* pcross=(CCross*)pshape;
        QLineF linef1(QPointF(pcross->m_center.tX-pcross->m_width/2,pcross->m_center.tY),
                      QPointF(pcross->m_center.tX+pcross->m_width/2,pcross->m_center.tY));

        QLineF linef2(QPointF(pcross->m_center.tX,pcross->m_center.tY-pcross->m_height/2),
                      QPointF(pcross->m_center.tX,pcross->m_center.tY+pcross->m_height/2));
        linef1=m_trans_LP2DP.map(linef1);
        linef2=m_trans_LP2DP.map(linef2);
        painter.drawLine(linef1);
        painter.drawLine(linef2);
        break;
    }
    case CShape::XLD:
    {
        CXLD* pXLD=(CXLD*)pshape;
        QPolygonF Polygon;
        for(QMMutexVector<CMPointd>::iterator ii=pXLD->m_vpointfs.begin();
            ii!=pXLD->m_vpointfs.end();ii++)
        {
            Polygon.push_back(QPointF((*ii).tX,(*ii).tY));
        }
        Polygon=m_trans_LP2DP.map(Polygon);
        painter.drawPolyline(Polygon);
        break;
    }
    case CShape::XLD_ROTATE:
    {
        CXLD_Rotate* pXLD=(CXLD_Rotate*)pshape;
        QPolygonF Polygon;
        for(QMMutexVector<CMPointd>::iterator ii=pXLD->m_vpointfs.begin();
            ii!=pXLD->m_vpointfs.end();ii++)
        {
            Polygon.push_back(QPointF((*ii).tX,(*ii).tY));
        }
        Polygon=m_trans_LP2DP.map(Polygon);
        QPointF pointCenter=m_trans_LP2DP.map(QPointF(pXLD->m_center.tX,
                                                      pXLD->m_center.tY));
        painter.save();
        painter.translate(pointCenter);
        painter.rotate(-pXLD->m_angle);
        painter.drawPolyline(Polygon);
        painter.restore();
        break;
    }
    case CShape::RECT_ROT:
    {

        CRectRot* prectrot=(CRectRot*)pshape;
        QRectF rectf(prectrot->m_center.tX-prectrot->m_width/2,
                     prectrot->m_center.tY-prectrot->m_height/2,
                     prectrot->m_width,
                     prectrot->m_height);
        rectf=m_trans_LP2DP.mapRect(rectf);
        QSizeF msize=rectf.size();
        painter.save();
        painter.translate(rectf.center());
        painter.rotate(-prectrot->m_angle);
        rectf=QRectF(-msize.width()/2,-msize.height()/2,
                     msize.width(),msize.height());
        painter.drawRect(rectf);
        painter.drawLine(rectf.center(),
                         QPointF(rectf.right(),rectf.top()+rectf.height()/2));
        painter.restore();
        break;
    }
    default:
        Q_ASSERT(0);
        break;
    }
}

void CCtrlMImgContainer::hittest_container_shapes(QPointF &point)
{
    Q_ASSERT(m_pContainer);
    QMutexLocker locker(&m_pContainer->mutex);
    for(SHAPELIST::iterator ii=m_pContainer->lactiveshapes.begin();
        ii!=m_pContainer->lactiveshapes.end();ii++)
    {
        m_hitType= hit_shape(point,*ii);
        if(m_hitType!=HIT_OUT)
        {
            m_pSelected_shape=*ii;
            return;
        }
    }
    m_pSelected_shape=0;
    m_hitType=HIT_OUT;
}

int32_t CCtrlMImgContainer::hit_shape(const QPointF& point,CShape *pshape)
{
    Q_ASSERT(pshape);
    if(!is_shape_can_selected(pshape)) return HIT_OUT;
    switch(pshape->etype)
    {
    case CShape::RECT_DEVICE:
    {
        CRect* prect=(CRect*)pshape;
        QRectF rectf(prect->m_center.tX-prect->m_width/2,
                     prect->m_center.tY-prect->m_height/2,
                     prect->m_width,
                     prect->m_height);
        rectf=m_trans_LP2DP.mapRect(rectf);
        QRectF rectMark(0,0,SEL_MARK_LEN,SEL_MARK_LEN);
        rectMark.moveCenter(rectf.topLeft());
        if(rectMark.contains(point))return TOP_LEFT;
        rectMark.moveCenter(rectf.topRight());
        if(rectMark.contains(point))return TOP_RIGHT;
        rectMark.moveCenter(rectf.bottomLeft());
        if(rectMark.contains(point))return BOTTOM_LEFT;
        rectMark.moveCenter(rectf.bottomRight());
        if(rectMark.contains(point))return BOTTOM_RIGHT;


        rectMark.moveCenter((rectf.topLeft()+rectf.topRight())/2);
        if(rectMark.contains(point))return HIT_TOP;
        rectMark.moveCenter((rectf.topLeft()+rectf.bottomLeft())/2);
        if(rectMark.contains(point))return HIT_LEFT;
        rectMark.moveCenter((rectf.bottomRight()+rectf.bottomLeft())/2);
        if(rectMark.contains(point))return HIT_BOTTOM;
        rectMark.moveCenter((rectf.bottomRight()+rectf.topRight())/2);
        if(rectMark.contains(point))return HIT_RIGHT;

        if(rectf.contains(point))return HIT_IN;
        break;
    }
    case CShape::RECT_ROT:
    {
        CRectRot* prectrot=(CRectRot*)pshape;
        QRectF rectf(prectrot->m_center.tX-prectrot->m_width/2,
                     prectrot->m_center.tY-prectrot->m_height/2,
                     prectrot->m_width,
                     prectrot->m_height);
        rectf=m_trans_LP2DP.mapRect(rectf);
        QTransform trans;
        trans.rotate(prectrot->m_angle);
        QPointF point_trans=trans.map(point-rectf.center())+rectf.center();

        //     rectTest=QRectF (0,0,SEL_MARK_LEN,SEL_MARK_LEN);
        //     rectTest.moveCenter(point_trans);
        QRectF rectMark(0,0,SEL_MARK_LEN,SEL_MARK_LEN);
        rectMark.moveCenter(rectf.topLeft());
        if(rectMark.contains(point_trans))return TOP_LEFT;
        rectMark.moveCenter(rectf.topRight());
        if(rectMark.contains(point_trans))return TOP_RIGHT;
        rectMark.moveCenter(rectf.bottomLeft());
        if(rectMark.contains(point_trans))return BOTTOM_LEFT;
        rectMark.moveCenter(rectf.bottomRight());
        if(rectMark.contains(point_trans))return BOTTOM_RIGHT;

        //       rectMark.moveCenter((rectf.topLeft()+rectf.topRight())/2);
        //       if(rectMark.contains(point_trans))return HIT_TOP;
        //       rectMark.moveCenter((rectf.topLeft()+rectf.bottomLeft())/2);
        //       if(rectMark.contains(point_trans))return HIT_LEFT;
        //       rectMark.moveCenter((rectf.bottomRight()+rectf.bottomLeft())/2);
        //       if(rectMark.contains(point_trans))return HIT_BOTTOM;
        //       rectMark.moveCenter((rectf.bottomRight()+rectf.topRight())/2);
        //       if(rectMark.contains(point_trans))return HIT_RIGHT;

        rectMark.moveCenter(QPointF(rectf.right(),rectf.top()+rectf.height()/2));
        if(rectMark.contains(point_trans))return ROTATE;

        if(rectf.contains(point_trans))return HIT_IN;
        break;
    }
    case CShape::COELLIPSE:
    {
        CCoEllipse* pCoEllipse=(CCoEllipse*)pshape;
        QRectF rectf=QRect(pCoEllipse->m_center.tX-pCoEllipse->m_widthin/2,
                           pCoEllipse->m_center.tY-pCoEllipse->m_heightin/2,
                           pCoEllipse->m_widthin,
                           pCoEllipse->m_heightin);
        rectf=m_trans_LP2DP.mapRect(rectf);

        QRectF rectMark(0,0,SEL_MARK_LEN,SEL_MARK_LEN);
        rectMark.moveCenter((rectf.topLeft()+rectf.topRight())/2);
        if(rectMark.contains(point))return HIT_TOP;
        rectMark.moveCenter((rectf.topLeft()+rectf.bottomLeft())/2);
        if(rectMark.contains(point))return HIT_LEFT;
        rectMark.moveCenter((rectf.bottomRight()+rectf.bottomLeft())/2);
        if(rectMark.contains(point))return HIT_BOTTOM;
        rectMark.moveCenter((rectf.bottomRight()+rectf.topRight())/2);
        if(rectMark.contains(point))return HIT_RIGHT;

        rectf=QRectF(pCoEllipse->m_center.tX-pCoEllipse->m_widthout/2,
                     pCoEllipse->m_center.tY-pCoEllipse->m_heightout/2,
                     pCoEllipse->m_widthout,
                     pCoEllipse->m_heightout);
        rectf=m_trans_LP2DP.mapRect(rectf);

        rectMark.moveCenter((rectf.topLeft()+rectf.topRight())/2);
        if(rectMark.contains(point))return TOP_OUT;
        rectMark.moveCenter((rectf.topLeft()+rectf.bottomLeft())/2);
        if(rectMark.contains(point))return LEFT_OUT;
        rectMark.moveCenter((rectf.bottomRight()+rectf.bottomLeft())/2);
        if(rectMark.contains(point))return BOTTOM_OUT;
        rectMark.moveCenter((rectf.bottomRight()+rectf.topRight())/2);
        if(rectMark.contains(point))return RIGHT_OUT;
        if(rectf.contains(point))return HIT_IN;
        break;
    }
    default:
        Q_ASSERT(0);
        break;
    }
    return HIT_OUT;
}

void CCtrlMImgContainer::resize_sel_shape(const QPointF &point,const QPointF &oldpoint)
{
    Q_ASSERT(m_pContainer);
    QMutexLocker locker(&m_pContainer->mutex);
    if(!is_hitted()) return;
    QLineF line=m_trans_DP2LP.map(QLineF(0,0,SEL_MARK_LEN,0));
    QPointF oldpoint_lp=m_trans_DP2LP.map(oldpoint);
    double minlen=line.length();
    switch(m_pSelected_shape->etype)
    {
    case CShape::RECT_DEVICE:
    {
        CRect* prect=(CRect*)m_pSelected_shape;
        QRectF rectf(prect->m_center.tX-prect->m_width/2,
                     prect->m_center.tY-prect->m_height/2,
                     prect->m_width,
                     prect->m_height);
        QPointF pointLP=m_trans_DP2LP.map(point);
        QPointF center=rectf.center();
        switch(m_hitType)
        {

        case TOP_LEFT:   rectf.setTopLeft(pointLP);       break;
        case BOTTOM_LEFT: rectf.setBottomLeft(pointLP);   break;
        case TOP_RIGHT:   rectf.setTopRight(pointLP);   break;
        case BOTTOM_RIGHT: rectf.setBottomRight(pointLP);   break;

        case HIT_LEFT:   rectf.setLeft(pointLP.x());     break;
        case HIT_TOP:    rectf.setTop(pointLP.y());   break;
        case HIT_BOTTOM: rectf.setBottom(pointLP.y());   break;
        case HIT_RIGHT:  rectf.setRight(pointLP.x());  break;

        case HIT_IN:
            if(!m_pSelected_shape->m_bCenterLocked)
            {
                center+=(pointLP-oldpoint_lp);
            }
            break;
        default :Q_ASSERT(0);break;
        }
        rectf.moveCenter(center);
        prect->m_center=CMPointd(rectf.center().x(),rectf.center().y());
        prect->m_width=max(rectf.width(),minlen);
        prect->m_height=max(rectf.height(),minlen);
        break;
    }
    case CShape::RECT_ROT:
    {
        CRectRot* prectrot=(CRectRot*)m_pSelected_shape;
        QRectF rectf(prectrot->m_center.tX-prectrot->m_width/2,
                     prectrot->m_center.tY-prectrot->m_height/2,
                     prectrot->m_width,
                     prectrot->m_height);
        QPointF pointLP=m_trans_DP2LP.map(point);
        QTransform trans;
        trans.rotate(prectrot->m_angle);
        QPointF point_trans=trans.map(pointLP-rectf.center())+rectf.center();

        QPointF center=rectf.center();
        switch(m_hitType)
        {

        case TOP_LEFT:   rectf.setTopLeft(point_trans);       break;
        case BOTTOM_LEFT: rectf.setBottomLeft(point_trans);   break;
        case TOP_RIGHT:   rectf.setTopRight(point_trans);   break;
        case BOTTOM_RIGHT: rectf.setBottomRight(point_trans);   break;

            //        case HIT_LEFT:   rectf.setLeft(point_trans.x());     break;
            //        case HIT_TOP:    rectf.setTop(point_trans.y());   break;
            //        case HIT_BOTTOM: rectf.setBottom(point_trans.y());   break;
            //        case HIT_RIGHT:  rectf.setRight(point_trans.x());  break;

        case HIT_IN:        center+=(pointLP-oldpoint_lp);break;
        case ROTATE:
            prectrot->m_angle= calcu_angle_logic(CMPointd(rectf.center().x(),-rectf.center().y()),
                                                 CMPointd(pointLP.x(),-pointLP.y()));
            MqDebug()<<"prectrot->m_angle:"<<prectrot->m_angle;
            return;
        default :Q_ASSERT(0);break;
        }
        rectf.moveCenter(center);
        prectrot->m_center=CMPointd(rectf.center().x(),rectf.center().y());
        prectrot->m_width=max(rectf.width(),minlen);
        prectrot->m_height=max(rectf.height(),minlen);
        break;
    }
    case CShape::COELLIPSE:
    {

        CCoEllipse* pCoEllipse=(CCoEllipse*)m_pSelected_shape;
        QRectF rectf=QRectF(pCoEllipse->m_center.tX-pCoEllipse->m_widthin/2,
                            pCoEllipse->m_center.tY-pCoEllipse->m_heightin/2,
                            pCoEllipse->m_widthin,
                            pCoEllipse->m_heightin);
        QPointF pointLP=m_trans_DP2LP.map(point);
        if(m_hitType==HIT_LEFT||m_hitType==HIT_TOP||m_hitType==HIT_BOTTOM||
                m_hitType==HIT_RIGHT)
        {

            QPointF center=rectf.center();
            //   QLineF radiusLine=QLineF(pointLP,center);
            //   double radius=radiusLine.length();
            //   rectf.setWidth(radius*2);
            //   rectf.setHeight(radius*2);
            bool badjustWidth=false;
            switch(m_hitType)
            {

            case HIT_LEFT:   rectf.setLeft(pointLP.x()); badjustWidth=true;    break;
            case HIT_TOP:    rectf.setTop(pointLP.y()); badjustWidth=false;  break;
            case HIT_BOTTOM: rectf.setBottom(pointLP.y()); badjustWidth=false;  break;
            case HIT_RIGHT:  rectf.setRight(pointLP.x()); badjustWidth=true;  break;
            default :break;
            }
            if(badjustWidth)
            {
                rectf.setHeight(rectf.width());
            }
            else
            {
                rectf.setWidth(rectf.height());
            }

            rectf.moveCenter(center);
            pCoEllipse->m_center=CMPointd(rectf.center().x(),rectf.center().y());
            pCoEllipse->m_widthin=max(rectf.width(),minlen);
            pCoEllipse->m_widthin=min(pCoEllipse->m_widthout-minlen,pCoEllipse->m_widthin);
            pCoEllipse->m_heightin=max(rectf.height(),minlen);
            pCoEllipse->m_heightin=min(pCoEllipse->m_heightout-minlen,pCoEllipse->m_heightin);

        }
        else
        {

            rectf=QRectF(pCoEllipse->m_center.tX-pCoEllipse->m_widthout/2,
                         pCoEllipse->m_center.tY-pCoEllipse->m_heightout/2,
                         pCoEllipse->m_widthout,
                         pCoEllipse->m_heightout);
            QPointF center=rectf.center();

            //     QLineF radiusLine=QLineF(pointLP,center);
            //     double radius=radiusLine.length();
            //     rectf.setWidth(radius*2);
            //     rectf.setHeight(radius*2);
            bool badjustWidth=false;
            switch(m_hitType)
            {

            case LEFT_OUT:   rectf.setLeft(pointLP.x()); badjustWidth=true;    break;
            case TOP_OUT:    rectf.setTop(pointLP.y()); badjustWidth=false;  break;
            case BOTTOM_OUT: rectf.setBottom(pointLP.y()); badjustWidth=false;  break;
            case RIGHT_OUT:  rectf.setRight(pointLP.x()); badjustWidth=true;  break;
            case HIT_IN:   center+=(pointLP-oldpoint_lp);break;
            default :break;
            }
            if(badjustWidth)
            {
                rectf.setHeight(rectf.width());
            }
            else
            {
                rectf.setWidth(rectf.height());
            }
            rectf.moveCenter(center);
            pCoEllipse->m_center=CMPointd(rectf.center().x(),rectf.center().y());
            pCoEllipse->m_widthout=max(rectf.width(),minlen);
            pCoEllipse->m_widthout=max(pCoEllipse->m_widthout,pCoEllipse->m_widthin+minlen);
            pCoEllipse->m_heightout=max(rectf.height(),minlen);
            pCoEllipse->m_heightout=max(pCoEllipse->m_heightout,pCoEllipse->m_heightin+minlen);
        }
        break;
    }
    default:
        Q_ASSERT(0);
        break;
    }
}

bool CCtrlMImgContainer::is_shape_selected(CShape *pshape)
{
    return (pshape==m_pSelected_shape)&&is_shape_can_selected(pshape);
}

bool CCtrlMImgContainer::is_shape_can_selected(CShape *pshape)
{
    return pshape->etype==CShape::RECT_DEVICE||pshape->etype==CShape::RECT_ROT||
            pshape->etype==CShape::COELLIPSE;
}

bool CCtrlMImgContainer::is_hitted()
{
    return m_hitType!=HIT_OUT&&m_pSelected_shape;
}
