#include "cprocess_coatclean.h"
#include "logic.h"
#include <algorithm>


CProcess_CoatClean::CProcess_CoatClean(const QString &name, int32_t id)
    :CMProcess(name, id)
{
    m_Variants.add_Variant(Var_CoatClean_Spindle_Move_TimeOut,
                           QObject::trUtf8("Spindle_Move_TimeOut"), int(20000), false,
                           Variant::TOXML);
    m_Variants.add_Variant(Var_CoatClean_Single_Wait_Time,
                           QObject::trUtf8("Single_Wait_Time"), int(100), false,
                           Variant::TOXML);
    m_Variants.add_Variant(Var_Process_Coat_TotalVolume,
                           QObject::trUtf8("TotalCoatVolume"), double(0), false,
                           Variant::TOFILE);
    m_iActionType = -1;
    m_iCurStep = -1;
    m_COAT_CLEAN_TIME.ClearTime();
    m_COAT_CLEAN_TIME.StopTime();
}

QString CProcess_CoatClean::GetActionName(int iActionID)
{
    UNUSED(iActionID);
    Q_ASSERT(0); return QString();
}

bool CProcess_CoatClean::GetCoatCleanStep(int iActionType,
                                          int iStepIndex,
                                          COATCLEANSTEP &step)
{
    COATCLEANSTEPVECTOR* vector = &m_vCoatCleanStep;
    if (iActionType == CLEANTABLE_ACTION) {
        vector = &m_vCleanTableStep;
    } else if (iActionType == CLEANCOATFLUID_ACTION) {
        vector = &m_vCleanTableRing;
    }
    QMutexLocker locker(&vector->mutex);
    if (!OUTOFRANGE(iStepIndex, 0, vector->size())) {
        step = (*vector)[iStepIndex];
        return true;
    }
    return false;
}


void CProcess_CoatClean::all_action_before(int iActionType, int iStep)
{
    UNUSED(iActionType);
    UNUSED(iStep);

}

void CProcess_CoatClean::single_action_before(int iActionType, int32_t iType,
                                              double dTime, int iRPM, int iStep)
{
    if (iStep >= 199) {
        m_COAT_CLEAN_TIME.StartTime();
    }
    if (iStep == 0) {
        m_COAT_CLEAN_TIME.ClearTime();
    }
    UNUSED(iActionType);
    UNUSED(iType);
    UNUSED(dTime);
    UNUSED(iRPM);
    UNUSED(iStep);
}

bool CProcess_CoatClean::single_action_wait(int iActionType, int32_t iType,
                                            double dTime, int iRPM, int iStep)
{
    UNUSED(iActionType);
    UNUSED(iType);
    UNUSED(dTime);
    UNUSED(iRPM);
    UNUSED(iStep);
    //    int iTime=
    //    m_Variants.get_VData(Var_CoatClean_Single_Wait_Time)->toInt();
    //    MSleep(iTime);
    return true;
}

void CProcess_CoatClean::single_action_after(int iActionType, int32_t iType,
                                             double dTime, int iRPM, int iStep)
{

    if (iStep == 1) {
        m_COAT_CLEAN_TIME.StopTime();
        SetdefaultSpeed(false);
    }
    UNUSED(iActionType);
    UNUSED(iType);
    UNUSED(dTime);
    UNUSED(iRPM);
    UNUSED(iStep);
}

void CProcess_CoatClean::all_action_after(int iActionType, int iStep)
{
    UNUSED(iActionType);
    UNUSED(iStep);
}

void CProcess_CoatClean::ReadCleanTable(const QString filePath, COATCLEANSTEPVECTOR& coatStepTable)
{
    QFile file(filePath);
    if (!file.exists(filePath)) {
        MQT_THROW_STR(QObject::trUtf8("open path %1 failed.File not exists")
                      .arg(filePath));
    }
    if (!file.open(QIODevice::ReadOnly)) {
        MQT_THROW_STR(QObject::trUtf8("open path %1 failed")
                      .arg(filePath));
    }
    QDataStream stream(&file);
    int iSize = 0;
    stream >> iSize;
    coatStepTable.resize(iSize);
    for (int i = 0; i < iSize; i++) {
        stream >> coatStepTable[i].dTime;
        stream >> coatStepTable[i].iRPM;
        stream >> coatStepTable[i].iType;
    }
    file.close();
}

void CProcess_CoatClean::WriteCleanTable(const QString filePath, COATCLEANSTEPVECTOR& coatStepTable)
{
    QFile file(filePath);
    //if(!file.exists(filePath)){
    //	MQT_THROW_STR(QObject::trUtf8("open path %1 failed.File not exists")
    //		.arg(filePath));
    //}
    if (!file.open(QIODevice::WriteOnly)) {
        MQT_THROW_STR(QObject::trUtf8("open path %1 failed")
                      .arg(filePath));
    }
    QDataStream stream(&file);
    int iSize = coatStepTable.size();
    stream << iSize;
    for (int i = 0; i < iSize; i++) {
        stream << coatStepTable[i].dTime;
        stream << coatStepTable[i].iRPM;
        stream << coatStepTable[i].iType;
    }
    file.close();
}

void CProcess_CoatClean::ReadWriteCleanTable(bool bWrite)
{

}

void CProcess_CoatClean::do_msg(int iID, QVariantList &vlInput, V_MsgOutput *pvlOutput)
{
    UNUSED(pvlOutput);
    int32_t isize = vlInput.size();
    switch (iID) {
        case ALL_ACTION_BEFORE:
            if (isize >= 2) {
                all_action_before(vlInput[0].toInt(), vlInput[1].toInt());
            }
            break;
        case SINGLE_ACTION_BEFORE:
            if (isize >= 5) {
                single_action_before(vlInput[0].toInt(), vlInput[1].toInt(),
                                     vlInput[2].toDouble(), vlInput[3].toInt(), vlInput[4].toInt());
            }
            break;

        case SINGLE_ACTION_WAIT:
            if (isize >= 5) {
                single_action_wait(vlInput[0].toInt(), vlInput[1].toInt(),
                                   vlInput[2].toDouble(), vlInput[3].toInt(), vlInput[4].toInt());
            }
            break;
        case SINGLE_ACTION_AFTER:
            if (isize >= 5) {
                single_action_after(vlInput[0].toInt(), vlInput[1].toInt(),
                                    vlInput[2].toDouble(), vlInput[3].toInt(), vlInput[4].toInt());
            }
            break;

        case ALL_ACTION_AFTER:
            if (isize >= 2) {
                all_action_after(vlInput[0].toInt(), vlInput[1].toInt());
            }
            break;
        case INIT_POS:
            if (isize >= 0) {
                Init_Pos();
            }
            break;
        case SPINDLE_UP:
        {
            if (isize >= 1) {
                SpindleUp(vlInput[0].toBool());
            }
            break;
        }
    }
    CMProcess::do_msg(iID, vlInput, pvlOutput);
}

void CProcess_CoatClean::Init_Pos()
{
    for (int i = 0; i < 500; i++) {
        all_action_before(NORMAL_ACTION, i);
    }
}

void CProcess_CoatClean::SpindleUp(bool bUp, bool bAfterChecked)
{
    bUp;
}

bool CProcess_CoatClean::isSpindleHomed()
{
    return false;
}

void CProcess_CoatClean::SetdefaultSpeed(bool bSetSpindle)
{
    UNUSED(bSetSpindle);
}

bool CProcess_CoatClean::AssertAcuireRes(int vsmId, uint resId, QString info)
{
    if (ResManager().NotAcquired(vsmId, resId))
    {
        MQT_THROW_CODESTR(ALARM_RESERVED, info + "\n" + QObject::tr("Acquire Resouce not acquired at first"));
    }

    if (false == ResManager().CanAcquire(vsmId, resId))
    {
        MQT_THROW_CODESTR(ALARM_RESERVED, info + "\n" + QObject::tr("Acquire Resouce failed"));
    }

    MqDebug() << "AssertAcuireRes" << vsmId << "res" << resId;
    return ResManager().Acquire(vsmId, resId);
}

bool CProcess_CoatClean::ReleaseRes(int vsmId, uint resId)
{
    MqDebug() << "ReleaseRes" << vsmId << "res" << resId;
    return ResManager().Release(vsmId, resId);
}

//Recipe中清洗涂敷的参数
void CProcess_CoatClean::Serialize(QDataStream &stream, bool bwrite, int iVersion)
{
    
    CMProcess::Serialize(stream,bwrite , iVersion);
#if 0
    QMap<int, Variant>::Iterator iter = m_Variants.m_mVariantMap.begin();
    for (; iter != m_Variants.m_mVariantMap.end(); iter++) {
        int valueType = (*iter).m_iSerialStyle;
        if (valueType == Variant::TOFILE || valueType == Variant::TOBOTH) {
            if (bwrite) {
                stream << (*iter).m_vVar;
            } else {
#ifdef __DEFINE_NEW_PARAM__
                if ((*iter).m_iID == Var_Process_Coat_TotalVolume)
                    continue;
#endif // __DEFINE_NEW_PARAM__
                QVariant var;
                stream >> var;
                (*iter).m_vVar = var;
            }
        }
    }
#endif

    if (bwrite) {
        int iSize = m_vCoatCleanStep.size();
        stream << iSize;
        for (int i = 0; i < iSize; i++) {
            stream << m_vCoatCleanStep[i].dTime;
            stream << m_vCoatCleanStep[i].iRPM;
            stream << m_vCoatCleanStep[i].iType;
            stream << m_vCoatCleanStep[i].dSpayNum;
            stream << m_vCoatCleanStep[i].dSpaySpd;
            stream << m_vCoatCleanStep[i].dCenterSpeed;
            stream << m_vCoatCleanStep[i].dEageSpeed;
            stream << m_vCoatCleanStep[i].dCenterWaitTime;
            stream << m_vCoatCleanStep[i].dCoatPreSpyNum;
            stream << m_vCoatCleanStep[i].iCoatPreSpyWaitTime;
            stream << m_vCoatCleanStep[i].dBumpNum;
            stream << m_vCoatCleanStep[i].dPreSpayNum;
        }
        COATCLEANSTEPVECTOR vCleanTable;
        iSize = vCleanTable.size();
        stream << iSize;
        for (int i = 0; i < iSize; i++) {
            stream << vCleanTable[i].dTime;
            stream << vCleanTable[i].iRPM;
            stream << vCleanTable[i].iType;
        }
    } else {
        int iSize;
        stream >> iSize;
        m_vCoatCleanStep.resize(iSize);
        for (int i = 0; i < iSize; i++) {
            stream >> m_vCoatCleanStep[i].dTime;
            stream >> m_vCoatCleanStep[i].iRPM;
            stream >> m_vCoatCleanStep[i].iType;
            stream >> m_vCoatCleanStep[i].dSpayNum;
            stream >> m_vCoatCleanStep[i].dSpaySpd;
            stream >> m_vCoatCleanStep[i].dCenterSpeed;
            stream >> m_vCoatCleanStep[i].dEageSpeed;
            stream >> m_vCoatCleanStep[i].dCenterWaitTime;
#ifdef __DEFINE_NEW_PARAM__
#else
            stream >> m_vCoatCleanStep[i].dCoatPreSpyNum;
            stream >> m_vCoatCleanStep[i].iCoatPreSpyWaitTime;
            stream >> m_vCoatCleanStep[i].dBumpNum;
            stream >> m_vCoatCleanStep[i].dPreSpayNum;
#endif // __DEFINE_NEW_PARAM__
        }
        COATCLEANSTEPVECTOR vCleanTable;
        stream >> iSize;
        vCleanTable.resize(iSize);
        for (int i = 0; i < iSize; i++) {
            stream >> vCleanTable[i].dTime;
            stream >> vCleanTable[i].iRPM;
            stream >> vCleanTable[i].iType;
        }
    }
}


void CProcess_CoatClean::ReadRecipe(ConfigStreamReader& streamReader, int iVersion)
{
    CMProcess::ReadRecipe(streamReader, iVersion);

    //read count
    streamReader.readNextStartElement();
    int iCount = streamReader.attributes().value("count").toString().toInt();

    m_vCoatCleanStep.resize(iCount);
    for (int i = 0; i < iCount; i++) {
        streamReader >> m_vCoatCleanStep[i];
    }

    streamReader.skipCurrentElement();
}

void CProcess_CoatClean::WriteRecipe(ConfigStreamWriter& streamWriter, int iVersion)
{
    CMProcess::WriteRecipe(streamWriter, iVersion);

    int iStepCount = m_vCoatCleanStep.size();
    streamWriter.writeStartElement("StepCount");
    streamWriter.writeAttribute("count", QString::number(iStepCount));

    for (int i = 0; i < iStepCount; i++) {
        streamWriter << m_vCoatCleanStep[i];
    }

    streamWriter.writeEndElement();
}

ConfigStreamWriter & operator<<(ConfigStreamWriter& out, const COATCLEANSTEP& var)
{
    out.writeStartElement("Step");
    out.writeStartElement("dTime");out.writeAttribute("Value", QString::number(var.dTime));out.writeEndElement();
    out.writeStartElement("iRPM"); out.writeAttribute("Value", QString::number(var.iRPM)); out.writeEndElement();
    out.writeStartElement("iType"); out.writeAttribute("Value", QString::number(var.iType)); out.writeEndElement();
    out.writeStartElement("dSpayNum"); out.writeAttribute("Value", QString::number(var.dSpayNum)); out.writeEndElement();
    out.writeStartElement("dSpaySpd"); out.writeAttribute("Value", QString::number(var.dSpaySpd)); out.writeEndElement();

    out.writeStartElement("dCenterSpeed"); out.writeAttribute("Value", QString::number(var.dCenterSpeed)); out.writeEndElement();
    out.writeStartElement("dEageSpeed"); out.writeAttribute("Value", QString::number(var.dEageSpeed)); out.writeEndElement();
    out.writeStartElement("dCenterWaitTime"); out.writeAttribute("Value", QString::number(var.dCenterWaitTime)); out.writeEndElement();
    out.writeStartElement("dCoatPreSpyNum"); out.writeAttribute("Value", QString::number(var.dCoatPreSpyNum)); out.writeEndElement();
    out.writeStartElement("iCoatPreSpyWaitTime"); out.writeAttribute("Value", QString::number(var.iCoatPreSpyWaitTime)); out.writeEndElement();

    out.writeStartElement("dBumpNum"); out.writeAttribute("Value", QString::number(var.dBumpNum)); out.writeEndElement();
    out.writeStartElement("dPreSpayNum"); out.writeAttribute("Value", QString::number(var.dPreSpayNum)); out.writeEndElement();

    out.writeEndElement();

    return out;
}

ConfigStreamReader & operator >> (ConfigStreamReader& in, COATCLEANSTEP& var)
{
    in.readNextStartElement();
    in.readNextStartElement(); var.dTime = in.attributes().value("Value").toDouble(); in.skipCurrentElement();
    in.readNextStartElement(); var.iRPM = in.attributes().value("Value").toInt(); in.skipCurrentElement();
    in.readNextStartElement(); var.iType = in.attributes().value("Value").toInt(); in.skipCurrentElement();
    in.readNextStartElement(); var.dSpayNum = in.attributes().value("Value").toDouble(); in.skipCurrentElement();
    in.readNextStartElement(); var.dSpaySpd = in.attributes().value("Value").toDouble(); in.skipCurrentElement();

    in.readNextStartElement(); var.dCenterSpeed = in.attributes().value("Value").toDouble(); in.skipCurrentElement();
    in.readNextStartElement(); var.dEageSpeed = in.attributes().value("Value").toDouble(); in.skipCurrentElement();
    in.readNextStartElement(); var.dCenterWaitTime = in.attributes().value("Value").toDouble(); in.skipCurrentElement();
    in.readNextStartElement(); var.dCoatPreSpyNum = in.attributes().value("Value").toDouble(); in.skipCurrentElement();
    in.readNextStartElement(); var.iCoatPreSpyWaitTime = in.attributes().value("Value").toInt(); in.skipCurrentElement();

    in.readNextStartElement(); var.dBumpNum = in.attributes().value("Value").toDouble(); in.skipCurrentElement();
    in.readNextStartElement(); var.dPreSpayNum = in.attributes().value("Value").toDouble(); in.skipCurrentElement();
    in.skipCurrentElement();

    return in;
}
