#include <QMessageBox>
#include "cmwmanualcut.h"
#include "ui_cmwmanualcut.h"
#include "logic.h"
#include "cmwparamcutside.h"
#include "cctrlbuttonid.h"
#include "qmymessagebox.h"
#include "vst_semi_main.h"

CMWManualCut::CMWManualCut(QWidget *parent) :
    CMWidget(parent),
    ui(new Ui::CMWManualCut)
{
    ui->setupUi(this);
    m_iCurLineCount=-1;
	m_iLineSelected=-1;
}

CMWManualCut::~CMWManualCut()
{
    delete ui;
}

void CMWManualCut::MInit()
{
    ui->tableWidget_Line->horizontalHeader()->
            setSectionResizeMode(QHeaderView::Stretch);
    mchildwidgets[0]=new CMWParamCutSide(this,SIDE_A,true);
    ui->horizontalLayout->addWidget(mchildwidgets[0]);
	ui->tableWidget_Line->setColumnHidden(4, true);
	ui->tableWidget_Line->setColumnWidth(0, 30);
}

void CMWManualCut::MApply()
{
    CMWidget::MApply();
}

void CMWManualCut::MFresh()
{
    if(m_gSystem.m_iCurSideID!=SIDE_A&&m_gSystem.m_iCurSideID!=SIDE_B)
    {
        showShieldWindow(true,
                         QObject::trUtf8("Switch to any side."));
        return;
    }
    showShieldWindow(false);
    m_iCurSideID=m_gSystem.m_iCurSideID;
    ui->label_Side->setText(m_gSystem.m_mapNameList[m_iCurSideID]);
    ((CMWParamCutSide*)(mchildwidgets[0]))->m_iSideID=m_iCurSideID;
    mchildwidgets[0]->MFresh();
	ui->txtLocationAfterIndex->setText("1");
	//ui->tableWidget_Line->setColumnHidden(4, true);

	CWorker* pWorker=GET_CHDIRECT(M_WORKER,CWorker);
	if(pWorker->m_workLevel>=LEVEL_ENGINEER){
		bool isVisible = true;
		ui->groupBox->setVisible(isVisible);
		//ui->btnAngleSet->setVisible(isVisible);
		ui->pushButton_ClearLines->setVisible(isVisible);
	}else{
		bool isVisible = false;
		ui->groupBox->setVisible(isVisible);		
		//ui->btnAngleSet->setVisible(isVisible);
		ui->pushButton_ClearLines->setVisible(isVisible);
	}
	if(pWorker->m_workLevel>=LEVEL_ENGINEER){
		bool isVisible = true;
		ui->label->setVisible(isVisible);
		ui->label_2->setVisible(isVisible);
		
		ui->label_4->setVisible(isVisible);
		ui->lineEdit_Start->setVisible(isVisible);
		ui->lineEdit_End->setVisible(isVisible);
		
		ui->txtStep->setVisible(isVisible);
		ui->pushButton_Stop->setVisible(isVisible);
		//ui->btnAngleSet->setVisible(isVisible);
		
		ui->btnIdx->setVisible(isVisible);
		ui->label_10->setVisible(isVisible);
		ui->lblCurLine->setVisible(isVisible);
		ui->txtLocationAfterIndex->setVisible(isVisible);
		ui->btnLocationCurLineAndAfter->setVisible(isVisible);
		ui->label_7->setVisible(isVisible);
		ui->btnManualLineCut->setVisible(isVisible);
	}else{
		bool isVisible = false;
		ui->label->setVisible(isVisible);
		ui->label_2->setVisible(isVisible);
		//ui->label_3->setVisible(isVisible);
		ui->label_4->setVisible(isVisible);
		ui->lineEdit_Start->setVisible(isVisible);
		ui->lineEdit_End->setVisible(isVisible);
		//ui->lineEdit_Channel->setVisible(isVisible);
		ui->txtStep->setVisible(isVisible);
		ui->pushButton_Stop->setVisible(isVisible);
		//ui->btnAngleSet->setVisible(isVisible);
		//ui->groupBox->setVisible(isVisible);
		ui->btnIdx->setVisible(isVisible);
		ui->label_10->setVisible(isVisible);
		ui->lblCurLine->setVisible(isVisible);
		ui->txtLocationAfterIndex->setVisible(isVisible);
		ui->btnLocationCurLineAndAfter->setVisible(isVisible);
		ui->label_7->setVisible(isVisible);
		ui->btnManualLineCut->setVisible(isVisible);
	}

	if(pWorker->m_workLevel >= LEVEL_FACTORAY){
		bool isVisible = true;
		ui->label_5->setVisible(isVisible);
		ui->label_8->setVisible(isVisible);
		ui->spDelay->setVisible(isVisible);
		ui->spDelayEnd->setVisible(isVisible);
		ui->label_6->setVisible(isVisible);
		ui->label_9->setVisible(isVisible);
		ui->chkEnableKerfWatch->setVisible(isVisible);
		ui->chkEnableKerfCut->setVisible(isVisible);
		ui->lineEdit_Channel->setVisible(isVisible);

		ui->btnToKerf->setVisible(isVisible);
		ui->btnKerfCut->setVisible(isVisible);
		ui->btnAngleSet->setVisible(isVisible);
		//ui->pushButton_ClearLines->setVisible(isVisible);
		ui->btnLocationCurLine->setVisible(isVisible);
		ui->pushButton_GenLines->setVisible(isVisible);

		ui->label_3->setVisible(isVisible);
	}else{
		bool isVisible = false;
		ui->label_5->setVisible(isVisible);
		ui->label_8->setVisible(isVisible);
		ui->spDelay->setVisible(isVisible);
		ui->spDelayEnd->setVisible(isVisible);
		ui->label_6->setVisible(isVisible);
		ui->label_9->setVisible(isVisible);
		ui->chkEnableKerfWatch->setVisible(isVisible);
		ui->chkEnableKerfCut->setVisible(isVisible);
		ui->lineEdit_Channel->setVisible(isVisible);

		ui->btnToKerf->setVisible(isVisible);
		ui->btnKerfCut->setVisible(isVisible);
		ui->btnAngleSet->setVisible(isVisible);
		//ui->pushButton_ClearLines->setVisible(isVisible);
		ui->btnLocationCurLine->setVisible(isVisible);
		ui->pushButton_GenLines->setVisible(isVisible);
		ui->label_3->setVisible(isVisible);
	}

	ui->pushButton_LineCut->setVisible(false);
	ui->btnReadCutData->setVisible(false);
	ui->btnWriteCutData->setVisible(false);

    ui->label_5->setVisible(false);
    ui->label_8->setVisible(false);
    ui->spDelay->setVisible(false);
    ui->spDelayEnd->setVisible(false);
    ui->label_9->setVisible(false);
    ui->label_6->setVisible(false);
    ui->chkEnableKerfWatch->setVisible(false);
    ui->chkEnableKerfCut->setVisible(false);
}

void CMWManualCut::MTimeFresh()
{
    if( strCurFile!=m_gSystem.GetCurFile()||
            m_iCurSideID!=m_gSystem.m_iCurSideID)
    {
        strCurFile=m_gSystem.GetCurFile();
        m_iCurSideID=m_gSystem.m_iCurSideID;

        MFresh();
    }
    FreshLines();

	QMutexLocker l(&m_gSystem.FindSM(SM_MAIN)->m_SMMutex);
	VST_Semi_Main* pSemiState = (VST_Semi_Main*)(m_gSystem.FindSM(SM_MAIN)->m_pState_Semi);
	int iType = m_gSystem.FindSM(SM_MAIN)->m_pCurState->m_iStateType;
	bool bSemiRun = false;
	if(iType == VS_Thread::State_Semi || iType == VS_Thread::State_Work_Semi
		|| m_gSystem.FindSM(SM_MAIN)->m_pHistoryState_Semi)
	{
		//半自动运行中
		bSemiRun = true;
	}
	l.unlock();

	int iCurOperator = pSemiState->m_iCurOperator;
	if(bSemiRun){
		if(iCurOperator == VarMsg_Manual_StartCut){
			ui->btnManualLineCut->setEnabled(true);
			ui->btnManualLineCut->setChecked(true);
		}else{
			ui->btnManualLineCut->setEnabled(false);
			ui->btnManualLineCut->setChecked(false);
		}
		ui->btnAngleSet->setEnabled(false);
	}else{
		ui->btnManualLineCut->setEnabled(true);
		ui->btnManualLineCut->setChecked(false);
		ui->btnAngleSet->setEnabled(true);
	}
}

void CMWManualCut::FreshLines(bool bForce/*=false*/)
{
    if((m_iCurSideID!=SIDE_A&&m_iCurSideID!=SIDE_B))return;
    CProductSide* pSide=GET_CHDIRECT(m_iCurSideID,CProductSide);
    int isize=pSide->m_CutLineVector.size();
    if(isize!=m_iCurLineCount || bForce)
    {
        //ui->txtLocationAfterIndex->setText("1");
		m_iLineSelected = -1;
        m_iCurLineCount=isize;
        ui->tableWidget_Line->clearContents();
        ui->tableWidget_Line->setRowCount(isize);
        for(int i=0;i<isize;i++)
        {
            CUTLINE* pLine= pSide->m_CutLineVector.mget(i);
            QString strLineId;
            if(pLine->m_bSUB)
            {
                strLineId=QString::fromUtf8("(%1)").arg(pLine->m_index+1);
            }
            else
            {
                strLineId=QString::fromUtf8("%1").arg(pLine->m_index+1);
            }
            QTableWidgetItem* pItem=new QTableWidgetItem(strLineId);
            pItem->setForeground(Qt::black);
            pItem->setTextAlignment(Qt::AlignCenter);
            ui->tableWidget_Line->setItem(i,0,pItem);

			pItem=new QTableWidgetItem(QString("Y:%1").arg(pLine->m_BasePt.tY));
			ui->tableWidget_Line->setItem(i,1,pItem);
			
			pItem=new QTableWidgetItem(QString("X:%1").arg(pLine->m_WPPair.ptNegative.tX));
            ui->tableWidget_Line->setItem(i,2,pItem);

            pItem=new QTableWidgetItem(QString("X:%1").arg(pLine->m_WPPair.ptPostive.tX));
            ui->tableWidget_Line->setItem(i,3,pItem);

            pItem=new QTableWidgetItem(QString::number(pLine->m_YOffset));
            ui->tableWidget_Line->setItem(i,4,pItem);
        }

    }
    int iSizeParam= pSide->m_vCutParam.size();
    for(int i=0;i<isize;i++)
    {
        QTableWidgetItem* pItem=ui->tableWidget_Line->item(i,0);
        QColor color=QColor(0,0,255);
		QColor forgroundColor = Qt::white;
        QMutexLocker locker(&pSide->m_CutLineVector.mutex);
        CUTLINE* pLine= pSide->m_CutLineVector.mget(i);
        int iLayer=-1;
        if(pLine)
        {
            iLayer=pLine->m_bHasCut-1;
        }
        locker.unlock();
        if(iLayer>=0&&iSizeParam)
        {
            int iStepColor=255/iSizeParam*(iLayer+1);
            //color=QColor(iStepColor,0,255-iStepColor);
			color=QColor(0,iStepColor,0);
			forgroundColor = Qt::black;
        }
        if(m_gSystem.m_iCurLine==i)
        {
			if(pLine->m_bHasCut>0){
				color=Qt::darkGreen;
				forgroundColor = Qt::yellow;
			}else{
				color=QColor(255,255,0);
				forgroundColor = Qt::black;
			}
			
        }
        pItem->setBackgroundColor(color);
		pItem->setForeground(forgroundColor);
    }

}

static bool CalcuBasePos(int isideID, int iLine,V_MsgQueue& msgqueue)
{
    CProductSide* pSide=GET_CHDIRECT(isideID,CProductSide);
	Q_ASSERT(isideID);
    QMutexLocker locker1(&pSide->m_CutLineVector.mutex);
	if(iLine > pSide->m_CutLineVector.size())
	{
		//QMessageBox::information(this, tr("Error"), tr("Cut line %1> LineVector:%2").arg(iLine).arg(pSide->m_CutLineVector));
		m_gSystem.m_SysMsg.SetMsg(QObject::trUtf8("Cut line %1 > LineVector size:%2").arg(iLine).arg(pSide->m_CutLineVector.size()));
		return false;
	}
    const CUTLINE& line= pSide->m_CutLineVector[iLine];
	locker1.unlock();

    //if(line.m_bSUB==false)
    {

        msgqueue.pushback_Msg(VarMsg_Process_ID,
                              QObject::trUtf8("Calcu pt by Line Sig"),
                              QVariantList()
                              <<PROCESS_LEVELING
                              <<CProcess_Level::CALCU_PT_BY_LINE
                              <<isideID<<iLine ,0);

    }
	return true;

}

//在外边缘切割的Kerf
static void AddKerfCutSingle(int isideID, int iLine,V_MsgQueue& msgqueue)
{
    /*msgqueue.pushback_Msg(VarMsg_Process_ID,
        QObject::trUtf8("Calcu pt and cut on film"),
        QVariantList()
        <<PROCESS_LASERKERF
        <<CProcess_LaserKerf::CUTKERFLINE
        <<isideID<<iLine<<0 ,0);*/

	msgqueue.pushback_Msg(VarMsg_Process_ID,
		QObject::trUtf8("Move Kerf Pt"),
		QVariantList()
		<<PROCESS_LASERKERF
		<<CProcess_LaserKerf::MOVEKERFPOS,0);

	msgqueue.pushback_Msg(VarMsg_Process_ID,
		QObject::trUtf8("Laser Cali"),
		QVariantList()
		<<PROCESS_LASERKERF
		<<CProcess_LaserKerf::KERF
		<<isideID<<0,0);
}


//添加仅观察的Kerf
static void AddKerfWatchSingle(int isideID, int iLine,V_MsgQueue& msgqueue)
{
	CProductSide* pSide=GET_CHDIRECT(isideID,CProductSide);
	QMutexLocker locker1(&pSide->m_CutLineVector.mutex);
	msgqueue.pushback_Msg(VarMsg_Process_ID,
		QObject::trUtf8("Calcu pt by Line Sig"),
		QVariantList()
		<<PROCESS_LEVELING
		<<CProcess_Level::CALCU_PT_BY_LINE
		<<isideID<<iLine ,0);

	msgqueue.pushback_Msg(VarMsg_Process_ID,
		QObject::trUtf8("Calcu pt by Line Sig"),
		QVariantList()
		<<PROCESS_KERFCHECK
		<<CProcess_Kerf::CALCUKERFPOS
		<<isideID<<iLine<<0 ,0);

	msgqueue.pushback_Msg(VarMsg_Process_ID,
		QObject::trUtf8("Move Kerf Pos"),
		QVariantList()
		<<PROCESS_KERFCHECK
		<<CProcess_Kerf::MOVEKERFPOS,0);

	msgqueue.pushback_Msg(VarMsg_Process_ID,
		QObject::trUtf8("Move Kerf Watch Sig"),
		QVariantList()
		<<PROCESS_KERFCHECK
		<<CProcess_Kerf::KERF_WATCH
		<<isideID<<0,0);
}


static void CalcuKerfPos(int isideID, int iLine, int iLayer,V_MsgQueue& msgqueue)
{
    CProductSide* pSide=GET_CHDIRECT(isideID,CProductSide);
    QMutexLocker locker1(&pSide->m_CutLineVector.mutex);
    const CUTLINE& line= pSide->m_CutLineVector[iLine];

    if(line.m_bSUB==false)
    {
        msgqueue.pushback_Msg(VarMsg_Process_ID,
                              QObject::trUtf8("Calcu Kerf Pos Sig"),
                              QVariantList()
                              <<PROCESS_KERFCHECK
                              <<CProcess_Kerf::CALCUKERFPOS
                              <<isideID<<iLine<<iLayer ,0);
    }
}
//单线切割
static void CutSingleLine(int isideID,int iLine,int iLayer,V_MsgQueue& msgqueue)
{
    if(false == CalcuBasePos(  isideID,   iLine,msgqueue)){
		//
		return;
	}
    msgqueue.pushback_Msg(VarMsg_Process_ID,
                          QObject::trUtf8("Manual Cut Line Sig"),
                          QVariantList()
                          <<PROCESS_CUT
                          <<CProcess_Cut::CUT_CUTLINE
                          <<isideID<<iLine<<iLayer<<0 ,0);
    CalcuKerfPos(  isideID,   iLine,   iLayer,msgqueue);
}
void CMWManualCut::on_pushButton_LineCut_clicked()
{
	VSMT_Base* pSM= (VSMT_Base*)m_gSystem.FindSM(SM_MAIN);
	if(pSM->IsIdle())
	{
		if(pSM->GetIdleState()->QueueSize()>3){
			m_gSystem.m_SysMsg.SetMsg(tr("Waiting action finish"));
			return;
		}
	}

    Q_ASSERT(!(m_iCurSideID!=SIDE_A&&m_iCurSideID!=SIDE_B));
    CProductSide* pSide=GET_CHDIRECT(m_iCurSideID,CProductSide);
    Q_ASSERT(pSide);
    CProduct* pProduct=GET_CHDIRECT(PRODUCT,CProduct);
    Q_ASSERT(pProduct);
    QMutexLocker locker(&pSide->m_CutLineVector.mutex);
    int isizeLine=pSide->m_CutLineVector.size();
    locker.unlock();
    QMutexLocker locker1(&pSide->m_vCutParam.mutex);
    int isizeParam=pSide->m_vCutParam.size();
    locker1.unlock();

    int iStart=ui->lineEdit_Start->text().toDouble()-1;
    int iEnd=ui->lineEdit_End->text().toDouble()-1;
    if(OUTOFRANGE(iStart,0,isizeLine)||
            OUTOFRANGE(iEnd,0,isizeLine)||
            iStart>iEnd)
    {
        m_gSystem.m_SysMsg.SetMsg(tr("line id is not valid"));
        return;
    }

    int iChannel=ui->lineEdit_Channel->text().toDouble();
    if(iChannel>0&&OUTOFRANGE(iChannel-1,0,isizeParam))
    {

        m_gSystem.m_SysMsg.SetMsg(tr("channel id is not valid"));
        return;
    }
    //
    bool_t bLineCycle=pProduct->m_Variants.get_VData(Var_MProduct_CutType_ID)
            ->toUInt() == 0;

    V_MsgQueue msgqueue;
    if(iChannel<=0)
    {
        if(bLineCycle)
        {
            //按所有通道一道一道切
            for(int i=iStart;i<=iEnd;i++)
            {
                for(int j=0;j<isizeParam;j++)
                {
                    CutSingleLine(m_iCurSideID,i,j,msgqueue);
                }
            }
        }
        else
        {
            for(int j=0;j<isizeParam;j++)
            {
                for(int i=iStart;i<=iEnd;i++)
                {
					/*if(ui->chkEnableKerfCut->isChecked())
					{
					if(0==j)
					{
					if(i==iStart || 0 == i%10)
					{
					AddKerfCutSingle(m_iCurSideID,i,msgqueue);
					}
					}
					}*/

                    CutSingleLine(m_iCurSideID,i,j,msgqueue);

					//切割后检测
					if(ui->chkEnableKerfWatch->isChecked())
					{
					if(0==j)
					{
					if(i==iStart || 0 == i%5)
					{
					AddKerfWatchSingle(m_iCurSideID,i,msgqueue);
					}
					}
					}
                }
            }
        }
    }
    else
    {
        //特定通道切割
        for(int i=iStart;i<=iEnd;i++)
        {
            CutSingleLine(m_iCurSideID,i,iChannel-1,msgqueue);
        }
    }

    msgqueue.pushback_Msg(VarMsg_Process_ID,
                          QObject::trUtf8("Move Kerf Pos Sig"),
                          QVariantList()
                          <<PROCESS_KERFCHECK
                          <<CProcess_Kerf::MOVEKERFPOS ,0);

    msgqueue.pushback_Msg(VarMsg_Driver_ID,
                          QObject::trUtf8("Switch Laser Sig"),
                          QVariantList()
                          <<LASER_DRIVER
                          <<CLaserDriver::OPENLASERGATE
                          <<LASERPATH_D_NARROW<<false,0);
    m_gSystem.start_manual(SM_MAIN, msgqueue);
}

void CMWManualCut::on_pushButton_Stop_clicked()
{
	//if(m_gSystem.FindSM(SM_MAIN)->m_pCurState == m_gSystem.FindSM(SM_MAIN)->m_pState_Idle){
	//	m_gSystem.FindSM(SM_MAIN)->
	//			m_pCurState->pushfront_Msg(VarMsg_Stop_ID,
	//									   QObject::trUtf8("Stop Manual Cut"));
	//}else{
		m_gSystem.StopSemi(SM_MAIN);
	//}	
}

void CMWManualCut::on_pushButton_Pos1_clicked()
{
    CMWorkTableDriver* pWorkTableDriver=GET_CARD(
                WORKTABLE_DRIVER,CMWorkTableDriver);
    pWorkTableDriver->CurAxisToWt(m_gSystem.m_iCurChID,m_Wt1,true);
    m_Wt2.tY=m_Wt1.tY;
}

void CMWManualCut::on_pushButton_Pos1MoveTo_clicked()
{
    CMPointd Axis;
    CMWorkTableDriver* pWorkTableDriver=GET_CARD(
                WORKTABLE_DRIVER,CMWorkTableDriver);
    pWorkTableDriver->WtToAxis(m_gSystem.m_iCurChID,m_Wt1,Axis);
    V_MsgQueue msgqueue;
    m_gSystem.absmove_xy_msg(Axis.tX,Axis.tY,msgqueue);
    m_gSystem.start_test(SM_MAIN, msgqueue,true);
}

void CMWManualCut::on_pushButton_Pos2_clicked()
{
    CMWorkTableDriver* pWorkTableDriver=GET_CARD(
                WORKTABLE_DRIVER,CMWorkTableDriver);
    pWorkTableDriver->CurAxisToWt(m_gSystem.m_iCurChID,m_Wt2,true);
}

void CMWManualCut::on_pushButton_Pos2MoveTo_clicked()
{
    CMPointd Axis;
    CMWorkTableDriver* pWorkTableDriver=GET_CARD(
                WORKTABLE_DRIVER,CMWorkTableDriver);
    pWorkTableDriver->WtToAxis(m_gSystem.m_iCurChID,m_Wt2,Axis);
    V_MsgQueue msgqueue;
    m_gSystem.absmove_xy_msg(Axis.tX,Axis.tY,msgqueue);
    m_gSystem.start_test(SM_MAIN, msgqueue,true);
}
//按点切割
static void CutSinglePosX(int isideID,double dStartPosX, double dEndPosX,
                         double dPosY,
                         int iLayerID,V_MsgQueue& msgqueue)
{
    msgqueue.pushback_Msg(VarMsg_Process_ID,
                          QObject::trUtf8("Cut Pos Sig"),
                          QVariantList()
                          <<PROCESS_CUT
                          <<CProcess_Cut::CUTPOS
                          <<isideID<<dStartPosX<<dEndPosX<<dPosY
                          <<iLayerID<<true,0);


	//计算中心Kerf的位置
    double dkerfPosX=min(dStartPosX,dEndPosX)+fabs(dEndPosX-dStartPosX)/2;
	msgqueue.pushback_Msg(VarMsg_Process_ID,
						QObject::trUtf8("Calcu Kerf Sig1"),
						QVariantList()
						<<PROCESS_KERFCHECK
						<<CProcess_Kerf::CALCUKERFPOS1
						<<dkerfPosX<<dPosY<<isideID
						<<iLayerID,0);
}
void CMWManualCut::on_pushButton_PosCut_clicked()
{

    Q_ASSERT(!(m_iCurSideID!=SIDE_A&&m_iCurSideID!=SIDE_B));
    CProductSide* pSide=GET_CHDIRECT(m_iCurSideID,CProductSide);
    Q_ASSERT(pSide);
    CProduct* pProduct=GET_CHDIRECT(PRODUCT,CProduct);
    Q_ASSERT(pProduct);

    QMutexLocker locker1(&pSide->m_vCutParam.mutex);
    int isizeParam=pSide->m_vCutParam.size();
    locker1.unlock();
    int iChannel=ui->lineEdit_Channel->text().toDouble();
    if(iChannel>0&&OUTOFRANGE(iChannel-1,0,isizeParam))
    {
        m_gSystem.m_SysMsg.SetMsg(tr("channel id is not valid"));
        return;
    }

	if(QMessageBox::Yes != QMessageBox::question(this, QObject::tr("Confirm"), 
		QObject::tr("Are you sure pos cut immediately")))
	{
		return;
	}
    if(m_Wt1.tX>m_Wt2.tX)
    {
        double dTemp=m_Wt1.tX;
        m_Wt1.tX=m_Wt2.tX;
        m_Wt2.tX=dTemp;
    }
    if(m_Wt1.tY<m_Wt2.tY)
    {
        double dTemp=m_Wt1.tY;
        m_Wt1.tY=m_Wt2.tY;
        m_Wt2.tY=dTemp;
    }
    bool_t bLineCycle=pProduct->m_Variants.get_VData(Var_MProduct_CutType_ID)
            ->toUInt() == 0;
    double dStep=pSide->m_Variants.get_VData(Var_ProductSide_SideStep)
            ->toDouble();

    double tmpStep = ui->txtStep->text().toDouble();
    if(tmpStep > 20){
        dStep = tmpStep/1000;

    }
    int iLayerID;
    V_MsgQueue  msgqueue;
    if(iChannel<=0)
    {
        if(bLineCycle)
        {
            for(double dstart=m_Wt1.tY;dstart>m_Wt2.tY-0.001;dstart-=dStep)
            {
                for(int j=0;j<isizeParam;j++)
                {
                    CutSinglePosX(m_iCurSideID,m_Wt1.tX,m_Wt2.tX,dstart,j
                                 ,msgqueue);
					iLayerID = j;
                }
            }
        }
        else
        {
            for(int j=0;j<isizeParam;j++)
            {
                for(double dstart=m_Wt1.tY;dstart>m_Wt2.tY-0.001;dstart-=dStep)
                {
                    CutSinglePosX(m_iCurSideID,m_Wt1.tX,m_Wt2.tX,dstart,j
                                 ,msgqueue);
                }
				iLayerID = j;
            }
        }
    }
    else
    {
        for(double dstart=m_Wt1.tY;dstart>m_Wt2.tY-0.001;dstart-=dStep)
        {
            CutSinglePosX(m_iCurSideID,m_Wt1.tX,m_Wt2.tX,dstart,iChannel-1
                         ,msgqueue);
			iLayerID = iChannel-1;
        }
    }


	//TODO:如果不Kerf，则运动到起点
	if(ui->chkEnableKerfCut->isChecked()){
		msgqueue.pushback_Msg(VarMsg_Process_ID,
			QObject::trUtf8("Move Kerf Pos Sig"),
			QVariantList()
			<<PROCESS_KERFCHECK
			<<CProcess_Kerf::MOVEKERFPOS ,0);


		msgqueue.pushback_Msg(VarMsg_Process_ID,
			QObject::trUtf8("Calcu Kerf Pos1 Sig"),
			QVariantList()
			<<PROCESS_KERFCHECK
			<<CProcess_Kerf::KERF
			<<m_gSystem.m_iCurSideID<<iLayerID,
			0);
	}else{
		//移动到起点
		msgqueue.pushback_Msg(VarMsg_Process_ID,
		                      QObject::trUtf8("Move to start"),
		                      QVariantList()
		                      <<PROCESS_CUT
		                      <<CProcess_Cut::MOVECUTPOS
		                      <<m_Wt1.tX<<m_Wt1.tY,0);
	}


	//关掉激光
    msgqueue.pushback_Msg(VarMsg_Driver_ID,
                          QObject::trUtf8("Move Kerf Pos Sig"),
                          QVariantList()
                          <<LASER_DRIVER
                          <<CLaserDriver::OPENLASERGATE
                          <<LASER<<false,0);

    m_gSystem.start_test(SM_MAIN, msgqueue);

}


void CMWManualCut::on_btnReadCutData_clicked()
{
	 /*CProductSide* pSideA =GET_CHDIRECT(SIDE_A,CProductSide);
	 pSideA->ReadRecoveredData();

	 CProductSide* pSideB =GET_CHDIRECT(SIDE_B,CProductSide);
	 pSideB->ReadRecoveredData();*/
}

void CMWManualCut::on_btnWriteCutData_clicked()
{
	/*CProductSide* pSideA =GET_CHDIRECT(SIDE_A,CProductSide);
	pSideA->WriteRecoveredData();

	CProductSide* pSideB =GET_CHDIRECT(SIDE_B,CProductSide);
	pSideB->WriteRecoveredData();*/
}

void CMWManualCut::on_btnManualLineCut_clicked()
{
	//int iStart=ui->lineEdit_Start->text().toInt();
	//int iEnd=ui->lineEdit_End->text().toInt();
	Q_ASSERT(!(m_iCurSideID!=SIDE_A&&m_iCurSideID!=SIDE_B));
	CProductSide* pSide=GET_CHDIRECT(m_iCurSideID,CProductSide);
	Q_ASSERT(pSide);
	QMutexLocker locker(&pSide->m_CutLineVector.mutex);
	int isizeLine=pSide->m_CutLineVector.size();
	locker.unlock();
	int iStart=ui->lineEdit_Start->text().toDouble()-1;
	int iEnd=ui->lineEdit_End->text().toDouble()-1;
	if(OUTOFRANGE(iStart,0,isizeLine)||
		OUTOFRANGE(iEnd,0,isizeLine)||
		iStart>iEnd)
	{
		m_gSystem.m_SysMsg.SetMsg(tr("line id is not valid"));
		return;
	}

	V_MsgQueue msgqueue;
	msgqueue.pushback_Msg(VarMsg_StartSemi_ID,
		QObject::trUtf8("Single Cut Sig"),
		QVariantList()<<VarMsg_Manual_StartCut<<m_iCurSideID<<iStart<<iEnd<<ui->btnKerfCut->isChecked()<<0<<0);

	int curOperateID = ((VST_Semi_Main*)(m_gSystem.FindSM(SM_MAIN)->m_pState_Semi))->m_iCurOperator;
	int ret = QMessageBox::Yes;
	//如果已经启动了，但是不是当前的操作，则需要处理这种情况
	if(curOperateID == VarMsg_Manual_StartCut){
		QMyMessageBox msgBoxAsk(QMessageBox::Question, tr("Confirm information"),tr("Operate not finish\n\nSelect what you want to do?"),
			QMessageBox::Yes | QMessageBox::Abort | QMessageBox::Cancel);
		//msgBoxAsk.setStandardButtons();
		msgBoxAsk.setDefaultButton(QMessageBox::Cancel);
		msgBoxAsk.setButtonText(QMessageBox::Yes, tr("Continue"));
		msgBoxAsk.setButtonText(QMessageBox::Abort, tr("Abort"));
		msgBoxAsk.setButtonText(QMessageBox::Cancel, tr("Cancel"));
		ret = msgBoxAsk.exec();
	}
	
	if(ret == QMessageBox::Abort){
		m_gSystem.StopSemi(SM_MAIN);
	}else if(ret == QMessageBox::Yes){
		if(curOperateID != -1 && curOperateID != VarMsg_Manual_StartCut)
		{
			QMessageBox::information(this, tr("Information"), tr("Another operation running, operation canceled"));
		}
		else
			m_gSystem.start_manual(SM_MAIN, msgqueue);
	}else{
		return;
	}
}

void CMWManualCut::on_tableWidget_Line_currentItemChanged(QTableWidgetItem *current,
                                                          QTableWidgetItem *previous)
{
	//HACK:切换时可能为-1
	if(m_iCurSideID!=SIDE_A&&m_iCurSideID!=SIDE_B)
	{
		return;
	}
    if(current)
    {
        if(current->column()>0 && current->column()<4)
        {

            CCtrlButtonID* pButton=new CCtrlButtonID(this,
                                                     current->row()|current->column()<<28);
            pButton->setText(tr("Move To"));
            ui->tableWidget_Line->
                    setCellWidget(current->row(),
                                  current->column(),
                                  pButton);
            connect(pButton,SIGNAL(MClick_Signal(int32_t)),
                    this,SLOT(mon_MovePos(int32_t)));

			m_iLineSelected = current->row();
			ui->lblCurLine->setText(QString::number(m_iLineSelected+1));
            V_MsgQueue  msgqueue;
            CalcuBasePos(m_iCurSideID, current->row(),msgqueue);
            m_gSystem.start_manual(SM_MAIN, msgqueue, true);
        }else if(current->column() == 4){
			CCtrlLineEdit* pLineEdit=new CCtrlLineEdit(current->text(),this);
			pLineEdit->SetRange(-10000,10000,true);
			ui->tableWidget_Line->setCellWidget(current->row(),
				current->column(),
				pLineEdit);
        }
    }
    if(previous)
    {
		if(previous->column() == 4){
			CCtrlLineEdit* pLineEdit=
				(CCtrlLineEdit*)ui->tableWidget_Line->cellWidget(previous->row(),
				previous->column());
			if(pLineEdit)
			{
				previous->setText(pLineEdit->text());

				CProductSide* pSide=GET_CHDIRECT(m_iCurSideID,CProductSide);
				Q_ASSERT(pSide);
				CUTLINE* pLine= pSide->m_CutLineVector.mget(previous->row());
				Q_ASSERT(pLine);
				pLine->m_YOffset = pLineEdit->text().toDouble();
			}
		}
        if(previous->column())
        {
            ui->tableWidget_Line->
                    removeCellWidget(previous->row(),
                                     previous->column());
        }
    }
}

void CMWManualCut::mon_MovePos(int32_t iID)
{
    int iMovePos=iID>>28;
    int iLineID=iID&0x0FFFFFFF;

    Q_ASSERT(!(m_iCurSideID!=SIDE_A&&m_iCurSideID!=SIDE_B));
    CProductSide* pSide=GET_CHDIRECT(m_iCurSideID,CProductSide);
    Q_ASSERT(pSide);
    QMutexLocker locker(&pSide->m_CutLineVector.mutex);
    CUTLINE* pLine=pSide->m_CutLineVector.mget(iLineID);
    if(pLine)
    {
        CMPointd Wt;
        switch(iMovePos)
        {
        case CENTER_POS:Wt=pLine->m_BasePt;break;
        case START_POS: Wt=pLine->m_WPPair.ptNegative;break;
        case END_POS: Wt=pLine->m_WPPair.ptPostive;break;
        }
        locker.unlock();
        CMPointd Axis;

        CMWorkTableDriver* pWorkTableDriver=GET_CARD(
                    WORKTABLE_DRIVER,CMWorkTableDriver);
        pWorkTableDriver->WtToAxis(m_gSystem.m_iCurChID,Wt,Axis);

		MqDebug() << "Line ID" << iLineID << "Line Wt X:" <<Wt.tX << " Y:" << Wt.tY;
        V_MsgQueue msgqueue;
        msgqueue.pushback_Msg(VarMsg_Driver_ID,QObject::trUtf8("XY Abs Move Sig"),
                              QVariantList()
                              <<MOTOR_DRIVER<<CMotorDriver::ABSMOVE_MULTI
                              <<MOTORX<<Axis.tX<<MOTORY<<Axis.tY,0);
        CalcuBasePos(  m_iCurSideID,   iLineID,msgqueue);
        m_gSystem.start_manual(SM_MAIN, msgqueue,true);
    }
}

//void CMWManualCut::on_pushButton_PosCut_2_clicked()
//{

//}

void CMWManualCut::on_pushButton_ClearLines_clicked()
{
	//需要停止时才能清除线
    if(!m_gSystem.IsSMStopped(SM_MAIN)){
		QMessageBox::information(this, tr("Information"), tr("Operation must stop at first"));
		return;
	}

    Q_ASSERT(!(m_iCurSideID!=SIDE_A&&m_iCurSideID!=SIDE_B));
    CProductSide* pSide=GET_CHDIRECT(m_iCurSideID,CProductSide);
    Q_ASSERT(pSide);
    pSide->m_CutLineVector.clear();
    m_iCurLineCount=-1;
    m_iLineSelected=-1;
    ui->txtLocationAfterIndex->setText("1");
    FreshLines();
    ui->lblCurLine->setText(QString::number(-1));
}

void CMWManualCut::on_pushButton_ImageCapture_clicked()
{

    Q_ASSERT(!(m_iCurSideID!=SIDE_A&&m_iCurSideID!=SIDE_B));
    CProductSide* pSide=GET_CHDIRECT(m_iCurSideID,CProductSide);
    Q_ASSERT(pSide);
    QMutexLocker locker(&pSide->m_CutLineVector.mutex);
//    CMWorkTableDriver* pworkTableDriver=GET_CARD(WORKTABLE_DRIVER,CMWorkTableDriver);
//    Q_ASSERT(pworkTableDriver);
    CUTLINE* pLine=pSide->GetCutLine(m_gSystem.m_iCurLine);
    if(pLine)
    {
        for(double dpos=pLine->m_WPPair.ptPostive.tX;
            dpos<pLine->m_WPPair.ptNegative.tX;dpos+=2)
        {

        }
    }
}

void CMWManualCut::on_pushButton_GenLines_clicked()
{
    if(!m_gSystem.IsAllSMStopped()) return;
    Q_ASSERT(!(m_iCurSideID!=SIDE_A&&m_iCurSideID!=SIDE_B));
    CProductSide* pSide=GET_CHDIRECT(m_iCurSideID,CProductSide);
    Q_ASSERT(pSide);

    CProcess_Level* process = GET_PROCESS(PROCESS_LEVELING, SM_MAIN, CProcess_Level);

	pSide->m_CutLineVector.clear();
    process->calcuLineCircle(m_iCurSideID);

    ui->txtLocationAfterIndex->setText("1");
    FreshLines();

    ui->lblCurLine->setText(QString::number(-1));
}

void CMWManualCut::on_spDelay_editingFinished()
{
    m_gSystem.m_LaserGateDelay = ui->spDelay->value();
}

void CMWManualCut::on_spDelayEnd_editingFinished()
{
    m_gSystem.m_LaserGateDelayEnd = ui->spDelayEnd->value();
}
void CMWManualCut::on_btnLocationCurLine_clicked()
{
	if(m_iLineSelected<0)return;
	int iLineID = m_iLineSelected;
	Q_ASSERT(!(m_iCurSideID!=SIDE_A&&m_iCurSideID!=SIDE_B));
	CProductSide* pSide=GET_CHDIRECT(m_iCurSideID,CProductSide);
	Q_ASSERT(pSide);
	QMutexLocker locker(&pSide->m_CutLineVector.mutex);
	CUTLINE* pLine=pSide->m_CutLineVector.mget(iLineID);
	if(pLine)
	{
		CMPointd Wt;
		locker.unlock();
		CMWorkTableDriver* pWorkTableDriver=GET_CARD(
			WORKTABLE_DRIVER,CMWorkTableDriver);
		pWorkTableDriver->CurAxisToWt(m_gSystem.m_iCurChID,Wt,true);

        if(fabs(Wt.tY-pLine->m_BasePt.tY)>0.01){
            QMessageBox::information(this, QObject::tr("Notice"), QObject::tr("Operator Ignored, Offset greater than 0.01."));
            MFresh();
            return;
        }
		
        if(fabs(Wt.tY-pLine->m_BasePt.tY)>0.0009)
        {
			if(QMessageBox::Yes != QMessageBox::question(this, QObject::tr("Confirm"), 
				QObject::tr("Are you sure modify line %1 from %2 to %3")
                .arg(pLine->m_index+1).arg(pLine->m_BasePt.tY).arg(Wt.tY)))
			{
				return;
			}
			pLine->m_BasePt.tY = Wt.tY;
			pLine->m_WPPair.ptPostive.tY = Wt.tY;
			pLine->m_WPPair.ptNegative.tY = Wt.tY;

			FreshLines(true);
		}
	}
    
}

void CMWManualCut::on_btnAngleSet_clicked()
{
    CProductSide* pSide=GET_CHDIRECT(m_iCurSideID,CProductSide);
    Q_ASSERT(pSide);

	if(m_gSystem.IsSMIdle(SM_MAIN)){
		CMotorDriver* pDriver=GET_CARD(MOTOR_DRIVER,CMotorDriver);
		pSide->m_dLevelAngle=pDriver->get_posdata(MOTORW,true);
	}else{
		m_gSystem.m_SysMsg.SetMsg
			(QObject::trUtf8("Pause action before test move"));
	}
}

bool CMWManualCut::RelocationLine(int iLineID, double dOffsetY)
{
    if(iLineID<0)return false;

    Q_ASSERT(!(m_iCurSideID!=SIDE_A&&m_iCurSideID!=SIDE_B));

    CProductSide* pSide=GET_CHDIRECT(m_iCurSideID,CProductSide);
    Q_ASSERT(pSide);

    QMutexLocker locker(&pSide->m_CutLineVector.mutex);
    CUTLINE* pLine=pSide->m_CutLineVector.mget(iLineID);
    if(pLine)
    {
        CMPointd Wt;
        locker.unlock();
        CMWorkTableDriver* pWorkTableDriver=GET_CARD(
            WORKTABLE_DRIVER,CMWorkTableDriver);
        pWorkTableDriver->CurAxisToWt(m_gSystem.m_iCurChID,Wt,true);

        double dYPos = pLine->m_BasePt.tY + dOffsetY;
        if(fabs(dOffsetY)>0.01){
            QMessageBox::information(this, QObject::tr("Notice"), QObject::tr("Operator Ignored, Offset greater than 10um."));
            MFresh();
            return false;
        }else{
			QString info = QString("Manual Relocation Line:%1 Offset:%2 From:%3 To %4").arg(iLineID+1).arg(dOffsetY).arg(pLine->m_BasePt.tY).arg(dYPos);
			m_gSystem.AddProductInfo(PROCESS_CUT, info, true);
		}

        pLine->m_BasePt.tY = dYPos;
        pLine->m_WPPair.ptPostive.tY = dYPos;
        pLine->m_WPPair.ptNegative.tY = dYPos;

        return true;
    }

    return false;
}

bool CMWManualCut::CalcOffset(int iLineID, double& dOffsetY)
{
    dOffsetY = 0;
    if(iLineID<0)return false;

    Q_ASSERT(!(m_iCurSideID!=SIDE_A&&m_iCurSideID!=SIDE_B));
    CProductSide* pSide=GET_CHDIRECT(m_iCurSideID,CProductSide);
    Q_ASSERT(pSide);
    QMutexLocker locker(&pSide->m_CutLineVector.mutex);
    CUTLINE* pLine=pSide->m_CutLineVector.mget(iLineID);
    if(pLine)
    {
        CMPointd Wt;
        locker.unlock();
        CMWorkTableDriver* pWorkTableDriver=GET_CARD(WORKTABLE_DRIVER,CMWorkTableDriver);
        pWorkTableDriver->CurAxisToWt(m_gSystem.m_iCurChID, Wt,true);

        dOffsetY = Wt.tY-pLine->m_BasePt.tY;
        return true;
    }

    return false;
}

void CMWManualCut::on_btnLocationCurLineAndAfter_clicked()
{
    double dOffsetY=0;
    int iLine = m_iLineSelected;
    if(true == CalcOffset(iLine, dOffsetY))
    {
        if(fabs(dOffsetY)>0.01)
        {
            QMessageBox::information(this, QObject::tr("Notice"), QObject::tr("Operator Ignored, Offset greater than 10um."));
            MFresh();
            return;
        }
        if(fabs(dOffsetY) < 0.0008)
        {
            QMessageBox::information(this, QObject::tr("Notice"), QObject::tr("Operator Ignored, Offset lesser than 1um."));
            MFresh();
            return;
        }

        bool b=false;
        int iLineRange = ui->txtLocationAfterIndex->text().toInt(&b);
        if(false == b){
            QMessageBox::information(this, QObject::tr("Notice"), QObject::tr("Operator Ignored, Location Count Error. %1")
                                     .arg(ui->txtLocationAfterIndex->text()));
            MFresh();
            return;
        }

        if(QMessageBox::Yes != QMessageBox::question(this, QObject::tr("Confirm"),
            QObject::tr("Are you sure modify line %1 ~ %2 Offset %3")
            .arg(iLine+1).arg(iLine+iLineRange).arg(dOffsetY)))
        {
            return;
        }

        for(int i=iLine;i<iLine+iLineRange;i++)
        {
            RelocationLine(i, dOffsetY);
        }

        FreshLines(true);
    }
}

void CMWManualCut::on_btnKerfCut_clicked()
{
    V_MsgQueue msgqueue;
	/*msgqueue.pushback_Msg(VarMsg_Process_ID,QObject::trUtf8("Cut Kerf"),
	QVariantList()
	<<PROCESS_CUT<<CProcess_Cut::CUT_KERF
	<<m_gSystem.m_iCurSideID<<m_iLineSelected<<0);*/

	/*msgqueue.pushback_Msg(VarMsg_Process_ID,
		QObject::trUtf8("Calcu pt by Line Sig"),
		QVariantList()
		<<PROCESS_LASERKERF
		<<CProcess_LaserKerf::CUTKERFLINE
		<<m_gSystem.m_iCurSideID<<m_iLineSelected<<0 ,0);*/

	msgqueue.pushback_Msg(VarMsg_Process_ID,
		QObject::trUtf8("Move Kerf P"),
		QVariantList()
		<<PROCESS_LASERKERF
		<<CProcess_LaserKerf::MOVEKERFPOS,0);

	msgqueue.pushback_Msg(VarMsg_Process_ID,
		QObject::trUtf8("Laser Cali"),
		QVariantList()
		<<PROCESS_LASERKERF
		<<CProcess_LaserKerf::KERF
		<<m_gSystem.m_iCurSideID<<0,0);
    m_gSystem.start_manual(SM_MAIN, msgqueue,true);
}

void CMWManualCut::on_btnToKerf_clicked()
{
    V_MsgQueue msgqueue;
    msgqueue.pushback_Msg(VarMsg_Process_ID,
        QObject::trUtf8("Move Kerf P"),
        QVariantList()
        <<PROCESS_LASERKERF
        <<CProcess_LaserKerf::MOVEKERFPOS,0);

    m_gSystem.start_manual(SM_MAIN, msgqueue,true);
}

void CMWManualCut::on_btnIdx_clicked(bool checked)
{
    if(true == checked){
        CProductSide* pSide=GET_CHDIRECT(m_gSystem.m_iCurSideID,CProductSide);
        if(!pSide){
            ui->txtStep->setText("0");
            return;
        }
        double dStep=pSide->m_Variants.get_VData(Var_ProductSide_SideStep)
                ->toDouble();
        ui->txtStep->setText(QString::number(dStep*1000, 'f', 2));
    }else{
        ui->txtStep->setText("0");
    }
}

void CMWManualCut::on_btnRotateCh1_clicked()
{
    CMPointd axis;
    CMWorkTableDriver* pWorkTableDriver = GET_CARD(WORKTABLE_DRIVER, CMWorkTableDriver);
    CMPointd wt(-m_Wt1.tY, m_Wt1.tX);

    if (m_gSystem.m_iCurChID == SIDE_A)
    {
        QMessageBox::information(this, QObject::tr("Notice"), QObject::tr("Same side."));
        return;
    }
    pWorkTableDriver->WtToAxis(m_gSystem.m_iCurChID, wt, axis);
    V_MsgQueue msgqueue;
    m_gSystem.changeSide_msg(SIDE_A, true, msgqueue);

    m_gSystem.absmove_xy_msg(axis.tX, axis.tY, msgqueue);
    m_gSystem.start_test(SM_MAIN, msgqueue, true);
}

void CMWManualCut::on_btnRotateCh2_clicked()
{
    CMPointd axis;
    CMWorkTableDriver* pWorkTableDriver = GET_CARD(WORKTABLE_DRIVER, CMWorkTableDriver);
    CMPointd wt(m_Wt1.tY, -m_Wt1.tX);
    if (m_gSystem.m_iCurChID == SIDE_B)
    {
        QMessageBox::information(this, QObject::tr("Notice"), QObject::tr("Same side."));
        return;
    }
    pWorkTableDriver->WtToAxis(m_gSystem.m_iCurChID, wt, axis);
    V_MsgQueue msgqueue;
    m_gSystem.changeSide_msg(SIDE_B, true, msgqueue);
    m_gSystem.absmove_xy_msg(axis.tX, axis.tY, msgqueue);
    m_gSystem.start_test(SM_MAIN, msgqueue, true);
}
