#ifndef CPROCESS_TRANS_H
#define CPROCESS_TRANS_H

#include "cmprocess.h"
#include "ccassette.h"
#include "logic_eap.h"
/*!
 * \brief The CProcess_Trans class
 * 转移操作
 */
class CProcess_Trans : public CMProcess {
public:
    enum msg_id {
        PROCESS_TRANS_MSG_ID = MAX_PROCESS_MSG_ID,

        TRANSSCANCASS,      //扫描料盒
        //TRANSCASSTOCOAT,    //料盒到涂敷台
        //TRANSCOATTOWT,      //涂敷台到平台
        //TRANSWTTOCLEAN,     //平台到清洗台
        //TRANSCLEANTOCASS,   //清洗台到料盒
        //TRANSCLEANTOCHECKBOX,   //清洗台到检查盒
        //TRANSCHECKBOXTOCASS,    //检查盒到料盒
        //TRANSCOATTOCLEAN,		//涂敷台到清洗台
        //TRANSCOATTOCASS,		//涂敷台到料盒
        //TRANSCOATTOCHECKBOX,	//涂覆台到检查盒
        //TRANSCHECKBOXTOCOAT,		//检查盒到涂覆台

        MOVEINITPOS,    //

        RESETSLOT,      //
        ABORTWAFER,     //

        MAX_PROCESS_TRANS_MSG_ID,
    };

    enum msg_new_id {
        //! 基础功能
        //! 
        kTransScanCass = TRANSSCANCASS,
        kMoveInitPos = MOVEINITPOS,
        kResetSlot = RESETSLOT,
        kAbortWafer = ABORTWAFER,
        kTransCassToRailNear = MAX_PROCESS_TRANS_MSG_ID,

        kTransRailNearToCoat,
        kTransRailNearToCheckBox,
        kTransRailNearToWorktable,
        kTransRailNearToClean,
        kTransRailNearToCass,
        kTransRailNearToFar,

        kTransRailFarToRailNear,
        kTransRailFarToCoat,
        kTransRailFarToWorktable,

        kTransCheckBoxToCass,
        kTransCheckBoxToRailNear,

        kTransCleanToRailNear,
        kTransCoatToRailFar,
        kTransCoatToRailNear,

        kTransWorktableToRailNear,

        kTransRailNearLocation,
        kTransRailNearLocationManual,

        kAbortTrans,    //直接放到近轨道上
        kAbortUnload,   //放到近轨道上
        kAbortLoad,     //放到远轨道上

        kTransCheckboxToCoat,
        kTransCheckboxToClean,
        kTransCoatToWt,
        kTransWtToClean,
        kTransCleanToCass,
        kTransCoatToCheckbox,
        kTransCleanToCheckbox,
        kTransCheckboxToWt,
        kTransWtToCheckbox,
    };
    CProcess_Trans(const QString& name, int32_t id);
    ~CProcess_Trans();
public:
    QString GetMsgName(int id);
    void ClawRelease(bool bWait = true);
    void ClawGrabed(bool bWait = true);
    void UnloadPos();
    void LoadPos();
    void ManualLoadPos();

    //! 当前位置低于关联的varId
    bool IsCurPosLower(double dCurPos, int varId);
    bool IsMotorPosLower(int iMotorId, int varId);
    //! 目标位置是否大于参数值
    bool IsPosBigger(double dTargetPos, int varId);
    bool IsPosInRange(double dTargetPos, int varId, double dOffset = 1.0);
    bool IsMotorInRange(int iMotorId, int varId, double dOffset = 1.0);
    //! 目标位置是否小于参数值
    bool IsPosLess(double dTargetPos, int varId);
    bool IsPosUpper(double dTargetPos, int varId);
    bool IsCurPosNearCass(double dCurPos, int varId);
    bool IsPosFar(double dCurPos, int varId);
    enum IonPos {
        IonEntrance, //! 入口
        IonTrans,
        IonLoad,
        IonUnload,
        IonWt,
        IonClean,
        IonCoat,
    };
    void IonBlowOn(IonPos eIonPos = IonEntrance);
    void IonBlowOff(IonPos eIonPos = IonEntrance);
    void IonBlowControl(IonPos eIonPos, bool bOn);

    //是否有晶圆异常检查
    bool AssertRailNearHasWafer(bool bassertexist, QString sTransInfo, int iAlarmCode = ALARM_TRANS_SAFE_PROTECT);
    bool AssertRailNearCassHasWafer(bool bAssertExist, int iAlarmCode = ALARM_TRANS_SAFE_PROTECT);
    bool AssertRailNearLocationHasWafer(bool bAssertExist, int iAlarmCode = ALARM_TRANS_SAFE_PROTECT);
    bool AssertRailFarHasWafer(bool bAssertExist, QString sTitleInfo, int iAlarmCode = ALARM_TRANS_SAFE_PROTECT);
    bool AssertCoatHasWafer(bool bAssertExist, QString sTitleInfo, int iAlarmCode = ALARM_RESERVED);
    bool AssertCleanHasWafer(bool bAssertExist, QString sInfo, int iAlarmCode = ALARM_RESERVED);
    bool AssertWtHasWafer(bool bAssertExist, QString sTitleInfo, int iAlarmCode = ALARM_RESERVED);
    bool AssertCheckBoxhasCell(bool bAssertExist, QString sTransInfo, int iAlarmCode = ALARM_TRANS_SAFE_PROTECT);
    bool AssertLoadHasWafer(bool bAssertExist, QString sTransInfo, int iAlarmCode = ALARM_TRANS_SAFE_PROTECT);
    void AssertUnloadHasWafer(bool bAssertExist, QString sTransInfo, int iAlarmCode = ALARM_TRANS_SAFE_PROTECT);
    bool AssertTransHasWafer(bool bAssertExist, QString sTitleInfo, int iAlarmCode = ALARM_TRANS_SAFE_PROTECT);
    void AssertGrabHasWafer(QString sTransInfo, int iAlarmCode = ALARM_TRANS_SAFE_PROTECT);

    void AssertCoatWaferHasWater(QString sTransInfo, int iAlarmCode = ALARM_TRANS_SAFE_PROTECT);
    void AssertCleanWaferHasWater(QString sTransInfo, int iAlarmCode = ALARM_TRANS_SAFE_PROTECT);


    //移动到初始位置
    void MoveTransInitPos();
    void MoveLoadInitPos();
    void MoveUnLoadInitPos();
    void MoveInitPos();

    //! 夹抓到准备位置
    void MoveHGrabWait(bool bWait = true);

    //夹瓜A
    //取料 //! 先拉到准备位置 再移动到推料准备位置  再推料到定位位置
    void MoveHGrabPickUpReadySpd(bool bWait);//! 到取晶圆准备位置
    void MoveHGrabPickUpCassSpd();//! 取出的位置
    void MoveHGrabPickUpCheckbox();
    void MoveHGrabWaferExistCheck(bool bOffset=false);
    void MoveHGrabBarcode(); //! 移动到读取标签位置
    void MoveHGrabLocationNearReady();   //! 拉到准备位置
    void MoveHGrabLocationNearPushPrepare(); //! 推之前的位置
    void MoveHGrabLocationNearSpd();        //定位操作,用半速

    //! 转移
    void MoveHGrabToCoat(bool bWait = true);
    void MoveHGrabToClean(bool bWait = true);
    void MoveHGrabToRailNear(bool bWait);
    void MoveHGrabToRailFar(bool bWait);

    //! 下料 
    void MoveHGrabPutDownToCassSpd();//! 放晶圆到料盒
    void MoveHGrabPutDownToCheckBoxSpd();//! 放晶圆到检查盒

    void MoveHGrabPutDownPrepare(); //! 下料前放到Barcode扫描位置，用Barcode位置进行运算得出 Location和取料的位置
    void MoveHGrabPutDownReady(); //! Checkbox to cass， 下料前等待位置


#if 0
    //void MoveToPosGrabCoat(bool bOffset);
    //! 过时
    void MoveToPosGrabLock(bool bOffset, bool bOffsetOneMM = false); //移动到规整位置
#endif

    void GrabToPos2Spd(double dPos);

    //中转
    //垂直方向 等待，抓取，规整 涂 清洗
    //轨道上下料使用
    void MoveVTransWait();  //! 安全位置,不用太高
    void MoveVTransPickUpWafer(); //! 从料盒取晶圆
    void MoveTransVNearPull();   //! \sa MoveVTransPickUpWafer
    void MoveTransVNearPush(); //! 推的位置要比拉的位置高一点

    //轨道
    void MoveVTransRailNearReady(bool bWait);
    void MoveVTransRailNear(bool bWait = true);

    void MoveVTransRailFarReady(bool bWait);
    void MoveVTransRailFar(bool bWait = true);

    //! 低于Ready位置则慢速，高于则根据参数
    void MoveVTransCoatReadySpd(bool bHalfspeed = true);
    void MoveVTransCoatUpABitSpd(bool bHalfSpeed = true); //抬高一点
    void MoveVTransCoatSpd(bool bHalfspeed = true);

    void MoveVTransCleanReady(bool bHalfspeed = true);
    void MoveVTransClean(bool bHalfspeed = true);

    void MoveTransPickUpWaferFromCoat(); //! 中转下降并且从涂覆台抓取晶圆
    void MoveTransPutDownWafterToCoat();//! 中转轴下降并放晶圆到涂覆台

    void MoveTransPickUpWaferFromClean();//! 中转轴下降并从清洗台取晶圆    
    void MoveTransPutDownWaferToClean();

    //中转垂直方向抓取上料偏移位
    //void MoveToPosTransOffsetVGrap();

    //! 近轨道操作
    void MoveRailNearOpen(bool bWait = true);
    void MoveRailNearClose();
    //完全规整的过渡位置
    void MoveRailNearReadyClose();
    //拉晶圆时的位置
    void MoveRailNearPullClose();
    void MoveRailNearPullOpen();
    void MoveRailNearOpenMax(bool bWait = true);

    //! 远轨道操作
    void MoveRailFarOpen(bool bWait = true);
    void MoveRailFarOpenMax(bool bWait);

    //! 上料操作
    //垂直方向，等待，清洗，平台
    void MoveVLoadWait();
    void MoveVLoadWT();
    void MoveVLoadFar();
    //! 水平方向
    void MoveHLoadWait(bool bWait);
    void MoveHLoadWT();
    void MoveHLoadRailFar();

    //提起晶圆准备位置
    //过时
    void MoveToPosLoadVCoatFinish(bool bHalfspeed = true);
    void MoveToPosLoadVCoatFinishLow(bool bHalfspeed = true);
    void MoveVLoadRailFar(bool bHalfSpeed = false);

    //下料操作
    //垂直方向，等待，清洗，平台
    void MoveVUnloadWait();
    void MoveVUnLoadWT();
    void MoveVUnloadRailNear();

    void MoveHUnloadWait();
    void MoveHUnloadWT(bool bWait = true);
    void MoveHUnloadRailNear(bool bWait = true);
private:
    void AssertSlotExists(bool bAssertExist, CASSSLOT** pSlot, QString sInfo);

public:
    //扫描料盒
    void TransScanCass(int iStep, bool bIsAutoMode);
    //void TransCassToCoat(int iStep);
    //void TransCoatToWT(int iStep);
    //void TransWTToClean(int iStep);
    //void TransCleanToCass(int iStep);		//直接到料盒
    //void TransCleanToCheckBox(int iStep);	//到CheckBox
    void TransCheckBoxToCass(int iStep, bool bIsAutoMode);	//checkBox到料盒
    ////手动
    //void TransCoatToCheckBox(int iStep);	//涂敷台到检查盒
    //void TransCoatToCass(int iStep);		//涂敷台到料盒
    //void TransCoatToClean(int iStep);		//涂敷台到清洗
    //void TransCheckBoxToCoat(int iStep);

    void AbortGrab(int iStep);
    void AbortArrange(int iStep);
    void AbortTrans(int iStep);
    void AbortCoat(int iStep);
    void AbortLoad(int iStep);
    void AbortWT(int iStep);
    void AbortUnLoad(int iStep);
    void AbortClean(int iStep);
    void AbortCheckBox(int iStep);

    void StepSleep();
    bool WriteRecoveredData();
    bool ReadRecoveredData();
public:
    void do_msg(int iID, QVariantList& vlInput, V_MsgOutput* pvlOutput);
public:
    CASSSLOT* m_pSlotGrab;		//夹抓状态TODO:如果拉的时候没完全拉出来，传感器又检测不到就会有异常， ReadyGrab添加
    CASSSLOT* m_pSlotRailNear;   //规整位
    CASSSLOT* m_pSlotTrans; //转移吸嘴
    CASSSLOT* m_pSlotCoat;	//涂敷台
    CASSSLOT* m_pSlotLoad;	//上料位的晶圆
    CASSSLOT* m_pSlotWT;	//平台上的晶圆
    CASSSLOT* m_pSlotUnLoad;	//下料手上的晶圆
    CASSSLOT* m_pSlotClean;		//清洗台
    CASSSLOT* m_pSlotCheckBox;	//检查料盒的晶圆
    CASSSLOT* m_pSlotRailFar;
    QMutex m_slotMutex;

    void ResetAllSlot();
    void ResetSlot(CASSSLOT** ppSlot);
    void SlotTransfer(CASSSLOT** ppSlotSource,
                      CASSSLOT** ppSlotDest);
    bool IsAllUnLoad();

    //! 真空控制
    void VaccumTransToCoat();
    void VaccumCoatToLoad();
    void VaccumLoadToWT();
    void VaccumWtToUnLoad();
    void VaccumUnLoadToClean();
    void VaccumCleanToTrans();
    void VaccumCoatToTrans();
    void VaccumLoadToCoat();
    void VaccumWTToLoad();
    void VaccumTransToClean();
    void VaccumTransToRail();
    void VaccumRailToTrans();
    void VaccumRailToLoad();
    void VaccumRailToUnLoad();
    void VaccumUnloadToRail();
    void VaccumUnloadToWt();
public:
    //上料轴在等待位置
    bool IsMotorLoadVAtWait();
    bool IsMotorLoadHAtWait();
    bool IsMotorLoadVAtWT();
    bool IsMotorLoadVAtRail();

    //下料轴在等待位置
    bool IsMotorUnloadVAtWait();
    bool IsMotorUnloadHAtWait();

    bool IsMotorUnloadVAtWT();
    bool IsMotorUnloadHAtWT();

    bool IsMotorUnloadVAtRail();
    bool IsMotorUnloadHAtClean();

    bool IsMotorLoadHAtCoat();

    void SetWaferId(CASSSLOT* pcass, _SVID svid);
    void SetWaferIdEmpty(_SVID svid);

private:
    bool MotorInRange(int motorId, int posId);
    void MoveMotorToPos(int motorId, int posId, bool isHalfSpeed = false, bool bWait = true);
    void MoveLoadVToPos(int posId, bool bHalfSpeed = false);
    void MoveHLoadToPos(int posId, bool bWait = true);

    void MoveUnloadVToPos(int posId);
    void MoveUnloadHToPos(int posId, bool bWait = true);

    //传片操作
    void TransCassToNear(int iStep, bool bIsAutoMode);    //! 料盒到近轨道
    void TransNearToCoat(int iStep, bool bIsAutoMode);    //! 近轨道到涂覆台
    void TransNearToFar(int iStep, bool bIsAutoMode);    //! 近轨道到远轨道
    void TransCoatToFar(int iStep, bool bIsAutoMode);     //! 涂覆台到远轨道
    void TransCoatToNear(int iStep, bool bIsAutoMode);    //! 涂覆台到近轨道
    void TransRailFarToWt(int iStep, bool bIsAutoMode);   //! 远轨道到平台
    void TransWtToNear(int iStep, bool bIsAutoMode);      //! 平台到近轨道
    void TransNearToClean(int iStep, bool bIsAutoMode);   //! 近轨道到清洗台
    void TransCleanToNear(int iStep, bool bIsAutoMode);   //! 清洗台到近轨道
    void TransNearToCass(int iStep, bool bIsAutoMode);    //! 近轨道到料盒

    void TransNearToCheckbox(int iStep, bool bIsAutoMode);        //! 近轨道到检查盒
    void TransNearToWt(int iStep, bool bIsAutoMode);              //! 近轨道到工作台         
    void TransFarToNear(int iStep, bool bIsAutoMode);             //! 远轨道到工作台

    void TransCheboxToNear(int iStep, bool bIsAutoMode);          //! 检查盒到近轨道

    void TransFarToCoat(int iStep, bool bIsAutoMode);     //! 远轨道到涂覆台

    /*!
     * @brief 近轨道晶圆规整操作.
     *
     */
    void TransRailNearWaferLocation(int iStep);

    void TransRailNearWaferLocationManual(int iStep);

    /*!
     * @brief 远轨道晶圆规整操作.
     *
     */
    void TransRailFarWaferLocation(int iStep);

    bool AssertAcuireRes(int vsmId, uint resId, QString info);        //! 获取资源，获取不到则报警
    bool ReleaseRes(int vsmId, uint resId);             //!　释放资源


    void CloseCoatCurtain(bool bWait);
    void OpenCoatCurtain(bool bWait);
    void CloseCleanCurtain(bool bWait);
    void OpenCleanCurtain(bool bWait);

    QString GetWaferName(CASSSLOT** ppSlot);

public:
    /**
     * 是否检查盒晶圆实例被使用了.
     * 
     * \return 
     */
    bool IsCheckboxWaferUsed();
    CASSSLOT* CreateOrBindToCheckbox();
    void CreateAndBindToSlot(CASSSLOT* & pSlot);
};

#endif // CPROCESS_TRANS_H
