#include "vsmt_main.h"
#include "logic.h"
#include "vst_idle_main.h"
#include "vst_work_main.h"
#include "vst_wait_main.h"
#include "vst_semi_main.h"
#include "cprocess_level_ex.h"
#include "cprocess_trans.h"
#include "cprocess_clean.h"
#include "cprocess_level.h"
#include "cprocess_coat.h"
#include "cprocess_cut.h"
#include "cprocess_locate.h"
#include "cprocess_kerf.h"
#include "cprocess_halfcutkerf.h"
#include "cprocess_laserkerf.h"
#include "cprocess_laserfoucscali.h"
#include "cprocess_laserpowercali.h"
#include "cprocess_laserpowercali_pi.h"
#include "cprocess_level.h"
#include "cmotordriver_base.h"
#include "claserdriver_base.h"
VSMT_Main::VSMT_Main(int iID, const QString &sName)
    :VSMT_Base(iID, sName)
{
    mprocesss[PROCESS_LOCATE] =
        new CProcess_Locate(m_gSystem.m_mapNameList[PROCESS_LOCATE],
                            PROCESS_LOCATE);

    mprocesss[PROCESS_LEVELING] =
        new CProcess_Level(m_gSystem.m_mapNameList[PROCESS_LEVELING],
                              PROCESS_LEVELING);

    mprocesss[PROCESS_CUT] =
        new CProcess_Cut(m_gSystem.m_mapNameList[PROCESS_CUT],
                         PROCESS_CUT);

    mprocesss[PROCESS_KERFCHECK] =
        new CProcess_Kerf(m_gSystem.m_mapNameList[PROCESS_KERFCHECK],
                          PROCESS_KERFCHECK);

    CMProcess* pProcess = new CProcess_HalfCutKerf(m_gSystem.m_mapNameList[PROCESS_HALFKERF],
                                                   PROCESS_HALFKERF);
    mprocesss[PROCESS_HALFKERF] = pProcess;
    //pProcess->init_Process();


    pProcess = new CProcess_LaserKerf(m_gSystem.m_mapNameList[PROCESS_LASERKERF],
                                      PROCESS_LASERKERF);
    mprocesss[PROCESS_LASERKERF] = pProcess;

    pProcess = new CProcess_LaserKerf(m_gSystem.m_mapNameList[PROCESS_LASERKERF_D_WIDE],
                                      PROCESS_LASERKERF_D_WIDE);
    mprocesss[PROCESS_LASERKERF_D_WIDE] = pProcess;
    //pProcess->init_Process();

    mprocesss[PROCESS_UTILS] =
        new CProcess_Utils(m_gSystem.m_mapNameList[PROCESS_UTILS],
                           PROCESS_UTILS);

    mprocesss[PROCESS_LASERFOUCSCALI_D_NARROW] =
        new CProcess_LaserFoucsCali(m_gSystem.m_mapNameList[PROCESS_LASERFOUCSCALI_D_NARROW],
                                    PROCESS_LASERFOUCSCALI_D_NARROW,
                                    LASERPATH_D_NARROW);
    mprocesss[PROCESS_LASERFOUCSCALI_S_NARROW] =
        new CProcess_LaserFoucsCali(m_gSystem.m_mapNameList[PROCESS_LASERFOUCSCALI_S_NARROW],
                                    PROCESS_LASERFOUCSCALI_S_NARROW,
                                    LASERPATH_S_NARROW);

    mprocesss[PROCESS_LASERFOUCSCALI_D_WIDE] =
        new CProcess_LaserFoucsCali(m_gSystem.m_mapNameList[PROCESS_LASERFOUCSCALI_D_WIDE],
                                    PROCESS_LASERFOUCSCALI_D_WIDE,
                                    LASERPATH_D_WIDE);

    mprocesss[PROCESS_LASERFOUCSCALI_L_NARROW] =
        new CProcess_LaserFoucsCali(m_gSystem.m_mapNameList[PROCESS_LASERFOUCSCALI_L_NARROW],
                                    PROCESS_LASERFOUCSCALI_L_NARROW,
                                    LASERPATH_L_NARROW);

    mprocesss[PROCESS_POWERCALI_D_WIDE] =
        new CProcess_LaserPowerCali(m_gSystem.m_mapNameList[PROCESS_POWERCALI_D_WIDE],
                                    PROCESS_POWERCALI_D_WIDE,
                                    LASERPATH_D_WIDE);
    mprocesss[PROCESS_POWERCALI_D_NARROW] =
        new CProcess_LaserPowerCali(m_gSystem.m_mapNameList[PROCESS_POWERCALI_D_NARROW],
                                    PROCESS_POWERCALI_D_NARROW,
                                    LASERPATH_D_NARROW);

    mprocesss[PROCESS_POWERCALI_S_NARROW] =
        new CProcess_LaserPowerCali(m_gSystem.m_mapNameList[PROCESS_POWERCALI_S_NARROW],
                                    PROCESS_POWERCALI_S_NARROW,
                                    LASERPATH_S_NARROW);

    mprocesss[PROCESS_POWERCALI_L_NARROW] =
        new CProcess_LaserPowerCali(m_gSystem.m_mapNameList[PROCESS_POWERCALI_L_NARROW],
                                    PROCESS_POWERCALI_L_NARROW,
                                    LASERPATH_L_NARROW);
     
}

void VSMT_Main::SM_Home(int iStep, bool bSingle)
{
    CMotorDriver* pMotorDriver = GET_CARD(MOTOR_DRIVER, CMotorDriver);
    switch (iStep) {
        case 1:
        {
            CLaserDriver_Base* pLaserDriver = GET_CARD(LASER_DRIVER, CLaserDriver_Base);
            Q_ASSERT(pLaserDriver);
            //关光，不在这里关光，有可能正在划线
            //pLaserDriver->SetGateSource(LASER, TRUE);
            //pLaserDriver->SetInnerGate(LASER, true);

            //关掉破真空
            pMotorDriver->setio(IO_OUTPUT, OUT_WT_WAFER_VACUUM_BREAK, false);

            //关闭总光闸
            pMotorDriver->setio(IO_OUTPUT, OUT_Shutter_All_Open, false);

        }
        break;
        case 2:
            pMotorDriver->home(MOTORZ, false);
            break;
        case 3:
            pMotorDriver->wait_home_finished(MOTORZ);
            break;
        case 4:
            //pMotorDriver->home(MOTORG1_PCHANGE);
            pMotorDriver->home(MOTORG2_POWER);

#ifdef __USE_G5_G6__
            pMotorDriver->home(MOTORG5_NARROWINDEX);
            pMotorDriver->home(MOTORG6_NARROW5050);
#endif

            pMotorDriver->home(MOTORX);
            pMotorDriver->home(MOTORW);
        case 7:
            pMotorDriver->wait_home_finished(MOTORX);
            pMotorDriver->wait_home_finished(MOTORW);
            pMotorDriver->wait_home_finished(MOTORG2_POWER);
#ifdef __USE_G5_G6__
            pMotorDriver->wait_home_finished(MOTORG5_NARROWINDEX);
            pMotorDriver->wait_home_finished(MOTORG6_NARROW5050);
#endif
            //pMotorDriver->wait_home_finished(MOTOR_SHUTTER);
            break;
        case 8:
            pMotorDriver->home(MOTORY);
        case 9:
            pMotorDriver->wait_home_finished(MOTORY);
            break;
        case 10:
            if (bSingle) {
                m_gSystem.m_SysMsg.SetMsg(QObject::trUtf8("%1 home finished")
                                          .arg(m_sName));
            }
            break;
    }
}

void VSMT_Main::init_Machine()
{
    m_pState_Idle = new VST_Idle_Main(VarState_Idle_Main, QObject::trUtf8("Cut Idle"), this);
    m_pState_Wait = new VST_Wait_Main(VarState_Wait_Main, QObject::trUtf8("Cut Wait"), this);
    m_pState_Semi = new VST_Semi_Main(VarState_Semi_Main, QObject::trUtf8("Cut Test"), this);

    CProcess_LaserKerf* processLaserKerf = GET_PROCESS(PROCESS_LASERKERF, SM_MAIN, CProcess_LaserKerf);
    CProcess_LaserKerf* processLaserKerfDwide = GET_PROCESS(PROCESS_LASERKERF_D_WIDE, SM_MAIN, CProcess_LaserKerf);
    CMProcess* processHalfcutKerf = GET_PROCESS(PROCESS_HALFKERF, SM_MAIN, CMProcess);
    CProcess_Level* processLevel = GET_PROCESS(PROCESS_LEVELING, SM_MAIN, CProcess_Level);

    processHalfcutKerf->init_Process();
    processLaserKerf->init_Process();
    processLaserKerfDwide->init_Process();

    processLaserKerf->SetContainer(&processLevel->m_imageContainerBase[0], 
                                   &processLevel->m_imageContainerBase[1]);

    processLaserKerfDwide->SetContainer(&processLevel->m_imageContainerBase[0],
                                   &processLevel->m_imageContainerBase[1]);

    VSMT_Base::init_Machine();
}

void VSMT_Main::exit_Machine()
{
    try {
        m_gSystem.SetIndicatorLight(Qt::red, false);
        m_gSystem.SetIndicatorLight(Qt::yellow, false);
        m_gSystem.SetIndicatorLight(Qt::green, false);
        m_gSystem.SetIndicatorBuzz(false);
    } catch (QString& s) {
        MqDebug() << s;
    }
    VSMT_Base::exit_Machine();
}

void VSMT_Main::do_Msg(const V_Msg &msg)
{

    switch (msg.m_iID) {
        case VarMsg_RestartAutoCut:
            if ((m_pHistoryState_Auto&&m_pHistoryState_Auto->m_iStateType == VS_Thread::State_Work_Auto) || m_pCurState->m_iStateType == VS_Thread::State_Work_Auto) {

                //停止所有
                LOG_WARN("Restart auto cutting");

                V_Msg msg(VarMsg_Stop_ID, "Restart auto cut stop machine");
                VSMT_Base::do_Msg(msg);

                //启用自动
                /*m_pState_Idle->pushfront_Msg(VarMsg_StartAuto_ID, "Start Auto", QVariantList());*/
                V_Msg msg2(VarMsg_StartAuto_ID, "Restart auto cut : start work");
                m_pState_Idle->do_Msg(msg2);

                //启用切割
                m_pState_Wait->pushback_Msg(VarMsg_Auto_StartCut,
                                            QObject::trUtf8("Cut_Process"), QVariantList());

                return;

            } else {
                m_gSystem.m_SysMsg.SetMsg(QObject::tr("Can't restart cutting,not start cut"));
                return;
            }
            break;

        case VarMSg_AbortAutoCut:
            if ((m_pHistoryState_Auto && m_pHistoryState_Auto->m_iStateType == VS_Thread::State_Work_Auto)
                || m_pCurState->m_iStateType == VS_Thread::State_Work_Auto) {

                //停止所有
                LOG_WARN("Abort auto cutting");

                V_Msg msg(VarMsg_Stop_ID, "Abort auto cut stop machine");
                VSMT_Base::do_Msg(msg);

                //启用自动
                /*m_pState_Idle->pushfront_Msg(VarMsg_StartAuto_ID, "Start Auto", QVariantList());*/
                V_Msg msg2(VarMsg_StartAuto_ID, "Abort auto cut : start work");
                m_pState_Idle->do_Msg(msg2);

                pushfront_Msg(VarMsg_Pause_ID, QObject::trUtf8("Pause Sig"));

                m_gSystem.m_SysMsg.SetMsg(QObject::tr("Please reset worktable wafer status"));

                return;

            } else {
                m_gSystem.m_SysMsg.SetMsg(QObject::tr("Can't abort cutting,not start cut"));
                return;
            }
            break;
        case VarMsg_Stop_ID:
        {

            CMotorDriver* pMotorDriver = GET_CARD(MOTOR_DRIVER, CMotorDriver);
            pMotorDriver->stopmove_all();
            pMotorDriver->abortprm_all();

            //停止时不重置切割道
            m_gSystem.Reset_All_Side(false);

            //总工作时间，包括暂停的时间
            m_gSystem.m_totalWorkTime.StopTime();
            m_gSystem.m_lineTime.StopTime();
            m_gSystem.m_cellTime.StopTime();
            m_gSystem.m_totalCoatTime.StopTime();
            m_gSystem.m_totalCleanTime.StopTime();
            m_gSystem.m_fullAutoTime.StopTime();

            CProcess_Clean* pClean = GET_PROCESS(PROCESS_CLEAN, SM_CLEAN, CProcess_Clean);
            CProcess_Coat* pCoat = GET_PROCESS(PROCESS_COAT, SM_COAT, CProcess_Coat);
            pCoat->m_COAT_CLEAN_TIME.StopTime();
            pClean->m_COAT_CLEAN_TIME.StopTime();
            m_gSystem.EvtLog(QString("STP"), QObject::trUtf8("Stop All"));

            PROCESSMAP::iterator ii = mprocesss.begin();
            for (; ii != mprocesss.end(); ii++) {
                CMProcess * p = (CMProcess *)(*ii);
                p->ClearContainer();
            }

            ((VST_Semi_Main*)m_pState_Semi)->m_iCurOperator = -1;
            break;
        }
        case VarMsg_Abort_ID:
        {
            //取消
            VS_Thread* pState = (VS_Thread*)m_pCurState;
            switch (pState->m_iStateType) {
                case VS_Thread::State_Work_Auto:

                    SetState(m_pState_Wait, true);
                    m_pState_Wait->clearAllNextState();
                    break;
                case VS_Thread::State_Idle:
                {
                    m_pState_Wait->clearAllNextState();
                    if (m_pHistoryState_Auto) {
                        m_pHistoryState_Auto = m_pState_Wait;
                    }
                    break;
                }

            }
        }
        case VarMsg_StopSemi_ID:
        {
            ((VST_Semi_Main*)m_pState_Semi)->m_iCurOperator = -1;
            break;
        }
    }
    VSMT_Base::do_Msg(msg);
}

