#include "vst_semi_transfer.h"
#include "logic.h"
#include "vsm_thread.h"
#include "vst_work_transfer.h"
VST_Semi_Transfer::VST_Semi_Transfer(int iID, const QString& sName,
                                     VSM_Thread* pParent)
    :VST_Semi(iID, sName, pParent)
{
    m_iCurOperator = -1;
}

void VST_Semi_Transfer::do_Msg(const V_Msg& msg)
{
    switch (msg.m_iID)
    {
        case VarMsg_StartSemi_ID:
        {
            Q_ASSERT(msg.m_vlInput.size() >= 1);
            m_iCurOperator = msg.m_vlInput[0].toInt();
            if (msg.m_vlInput[0].toInt() == VarMsg_Transfer_UnLoadAll)
            {
                pushfront_Msg(VarMsg_Transfer_UnLoadAll, msg.m_sName);
            }
            else if (msg.m_vlInput[0].toInt() == VarMsg_Transfer_Component)
            {
                V_Msg msg1 = msg;
                msg1.m_vlInput.pop_front();
                m_iCurOperator = msg1.m_vlInput[0].toInt();
                pushfront_Msg(VarMsg_Transfer_Component, msg1.m_sName, msg1.m_vlInput);
            }
            else
            {
                if (!m_pNextState)
                {
                    m_pNextState = new VST_Work_Transfer(VarState_Semi_Transfer,
                                                         QObject::trUtf8("Single Transfer"),
                                                         m_pParent, this, 0);
                    ((VST_Work_Transfer*)m_pNextState)->m_VarMsgProcess.
                        pushback_Msg(VarMsg_Transfer_Step, msg.m_sName,
                                     QVariantList() << msg.m_vlInput[0] << false);

                    ((VST_Work_Transfer*)m_pNextState)->LoadMsgProcess();
                }
                pushback_Msg(VarMsg_Transfer_Finish, msg.m_sName);
                m_pParent->SetState(m_pNextState);
            }
            break;
        }
        case VarMsg_Transfer_Finish:
        {
#ifdef __SIMULATOR__
            MSleep(2000);
#endif // __SIMULATOR__
            m_pParent->pushfront_Msg(VarMsg_StopSemi_ID, QObject::trUtf8("Stop Semi Transfer Sig"));
            QString str = QObject::trUtf8("%1 Finished").arg(msg.m_sName);
            m_gSystem.m_SysMsg.SetMsg(str);
            m_iCurOperator = -1;
            break;
        }
        case VarMsg_Transfer_UnLoadAll:
        {
            //一键下料
            CProcess_Trans* pTrans = GET_PROCESS(PROCESS_TRANS,
                                                 SM_TRANS, CProcess_Trans);
            if (pTrans->IsAllUnLoad())
            {
                m_pParent->pushfront_Msg(VarMsg_StopSemi_ID, QObject::trUtf8("Stop Semi Transfer Sig"));
                m_gSystem.m_SysMsg.SetMsg(QObject::trUtf8("All unload finished"));
                m_iCurOperator = -1;
                return;
            }
            

            //Transfer 往近轨道放,否则报警人来处理
            if (pTrans->m_pSlotTrans)
            {
                if (pTrans->m_pSlotRailNear)
                {
                    MQT_THROW_CODESTR(ALARM_MAIN_SAFE_PROTECT, QObject::trUtf8("Transfer and rail Near has wafer, please remove rail near wafer and Abort angain"));
                }
            }

            if (pTrans->m_pSlotGrab)
            {
                MQT_THROW_CODESTR(ALARM_MAIN_SAFE_PROTECT, QObject::trUtf8("Please remove rail near Wafer and Reset Grab Status and Abort again"));
            }

            //如果上面有水,不能执行下料操作
            pTrans->AssertCoatWaferHasWater(QObject::trUtf8("All unload"));
            pTrans->AssertCleanWaferHasWater(QObject::trUtf8("All unload"));

            if (pTrans->m_pSlotTrans)
            {
                AddAbortWaferMsg(pTrans->m_pSlotTrans, CProcess_Trans::kAbortTrans);
            }            
            else if (pTrans->m_pSlotRailNear)
            {
				if (pTrans->m_pSlotCheckBox) {
					if (pTrans->m_pSlotCheckBox->index == -1)
					{
						CMotorDriver* pDriver = GET_CARD(MOTOR_DRIVER, CMotorDriver);
						if (!pDriver->get_iodata(IO_INPUT, IN_CHECKBOX_HAS_WAFER_LEFT, true))
						{
							pTrans->m_pSlotCheckBox = 0;
						}
					}
				}

				if (pTrans->m_pSlotRailNear->index == -1 && pTrans->m_pSlotCheckBox)
				{
					m_pParent->pushfront_Msg(VarMsg_StopSemi_ID, QObject::trUtf8("Stop Semi Transfer Sig"));
					m_gSystem.m_SysMsg.SetMsg(QObject::trUtf8("Please Remove cupboard wafer and try again"));
				}
                else
                {
                    AddAbortWaferMsg(pTrans->m_pSlotRailNear, CProcess_Trans::kTransRailNearToCass);
                }
            }
            else if (pTrans->m_pSlotRailFar)
            {
                AddAbortWaferMsg(pTrans->m_pSlotRailFar, CProcess_Trans::kTransRailFarToRailNear);
            }
            else if (pTrans->m_pSlotCoat)
            {
                AddAbortWaferMsg(pTrans->m_pSlotCoat, CProcess_Trans::kTransCoatToRailFar);
            }
            else if (pTrans->m_pSlotClean)
            {
                AddAbortWaferMsg(pTrans->m_pSlotClean, CProcess_Trans::kTransCleanToRailNear);
            }
            else if (pTrans->m_pSlotLoad)
            {
                AddAbortWaferMsg(pTrans->m_pSlotLoad, CProcess_Trans::kAbortLoad);
            }
            else if (pTrans->m_pSlotUnLoad)
            {
                AddAbortWaferMsg(pTrans->m_pSlotUnLoad, CProcess_Trans::kAbortUnload);
            }
            else if (pTrans->m_pSlotWT)
            {
                AddAbortWaferMsg(pTrans->m_pSlotClean, CProcess_Trans::kTransWorktableToRailNear);
            }
            else if (pTrans->m_pSlotCheckBox)
            {
                if (pTrans->m_pSlotCheckBox->index != -1)
                {
                    AddAbortWaferMsg(pTrans->m_pSlotCheckBox, CProcess_Trans::kTransCheckBoxToRailNear);
                }
                else
                {
                    CMotorDriver* pDriver = GET_CARD(MOTOR_DRIVER, CMotorDriver);
                    if (!pDriver->get_iodata(IO_INPUT, IN_CHECKBOX_HAS_WAFER_LEFT, true))
                    {
                        pTrans->m_pSlotCheckBox = 0;
                    }

                    if (pTrans->IsAllUnLoad())
                    {
                        m_pParent->pushfront_Msg(VarMsg_StopSemi_ID, QObject::trUtf8("Stop Semi Transfer Sig"));
                        m_gSystem.m_SysMsg.SetMsg(QObject::trUtf8("All unload finished, please remove Checkbox wafer and reset checkbox status"));
                    }
                    
                }
            }
            

            pushback_Msg(msg);
            break;
        }
        case VarMsg_Transfer_Sequence:
        {
            if (!m_pNextState)
            {
                m_pNextState = new VST_Work_Transfer(VarState_Semi_Transfer,
                                                     QObject::trUtf8("Single Transfer"),
                                                     m_pParent, this, 0);
                ((VST_Work_Transfer*)m_pNextState)->m_VarMsgProcess.
                    pushback_Msg(VarMsg_Transfer_Step, msg.m_sName,
                                 QVariantList() << msg.m_vlInput[0] << false);

                ((VST_Work_Transfer*)m_pNextState)->LoadMsgProcess();
            }
            m_pParent->SetState(m_pNextState);

            break;
        }
        case VarMsg_Transfer_Component:
        {
            if (msg.m_vlInput[0].toInt() == CProcess_Trans::kTransCheckboxToCoat)
            {
                
                {
                    CProcess_Trans* pTrans = GET_PROCESS(PROCESS_TRANS, SM_TRANS, CProcess_Trans);

                    QMutexLocker l(&pTrans->m_slotMutex);
                    CASSSLOT* pSlotCass = pTrans->CreateOrBindToCheckbox();
                    pSlotCass->WPstatus = WPUNCUT;
                    pSlotCass->index = -1;
                    pTrans->m_pSlotCheckBox = pSlotCass;
                }//release lock


                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransCheckBoxToRailNear);

                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransRailNearToCoat);
            }
            else if (msg.m_vlInput[0].toInt() == CProcess_Trans::kTransCheckboxToClean)
            {
                {
                    CProcess_Trans* pTrans = GET_PROCESS(PROCESS_TRANS, SM_TRANS, CProcess_Trans);
                    QMutexLocker l(&pTrans->m_slotMutex);
                    CASSSLOT* pSlotCass = pTrans->CreateOrBindToCheckbox();
                    pSlotCass->WPstatus = WPUNCUT;
                    pSlotCass->index = -1;
                    pTrans->m_pSlotCheckBox = pSlotCass;
                }//release lock


                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransCheckBoxToRailNear);

                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransRailNearToClean);
            }
            else if (msg.m_vlInput[0].toInt() == CProcess_Trans::kTransCoatToWt)
            {
                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransCoatToRailFar);

                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransRailFarToWorktable);
            }
            else if (msg.m_vlInput[0].toInt() == CProcess_Trans::kTransWtToClean)
            {
                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransWorktableToRailNear);

                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransRailNearToClean);
            }
            else if (msg.m_vlInput[0].toInt() == CProcess_Trans::kTransCleanToCass)
            {
                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransCleanToRailNear);

                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransRailNearToClean);
            }
            else if (msg.m_vlInput[0].toInt() == CProcess_Trans::kTransCleanToCheckbox)
            {
                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransCleanToRailNear);

                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransRailNearToCheckBox);
            }
            else if (msg.m_vlInput[0].toInt() == CProcess_Trans::kTransCoatToCheckbox)
            {
                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransCoatToRailFar);

                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransRailFarToRailNear);

                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransRailNearToCheckBox);
            } 
            else if (msg.m_vlInput[0].toInt() == CProcess_Trans::kTransCheckboxToWt)
            {
				
				{
					CProcess_Trans* pTrans = GET_PROCESS(PROCESS_TRANS, SM_TRANS, CProcess_Trans);
 					QMutexLocker l(&pTrans->m_slotMutex);
                	CASSSLOT* pSlotCass = pTrans->CreateOrBindToCheckbox();
					pSlotCass->WPstatus = WPUNCUT;
					pSlotCass->index = -1;
					pTrans->m_pSlotCheckBox = pSlotCass;
				}//release lock
                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransCheckBoxToRailNear);
                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransRailNearToWorktable);
            }
            else if (msg.m_vlInput[0].toInt() == CProcess_Trans::kTransWtToCheckbox)
            {
                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransWorktableToRailNear);
                pushback_Msg(VarMsg_Transfer_Sequence, "", QVariantList() << CProcess_Trans::kTransRailNearToCheckBox);
            }

            pushback_Msg(VarMsg_Transfer_Finish, msg.m_sName);
            break;
        }
        case VarMsg_Abort_Finish:
        {
            CASSSLOT* pSlot = (CASSSLOT*)msg.m_vlInput[0].toULongLong();
            if (pSlot)
            {
                pSlot->WPstatus = WPABORT;
            }
            break;
        }
    }
    VST_Semi::do_Msg(msg);
}

void VST_Semi_Transfer::AddUnLoadWaferMsg(CASSSLOT* pSlot)
{
    if (!m_pNextState)
    {
        m_pNextState = new VST_Work_Transfer(VarState_Semi_Transfer,
                                             QObject::trUtf8("Single UnLoad"),
                                             m_pParent, this, 0);
        for (int i = 0; i < 500; i++)
        {
            ((VST_Work_Transfer*)m_pNextState)->m_VarMsgProcess.
                pushback_Msg(VarMsg_Process_ID,
                             QObject::trUtf8("Single UnLoad Sig"),
                             QVariantList() << PROCESS_TRANS <<
                             CProcess_Trans::ABORTWAFER <<
                             (uint64_t)pSlot << i);
        }

        ((VST_Work_Transfer*)m_pNextState)->LoadMsgProcess();
    }
    m_pParent->SetState(m_pNextState);
}

void VST_Semi_Transfer::AddAbortWaferMsg(CASSSLOT* pSlot, int iMsgId)
{
    if (!m_pNextState)
    {
        m_pNextState = new VST_Work_Transfer(VarState_Semi_Transfer,
                                             QObject::trUtf8("Single Transfer"),
                                             m_pParent, this, 0);

        ((VST_Work_Transfer*)m_pNextState)->m_VarMsgProcess.
            pushback_Msg(VarMsg_Transfer_Step, "",
                         QVariantList() << iMsgId << false);

        ((VST_Work_Transfer*)m_pNextState)->LoadMsgProcess();
    }
    pushback_Msg(VarMsg_Abort_Finish, "Abort Wafer", QVariantList() << (uint64_t)pSlot);
    m_pParent->SetState(m_pNextState);
}
