#include "cctrlmimg_opengl.h"
#include <QPainter>
#include <QTransform>
#include <QStylePainter>
#include <QSizeF>
#include <QMutexLocker>
#include <QOpenGLPaintDevice>
#include <QDateTime>
#include "m_math.h"
#include "logic.h"
#include "gui.h"

#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 CCtrlMImg_OPenGL::initializeGL()
{
    makeCurrent();
    initializeOpenGLFunctions(); //初始化OPenGL功能函数
    glClearColor(0.925f, 0.925f, 0.925f, 1.0f);    //设置背景为黑色
    //m_device=new QOpenGLPaintDevice;

}

void CCtrlMImg_OPenGL::resizeGL(int w, int h)
{
    UNUSED(w);
    UNUSED(h);
    ZoomFit();
    refreshPixmap();
}

void CCtrlMImg_OPenGL::paintGL()
{
    makeCurrent();
    QPainter painter(this);
    painter.setRenderHint(QPainter::SmoothPixmapTransform);
    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());
        }
    }
}

CCtrlMImg_OPenGL::CCtrlMImg_OPenGL(QWidget *parent) :
    QOpenGLWidget(parent)
{
    //m_device=0;
	m_dOrinScale=0.25;
    m_pContainer=0;
    m_dcurScale=1;
    m_dmaxScale=4;
    m_dminScale=0.25;
	m_bIsCamera = false;

    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_bInited=false;
    m_bEnableMouseZoom=false;
    m_bEnableClickZoom=true;
    m_bContainerInside=true;

    m_BKColor=QRgb(0x000080);
    m_PenColor=QRgb(0x00ff00);
    m_contextMenu = new QMenu;
    savecontainer = new QAction(tr("save container"),this);
    saveimage = new QAction(tr("save image"),this);
    connect(savecontainer, SIGNAL(triggered()), this, SLOT(saveContainer()));
    connect(saveimage, SIGNAL(triggered()), this, SLOT(saveImage()));

    m_contextMenu->addAction(savecontainer);
    m_contextMenu->addAction(saveimage);
    setContextMenuPolicy(Qt::CustomContextMenu);
}

CCtrlMImg_OPenGL::~CCtrlMImg_OPenGL()
{
    makeCurrent();
    if(m_bContainerInside&&m_pContainer)
    {
        delete    m_pContainer;
    }
    m_contextMenu->removeAction(savecontainer);
    m_contextMenu->removeAction(saveimage);
    delete savecontainer;
    delete saveimage;
    delete m_contextMenu;
    //    if(m_device)
    //    {
    //        delete m_device;
    //    }
}


void CCtrlMImg_OPenGL::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 CCtrlMImg_OPenGL::mousePressEvent(QMouseEvent *pEvent)
{
    QPointF pos(pEvent->pos());
    hittest_container_shapes(pos);
    if(is_hitted())
    {
        m_oldPoint=QPointF(pEvent->pos());
    }

}

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

void CCtrlMImg_OPenGL::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_pContainer->name+"_RawImage_"+QDateTime::currentDateTime()
            .toString(QString::fromUtf8("yyyy_MM_dd_HH_mm_ss"));
    QString filepath=CMakePath::make_file_path(imagename+".jpg");
    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 CCtrlMImg_OPenGL::saveContainer()
{
    if(!m_pContainer) return;
    QString filePathName = m_pContainer->name+"_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"))
    {
        m_gSystem.m_SysMsg.SetMsg(tr("Save container failed"));
    }
}

void CCtrlMImg_OPenGL::mouseReleaseEvent(QMouseEvent *pEvent)
{
    if(pEvent->button()==Qt::RightButton)
    {
        if(m_bEnableMouseZoom)
        {
            ZoomOrginal();
        }
        CWorker* pWorker=GET_CHDIRECT(M_WORKER,CWorker);
        if(pWorker->m_workLevel>2)
        {m_contextMenu->popup(pEvent->globalPos());}
    }
    if(!is_hitted()&&m_bEnableClickZoom
            &&pEvent->button()==Qt::LeftButton)
    {
        if(m_bFit)
        {
            ZoomOrginal();
        }
        else
        {
            ZoomFit();
        }
    }
}

void CCtrlMImg_OPenGL::showEvent(QShowEvent *pEvent)
{
    UNUSED(pEvent);
    if(!m_bInited)
    {
        ZoomFit();
        m_bInited=true;
    }
}


void CCtrlMImg_OPenGL::MTimeFresh()
{
    refreshPixmap();
    if(m_pContainer)
    {
        int  iImgWidth=m_pContainer->m_Image.m_width;
        int  iImgHeight=m_pContainer->m_Image.m_height;
        if(iImgWidth&&iImgHeight)
        {
            if(m_iCurWidth!=iImgWidth||m_iCurHeight!=iImgHeight)
            {
                ZoomFit();
                m_iCurWidth=iImgWidth;
                m_iCurHeight=iImgHeight;
            }
        }
    }
}


void CCtrlMImg_OPenGL::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;
    if (m_dcurScale < 0.02)
    {
        m_dcurScale = min(dfullviewwidth / (iImgWidth + 1),
                          dfullviewheight / (iImgHeight + 1));
    }
    QPointF imgViewCenter=m_rectImageView.center();
    double dimgviewwidth=iImgWidth*m_dcurScale;
    double dimgviewheight=iImgHeight*m_dcurScale;
    double dleft=0,dtop=0;
    double dRangeX=0,dRangeY=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();
        dRangeX= dimgviewwidth-dfullviewwidth;

    }
    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();
        dRangeY= dimgviewheight-dfullviewheight;
    }
    if(m_pHbar->isVisible())
    {
//        if(m_pVbar->isVisible())
//        {
//            dRangeX+=m_pVbar->width();
//        }
        m_pHbar->setRange(-dRangeX/2,dRangeX/2);
        m_pHbar->setPageStep(dRangeX/10);
        m_pHbar->setSingleStep(dRangeX/100);
    }
    if(m_pVbar->isVisible())
    {
//        if(m_pHbar->isVisible())
//        {
//            dRangeY+=m_pHbar->height();
//        }
        m_pVbar->setRange(-dRangeY/2,dRangeY/2);
        m_pVbar->setPageStep(dRangeY/10);
        m_pVbar->setSingleStep(dRangeY/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);//if(!bsuccess) return;
    m_trans_DP2LP=m_trans_LP2DP.inverted(&bsuccess);
    Q_ASSERT(bsuccess);//if(!bsuccess) return;
}

void CCtrlMImg_OPenGL::refreshPixmap()
{
    if(!isVisible()) return;
	//LOG(INFO) << "Cam Capture Start" << endl;
    makeCurrent();
    m_Pixmap=QPixmap(size());
    m_Pixmap.fill(m_BKColor);
    if(!m_pContainer){return;}

    int32_t  iImgWidth=m_pContainer->m_Image.m_width;
    int32_t  iImgHeight=m_pContainer->m_Image.m_height;
    /*if (iImgWidth < 1
        || iImgHeight < 1)
    {
        m_dcurScale = m_dOrinScale*2;
    }*/

    QPainter painter(&m_Pixmap);
    painter.initFrom(this);
    if(!painter.isActive())return;
    if(!iImgWidth||!iImgHeight)
    {
        draw_container_name( painter,true);

        return;
    }


    adjust_imgviewrect();
    painter.setClipRect(get_clipRect());

    draw_container_image(painter);
    draw_container_shapes( painter);
    draw_container_strings( painter);
    draw_container_name( painter,false);
	//LOG(INFO) << "Cam Capture Stop" << endl;

    update();

}

QRectF CCtrlMImg_OPenGL::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 CCtrlMImg_OPenGL::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);
    adjust_imgviewrect( );
}

void CCtrlMImg_OPenGL::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);
    adjust_imgviewrect( );
}

void CCtrlMImg_OPenGL::ZoomFit()
{
    if(!m_pContainer) return;
    m_bFit=true;
    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;

    if (iImgHeight == 0 || iImgWidth == 0)
    {
        m_dcurScale = 0.01;
        return;
    }

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

    refreshPixmap();
}

void CCtrlMImg_OPenGL::ZoomOrginal()
{
    m_dcurScale=m_dOrinScale;//以前是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);

    adjust_imgviewrect( );
    m_bFit=false;
    refreshPixmap();
}

void CCtrlMImg_OPenGL::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 CCtrlMImg_OPenGL::setImage(CMImage &Image)
{
    if(!m_pContainer) return;
    m_pContainer->SetImage(Image);
    ZoomFit();
    refreshPixmap();
}

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

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

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

void CCtrlMImg_OPenGL::draw_container_image(QPainter &painter)
{
    QMutexLocker locker(&m_pContainer->mutex);
    QImage img(m_pContainer->m_Image.m_pRawImage,
               m_pContainer->m_Image.m_width,
               m_pContainer->m_Image.m_height,
               m_pContainer->m_Image.m_width,
               QImage::Format_Grayscale8);
    painter.drawImage(m_rectImageView,img);
}

void CCtrlMImg_OPenGL::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(128,0,0)),0));
            draw_sel_shape((*ii),painter);
        }
    }
    for(SHAPELIST::iterator ii=m_pContainer->lmarkshapes.begin();
        ii!=m_pContainer->lmarkshapes.end();ii++)
    {
		if((*ii)->etype == CShape::LINE){
			CLine* pLine = (CLine*)(*ii);
			CLine line;
			double x1 = pLine->m_pt1.tX;
			double x2 = pLine->m_pt2.tX;
			double halfLength = (x2-x1)/4;
			line.m_pt1.tX = x1+halfLength;
			line.m_pt2.tX = x2-halfLength;
			line.m_pt1.tY = pLine->m_pt1.tY;
			line.m_pt2.tY = pLine->m_pt2.tY;
			draw_shape(&line,painter);
			continue;
		}
		
        draw_shape((*ii),painter);
    }
}
void CCtrlMImg_OPenGL::draw_container_strings(QPainter &painter)
{
    Q_ASSERT(m_pContainer);
    

	QFont font = painter.font();
	font.setPointSize(14);
	painter.setFont(font);

    painter.setPen(QPen(m_PenColor,0));
	//painter.setPen(QPen(Qt::blue,0));
    QRectF rectClip=m_rectImageView.intersected(get_clipRect());
    painter.setClipRect(rectClip);
    QString text;
    QMutexLocker locker(&m_pContainer->mutex);
    text=m_pContainer->lstrs.join('\n');
	if (rectClip.left() < 70)
	{
		rectClip.setLeft(70);
	}

	if(text.length()>35 || m_pContainer->lstrs.length()>5){
		font.setPointSize(13);
		painter.setFont(font);
	}
    painter.drawText(rectClip,
                     Qt::AlignTop|Qt::AlignLeft,text);

	font.setPointSize(10);
	painter.setFont(font);
}

void CCtrlMImg_OPenGL::draw_container_name(QPainter &painter, bool bedge)
{
    Q_ASSERT(m_pContainer);

    painter.setPen(QPen(m_PenColor,2));
    //    QMutexLocker locker(&m_pContainer->mutex);
    QRectF rectClip=rect();
    if(!bedge)
    {
        rectClip=m_rectImageView.intersected(get_clipRect());
    }

	QFont font = painter.font();
	font.setPointSize(13);
	painter.setFont(font);


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

void CCtrlMImg_OPenGL::draw_sel_shape(CShape *pshape, QPainter &painter)
{
    Q_ASSERT(pshape);
    switch(pshape->etype)
    {
    case CShape::RECT_DEVICE:
    {
        CRect* prect=(CRect*)pshape;
		if(prect->m_width>prect->m_center.tX*2){
			prect->m_width = prect->m_center.tX*2-20;
		}
		if(prect->m_height>prect->m_center.tY*2){
			prect->m_height = prect->m_center.tY*2-20;
		}
        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 CCtrlMImg_OPenGL::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::DashDotDotLine);
		pen.setStyle(Qt::CustomDashLine);
		QVector<qreal>dashes;
		qreal space = 6;
		dashes<<4<<space<<4<<space;
		pen.setDashPattern(dashes);
		pen.setWidth(1);
		//if(m_bIsCamera)
		//	pen.setWidthF(2);
		//else
		//	pen.setWidthF(1.5);

		int penWidth = pen.width();
		int x = penWidth;
    }
    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::DLINE:
    {
        CDLine* pline=(CDLine*)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);
		//qDebug()<<"HairLinePt:pt1("<<linef.x1()<<","<<linef.y1()<<") pt2(" << linef.x2() <<","<< linef.y2() << ")";
        painter.drawLine(linef);
        QLineF linef2(QPointF(pline->m_pt3.tX,pline->m_pt3.tY),
                      QPointF(pline->m_pt4.tX,pline->m_pt4.tY));
        linef2=m_trans_LP2DP.map(linef2);
        painter.drawLine(linef2);
        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/3,pcross->m_center.tY),
                      QPointF(pcross->m_center.tX+pcross->m_width/3,pcross->m_center.tY));

        QLineF linef2(QPointF(pcross->m_center.tX,pcross->m_center.tY-pcross->m_height/3),
                      QPointF(pcross->m_center.tX,pcross->m_center.tY+pcross->m_height/3));
        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));

        int isize=Polygon.size();
        for(int i=0;i<isize;i++)
        {
            Polygon[i]-=pointCenter;
        }
        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 CCtrlMImg_OPenGL::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 CCtrlMImg_OPenGL::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 CCtrlMImg_OPenGL::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 CCtrlMImg_OPenGL::is_shape_selected(CShape *pshape)
{
    return (pshape==m_pSelected_shape)&&is_shape_can_selected(pshape);
}

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

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