#include "vst_wait_transfer.h"
#include "vst_work_transfer.h"
#include "cprocess_trans.h"
#include "vsm_thread.h"
#include "vsmt_base.h"
#include "logic.h"
VST_Wait_Transfer::VST_Wait_Transfer(int iID, const QString &sName,
                                     VSM_Thread *pParent)
    :VST_Wait_Base(  iID,  sName, pParent)
{

}

void VST_Wait_Transfer::do_Msg(const V_Msg &msg)
{
    if(IsQueueEmpty())
    {
		
		//自动为空的时候，启动添加VarMsg_Transfer_CheckState消息
        pushback_Msg(VarMsg_Transfer_CheckState,
                     QObject::trUtf8("Check Transfer State"));
		MSleep(10);
    }
    switch(msg.m_iID)
    {
        case VarMsg_StartAuto_ID:
        {
			m_gSystem.m_totalWorkTime.StartTime();
			m_gSystem.m_fullAutoTime.ClearTime();
			m_gSystem.m_fullAutoTime.StartTime();
			if(m_gSystem.IsSimulator()){
				m_gSystem.SetLotId(QString("SIMULATOR")+QDateTime::currentDateTime().toString("MMddhhmm"));
			}
			m_gSystem.WriteRecoverData();

			//g_SecsManager.SendEvent(EVENT_JobStarted);
			//扫描料盒，添加200个单步操作，并调用VST_Work_Transfer的，再调用
			//TODO:料盒里面没有内容的时候才需要扫描料盒
            AddMsgToState(CProcess_Trans::TRANSSCANCASS,QObject::trUtf8("Scan Cass"));
            break;
        }
#if 0
        case VarMsg_Transfer_CheckState:
        {
            CCassette* pCass=GET_CHDIRECT(CASSETTE,CCassette);
            bool bIsCutFinished= pCass->IsCassCutFinished();
            if(bIsCutFinished)
            {
                CMWorkTableDriver* pWorkTableDriver=GET_CARD(WORKTABLE_DRIVER,
                                                             CMWorkTableDriver);

                pWorkTableDriver->ManualLoadPos(WORKTABLE);

				CProcess_Trans* processTrans =GET_PROCESS(PROCESS_TRANS,SM_TRANS,CProcess_Trans);
				processTrans->MoveHGrabWait();

				CProcess_Scan* pCass=GET_PROCESS(PROCESS_SCAN,SM_TRANS,
					CProcess_Scan);
				pCass->CassUp(CASSETTE);

                m_gSystem.EvtLog(QString::fromUtf8("FAE"),
                                 QObject::trUtf8("Cassette Cut Finished"));
				//结束计时
				m_gSystem.m_totalWorkTime.StopTime();
				m_gSystem.m_fullAutoTime.StopTime();
				m_gSystem.m_totalWorkHour += m_gSystem.m_totalWorkTime.GetTime()/3600; 
				m_gSystem.m_totalWorkTime.ClearTime();
				
				int maxCycleCount = m_gSystem.m_Variants.get_VData(Var_MaxCycle_Count)->toInt();
                if(m_gSystem.m_bEnableCycle 
					&& (maxCycleCount<=0 || (maxCycleCount>0 && m_gSystem.m_iTotalCuttedWafer<maxCycleCount)))
                {
                    clear_Msg();
                    pushback_Msg(VarMsg_StartAuto_ID,
                                 QObject::trUtf8("Restart auto cycle"));
                }
                else
                {
					g_SecsManager.SendEvent(EVENT_JobComplete);
                    m_gSystem.publish_msg(V_Msg(VarMsg_Stop_ID,
                                                QObject::trUtf8("Cut Finished,Stop All")));
                    m_gSystem.m_SysMsg.SetMsg(QObject::trUtf8("Cassette Cut Finished"));
                }
                return;
            }

			//TODO:提前终止
            CProcess_Trans* pTrans=GET_PROCESS(PROCESS_TRANS,
                                               SM_TRANS,CProcess_Trans);
            Q_ASSERT(pTrans);

			//TODO：同时竞争往料盒放的时候，就发生问题，需要处理
			//优先把Cupboard里面的处理了，就没有竞争的情况了
			//从后往前
			if(pTrans->m_pSlotCheckBox&&pTrans->m_pSlotCheckBox->CheckStatus==CHECKCUTING)
			{
				//暂停等待检查
				m_gSystem.FindSM(SM_TRANS)->pushfront_Msg(VarMsg_Pause_ID, QObject::trUtf8("Pause for check wafer cutting."));
				m_gSystem.m_SysMsg.SetMsg( QObject::trUtf8("Please check cuting quality on the cupboard."));
				
				g_SecsManager.SendEvent(EVENT_JobPaused);
				g_SecsManager.SendEvent(EVENT_CutingCheckStarted);
			}else if(pTrans->m_pSlotCheckBox&&pTrans->m_pSlotCheckBox->CheckStatus==CHECKCUTFINISHED){
				//CheckBox有晶圆，并且检查完毕
				AddMsgToState(CProcess_Trans::TRANSCHECKBOXTOCASS, QObject::trUtf8("Cupboard to Cass"));

				//添加一个消息，表示首片检查完毕
			}
			else if(pTrans->m_pSlotCheckBox && pTrans->m_pSlotCheckBox->CheckStatus==CHECKCOATING)
			{
				//通知暂停
				m_gSystem.FindSM(SM_TRANS)->pushfront_Msg(VarMsg_Pause_ID, QObject::trUtf8("Pause for check wafer coating."));
				m_gSystem.m_SysMsg.SetMsg( QObject::trUtf8("Please check coating quality on the cupboard."));

				g_SecsManager.SendEvent(EVENT_JobPaused);
				g_SecsManager.SendEvent(EVENT_CoatingCheckStarted);

			}else if(pTrans->m_pSlotCheckBox && pTrans->m_pSlotCheckBox->CheckStatus==CHECKCOATFINISHED){
				//Checkbox转移到涂覆台
				AddMsgToState(CProcess_Trans::TRANSCHECKBOXTOCOAT,QObject::trUtf8("Cupboard to CoatTable"));
				//TODO:如果这里需要重新涂覆，则需要添加一个涂覆的消息
			}
			else if(pTrans->m_pSlotCoat&&pTrans->m_pSlotCoat->WPstatus==WPCOATFINISH
				&&!pTrans->m_pSlotWT)
			{
				//如果检查完成，则转移到平台并切割
				if(pTrans->m_pSlotCoat->bNeedCheckCoat)
				{
					//已经检查过了
					if(pTrans->m_pSlotCoat->CheckStatus>=CHECKCOATFINISHED){
						//转移到平台
						AddMsgToState(CProcess_Trans::TRANSCOATTOWT,
							QObject::trUtf8("CleanTable to WorkTable"));

						//开始切割
						QString strStart=QObject::trUtf8("Auto Cut Start");
						pushfront_Msg(VarMsg_Auto_StartCut,strStart);
					}else if(!pTrans->m_pSlotCheckBox){
						//转移到检查料盒
						AddMsgToState(CProcess_Trans::TRANSCOATTOCHECKBOX,
							QObject::trUtf8("CleanTable to WorkTable"));
					}
					else
					{
						//等待检测料盒更新
						m_gSystem.FindSM(SM_TRANS)->pushfront_Msg(VarMsg_Pause_ID, QObject::trUtf8("Pause for check wafer coating."));
						m_gSystem.m_SysMsg.SetMsg( QObject::trUtf8("Please check coating quality on the cupboard."));
						g_SecsManager.SendEvent(EVENT_JobPaused);
						g_SecsManager.SendEvent(EVENT_CoatingCheckStarted);
					}
				}
				else
				{
					//不需要检查，直接放到涂敷台
					//转移到平台
					AddMsgToState(CProcess_Trans::TRANSCOATTOWT,
						QObject::trUtf8("CleanTable to WorkTable"));

					//开始切割
					QString strStart=QObject::trUtf8("Auto Cut Start");
					pushfront_Msg(VarMsg_Auto_StartCut,strStart);
				}
			}
			else if(pTrans->m_pSlotClean&&pTrans->m_pSlotClean->WPstatus==WPCLEANFINISH)
			{
				//清洗台有晶圆，并且清洗完成,如果需要切割检查，转移到料盒或CheckBox
				//HACK:这里会与涂覆竞争，如果涂覆正在检查，没办法放到检查料盒中
				CProcess_Scan* pScan=GET_PROCESS(PROCESS_SCAN,SM_TRANS,CProcess_Scan);
				Q_ASSERT(pScan);
				bool bNeedCheckCut = pTrans->m_pSlotClean->bNeedCheckCut;
				if(bNeedCheckCut)
				{
					//如果检查料盒为空时，则可以转移到检查料盒
					if(!pTrans->m_pSlotCheckBox){
						AddMsgToState(CProcess_Trans::TRANSCLEANTOCHECKBOX,
							QObject::trUtf8("CleanTable to Cupboard"));
					}else if(pTrans->m_pSlotCheckBox&&pTrans->m_pSlotCheckBox->CheckStatus==CHECKCOATFINISHED){
						//Checkbox转移到涂覆台
						AddMsgToState(CProcess_Trans::TRANSCHECKBOXTOCOAT,QObject::trUtf8("Cupboard to CoatTable"));
					}else if(pTrans->m_pSlotCheckBox&&pTrans->m_pSlotCheckBox->CheckStatus == CHECKCOATING){
						m_gSystem.FindSM(SM_TRANS)->pushfront_Msg(VarMsg_Pause_ID, QObject::trUtf8("Pause for check wafer coating."));
						m_gSystem.m_SysMsg.SetMsg( QObject::trUtf8("Please check coating quality on the cupboard."));
					}
				}
				else
				{
					AddMsgToState(CProcess_Trans::TRANSCLEANTOCASS,
						QObject::trUtf8("CleanTable to Cass"));
				}
			}
			else if(pTrans->m_pSlotWT&&pTrans->m_pSlotWT->WPstatus==WPCUTFINISH
				&&!pTrans->m_pSlotClean)
			{
				//平台有晶圆，并且切割完成，并且没有未清洗的晶圆
				AddMsgToState(CProcess_Trans::TRANSWTTOCLEAN,
					QObject::trUtf8("WT to CleanTable"));

				QString strStart=QObject::trUtf8("Auto Clean Start");
				pushfront_Msg(VarMsg_Auto_StartClean,strStart);
			}else if(!pTrans->m_pSlotCoat&&pCass->GetFirstUnCutWafer()){
				CASSSLOT* pSlot= pCass->GetFirstUnCutWafer();
				//如果是首片，直接走
				if(pCass->IsSlotFirstInCass(pSlot)){
					//设置首片检查

					AddMsgToState(CProcess_Trans::TRANSCASSTOCOAT,
						QObject::trUtf8("Cass to CoatTable"));

					QString strStart=QObject::trUtf8("Auto Coat Start");
					pushfront_Msg(VarMsg_Auto_StartCoat,strStart);
				}else{
					if(pCass->IsFirstCheckFinished()){
						//首片检测完毕
						Q_ASSERT(!pTrans->m_pSlotCheckBox);
						AddMsgToState(CProcess_Trans::TRANSCASSTOCOAT,
							QObject::trUtf8("Cass to CoatTable"));

						QString strStart=QObject::trUtf8("Auto Coat Start");
						pushfront_Msg(VarMsg_Auto_StartCoat,strStart);
					}else{
						//首片检测没完成，就等待
						//TODO:
						//m_gSystem.FindSM(SM_TRANS)->pushfront_Msg(VarMsg_Pause_ID, QObject::trUtf8("Pause for check wafer."));
					}
				}
			}
			else{

			}

			//直接跳出去
			break;
#if 0
			//涂敷台没有晶圆并且有未切割的晶圆
			//首片检测已经做完
            if(!pTrans->m_pSlotCoat&&pCass->GetFirstUnCutWafer())
            {
				//转移到涂敷台
                    AddMsgToState(CProcess_Trans::TRANSCASSTOCOAT,
                                  QObject::trUtf8("Cass to CoatTable"));

                    QString strStart=QObject::trUtf8("Auto Coat Start");
                    pushfront_Msg(VarMsg_Auto_StartCoat,strStart);

					CASSSLOT* pSlot= pCass->GetFirstUnCutWafer();
					pSlot->BeginDate = QDateTime::currentDateTime();
					int iSlotID = pSlot->index+1;

					QString str=QObject::trUtf8("DNo:%1,DID:%2,TM:%3")
						.arg(m_gSystem.GetCurFile())
						.arg(iSlotID)
                        .arg(pSlot->BeginDate.toString("hh:mm:ss"));
					m_gSystem.EvtLog(QString::fromUtf8("JOB_START"),str);
            }
            else if(pTrans->m_pSlotCheckBox&&pTrans->m_pSlotCheckBox->WPstatus==WPCHECKING)
            {
				//暂停等待检查
                m_gSystem.publish_msg(V_Msg(VarMsg_Pause_ID,
                                            QObject::trUtf8("Pause for check wafer.")));
            }
            else if(pTrans->m_pSlotCheckBox&&pTrans->m_pSlotCheckBox->WPstatus==WPCHECKED)
            {
				//CheckBox有晶圆，并且检查完毕
                AddMsgToState(CProcess_Trans::TRANSCHECKBOXTOCASS,
                              QObject::trUtf8("Cupboard to Cass"));
            }
            else if(pTrans->m_pSlotClean&&pTrans->m_pSlotClean->WPstatus==WPCLEANFINISH)
            {
				//清洗台有晶圆，并且清洗完成，转移到料盒或CheckBox
                CProcess_Scan* pScan=GET_PROCESS(PROCESS_SCAN,SM_TRANS,CProcess_Scan);
                Q_ASSERT(pScan);
                bool bEnableCheckWafer=pScan->m_Variants.get_VData(Var_CheckBox_EnableCheck)
                        ->toBool();
                bool bIsFirstSlot=pCass->IsSlotFirstInCass(pTrans->m_pSlotClean);
                if(bIsFirstSlot&&bEnableCheckWafer)
                {
                    AddMsgToState(CProcess_Trans::TRANSCLEANTOCHECKBOX,
                                  QObject::trUtf8("CleanTable to Cupboard"));
                }
                else
                {
                    AddMsgToState(CProcess_Trans::TRANSCLEANTOCASS,
                                  QObject::trUtf8("CleanTable to Cass"));
                }
            }
            else if(pTrans->m_pSlotWT&&pTrans->m_pSlotWT->WPstatus==WPCUTFINISH
                    &&!pTrans->m_pSlotClean)
            {
				//平台有晶圆，并且切割完成，并且没有未清洗的晶圆
                AddMsgToState(CProcess_Trans::TRANSWTTOCLEAN,
                              QObject::trUtf8("WT to CleanTable"));

                QString strStart=QObject::trUtf8("Auto Clean Start");
                pushfront_Msg(VarMsg_Auto_StartClean,strStart);
            }
            else if(pTrans->m_pSlotCoat&&pTrans->m_pSlotCoat->WPstatus==WPCOATFINISH
                    &&!pTrans->m_pSlotWT)
            {
				//转移到平台
                AddMsgToState(CProcess_Trans::TRANSCOATTOWT,
                              QObject::trUtf8("CleanTable to WorkTable"));

                QString strStart=QObject::trUtf8("Auto Cut Start");
                pushfront_Msg(VarMsg_Auto_StartCut,strStart);
            }
            break;
#endif
        }
#endif
    case VarMsg_Auto_StartCoat://开始涂敷
    {
        //如果没有处于自动状态会异常
        CProcess_Trans* pTrans=GET_PROCESS(PROCESS_TRANS,
                                           SM_TRANS,CProcess_Trans);
        Q_ASSERT(pTrans);
        if(pTrans->m_pSlotCoat)
        {
			
              VSMT_Base* pSMCoat=GET_STATEMACHINE(SM_COAT,VSMT_Base);

              pSMCoat->pushBack_Msg_toState(nullptr,msg);
        }
        break;
    }
    case VarMsg_Auto_StartClean://开始清洗
    {
        CProcess_Trans* pTrans=GET_PROCESS(PROCESS_TRANS,
                                           SM_TRANS,CProcess_Trans);
        Q_ASSERT(pTrans);
        if(pTrans->m_pSlotClean)
        {
			//如果清洗台有晶圆了，则开始清洗
              VSMT_Base* pSMClean=GET_STATEMACHINE(SM_CLEAN,VSMT_Base);

              pSMClean->pushBack_Msg_toState(0,msg);
        }
        break;
    }
    case VarMsg_Auto_StartCut://开始切割
    {
        CProcess_Trans* pTrans=GET_PROCESS(PROCESS_TRANS,
                                           SM_TRANS,CProcess_Trans);
        Q_ASSERT(pTrans);
        if(pTrans->m_pSlotWT)
        {
              VSMT_Base* pSMMain=GET_STATEMACHINE(SM_MAIN,VSMT_Base);

              pSMMain->pushBack_Msg_toState(0,msg);
        }
        break;
    }
    }
    VST_Wait::do_Msg( msg);
}

//将消息委托给VST_Work_Transfer执行，内部调用CProcess_Trans的消息循环
void VST_Wait_Transfer::AddMsgToState(int iTransMsgID, const QString &msgName,
                                      bool bfront/*=false*/)
{

    if(!m_pNextState)
    {
        m_pNextState= new VST_Work_Transfer(VarState_Work_Transfer,
                                            QObject::trUtf8("Auto Transfer"),
                                            m_pParent,this,0);
        if(bfront)
        {
            ((VST_Work_Transfer*)m_pNextState)->m_VarMsgProcess.
                    pushfront_Msg(VarMsg_Transfer_Step,msgName,
                                  QVariantList()<< iTransMsgID << true);
        }
        else
        {
            ((VST_Work_Transfer*)m_pNextState)->m_VarMsgProcess.
                    pushback_Msg(VarMsg_Transfer_Step,msgName,
                                 QVariantList()<< iTransMsgID << true);
        }
        ((VST_Work_Transfer*)m_pNextState)->LoadMsgProcess();
    }
    m_pParent->SetState(m_pNextState);

}
