/*******************************************************************************
*                                                                              *
* Société de Transports de Montréal.                                    	   *
* 2012 - 2013                                                                        *
*                                                                              *
* Projet Zones Tests                                                           *
*                                                                              *
*                                                                              *
*                                                                              *
*******************************************************************************/
/*
	Description:
	Gère la création et l'exécution d'un scénario de passage de train simulé.
	
*/

/* ************************************************************************** */
/* Revision:
### YYYMMDD JFM
	Verision d'origine.
	
### YYYYMMDD Description du besoin ou du bug
	Description du changement.
 */

/* ************************************************************************** */

#include "SimulationScenario.h"

#define BOGIE_DELAY 100
#define SENSOR_DELAY 100

CSimulationScenario::CSimulationScenario()
{
	mCurStep = 0;

	mScenarioTimer = new QTimer();
	mScenarioTimer->setSingleShot(true);
	connect(mScenarioTimer,SIGNAL(timeout()),this,SLOT(ScenarioTimerExpired()));
}

CSimulationScenario::~CSimulationScenario()
{
	DestroyScenario();
}

unsigned int CSimulationScenario::CreateScenario()
{


///    //MPM10
            InsertNewStep(STEP_ACTION_REGISTER_ZT1_ITI,300);
            InsertNewStep(STEP_ACTION_OCCUPY_ZT1_APPROACH,300);
            InsertNewStep(STEP_ACTION_OCCUPY_ZT1,300);
            InsertNewStep(STEP_ACTION_ACTIVATE_FN,0);

            for(int bogie = 1; bogie <= 18; bogie++)
            {

                //if(bogie != 5 /*&& bogie != 6*/)
//                InsertNewStep(STEP_ACTION_ACTIVATE_PGI,0);
//                InsertNewStep(STEP_ACTION_ACTIVATE_PGE,5);

                InsertNewStep(STEP_ACTION_ACTIVATE_S1,SENSOR_DELAY);
                InsertNewStep(STEP_ACTION_DEACTIVATE_S1,BOGIE_DELAY);

                InsertNewStep(STEP_ACTION_DEACTIVATE_PGI,0);
                InsertNewStep(STEP_ACTION_DEACTIVATE_PGE,0);

//                if(bogie != 5 && bogie != 6)
//                    InsertNewStep(STEP_ACTION_ACTIVATE_FN,5);
//                    InsertNewStep(STEP_ACTION_ACTIVATE_FN,5);

//                if(bogie == 12)
//                    InsertNewStep(STEP_ACTION_ACTIVATE_PPI,0);

                InsertNewStep(STEP_ACTION_ACTIVATE_S2,SENSOR_DELAY);
                InsertNewStep(STEP_ACTION_DEACTIVATE_S2,SENSOR_DELAY);


//                InsertNewStep(STEP_ACTION_DEACTIVATE_FN,5);

//                InsertNewStep(STEP_ACTION_DEACTIVATE_PPI,5);

                InsertNewStep(STEP_ACTION_ACTIVATE_S1,SENSOR_DELAY);
                InsertNewStep(STEP_ACTION_DEACTIVATE_S1,BOGIE_DELAY);


                //if(bogie != 5 /*&& bogie != 6 && bogie != 7*/)
//                InsertNewStep(STEP_ACTION_ACTIVATE_PGI,0);
//                InsertNewStep(STEP_ACTION_ACTIVATE_PGE,5);
                InsertNewStep(STEP_ACTION_ACTIVATE_S2,SENSOR_DELAY);
                InsertNewStep(STEP_ACTION_DEACTIVATE_S2,BOGIE_DELAY);
                InsertNewStep(STEP_ACTION_DEACTIVATE_PGI,0);
                InsertNewStep(STEP_ACTION_DEACTIVATE_PGE,0);

            }


 //           InsertNewStep(STEP_ACTION_DESTROY_ZT1_ITI,800);
            InsertNewStep(STEP_ACTION_FREE_ZT1_APPROACH,800);
            InsertNewStep(STEP_ACTION_FREE_ZT1,800);





///    //ZT2


//                InsertNewStep(STEP_ACTION_REGISTER_ZT2_ITI,300);
//                InsertNewStep(STEP_ACTION_OCCUPY_ZT2,300);

//                for(int bogie = 1; bogie <= 18; bogie++)
//                {
//                    InsertNewStep(STEP_ACTION_ACTIVATE_ZT2_S1,SENSOR_DELAY);
//                    InsertNewStep(STEP_ACTION_DEACTIVATE_ZT2_S1,BOGIE_DELAY);

//                //    if(bogie == 5 || bogie == 2)
//                    {
//                  //      InsertNewStep(STEP_ACTION_ACTIVATE_ZT2_PPE,5);
//                  //      InsertNewStep(STEP_ACTION_DEACTIVATE_ZT2_PPE,1);

//                    }

//                   // if(bogie == 3 || bogie == 10)
//                    {
////						InsertNewStep(STEP_ACTION_ACTIVATE_ZT2_PPI,3);
////						InsertNewStep(STEP_ACTION_DEACTIVATE_ZT2_PPI,1);

//                    }

//                    //if(bogie != 3)
//                    {
//                        InsertNewStep(STEP_ACTION_ACTIVATE_ZT2_S1,SENSOR_DELAY);
//                        InsertNewStep(STEP_ACTION_DEACTIVATE_ZT2_S1,BOGIE_DELAY);
//                    }


//                }

//                InsertNewStep(STEP_ACTION_DESTROY_ZT2_ITI,800);
//                InsertNewStep(STEP_ACTION_FREE_ZT2,800);



//////	MR
//      //  InsertNewStep(STEP_ACTION_REGISTER_ZT1_ITI,300);
//        InsertNewStep(STEP_ACTION_OCCUPY_ZT1_APPROACH,300);
//        InsertNewStep(STEP_ACTION_OCCUPY_ZT1,300);

//        InsertNewStep(STEP_ACTION_DEACTIVATE_PGE,0);

//        for(int bogie = 1; bogie <= 18; bogie++)
//        {
//           // if(bogie != 5 && bogie != 7)
//   //         InsertNewStep(STEP_ACTION_ACTIVATE_PGI,0);
//   //         InsertNewStep(STEP_ACTION_ACTIVATE_PGE,0);
////V00 DETECTION
////            if(bogie != 9)
////            {
//               InsertNewStep(STEP_ACTION_ACTIVATE_S1,SENSOR_DELAY);
////            }
//            InsertNewStep(STEP_ACTION_DEACTIVATE_S1,BOGIE_DELAY);
//  //          InsertNewStep(STEP_ACTION_DEACTIVATE_PGI,0);
//   //         InsertNewStep(STEP_ACTION_DEACTIVATE_PGE,0);

////FN DETECTION
////           if(bogie != 7 /*&& bogie != 8 && bogie != 3*/)
//                InsertNewStep(STEP_ACTION_ACTIVATE_FN,0);

//            InsertNewStep(STEP_ACTION_ACTIVATE_S1,SENSOR_DELAY);
//            InsertNewStep(STEP_ACTION_ACTIVATE_S2,SENSOR_DELAY);
//            InsertNewStep(STEP_ACTION_DEACTIVATE_S1,BOGIE_DELAY);

////PPI DETECTION
//            if(bogie == 6 || bogie == 9)
//                InsertNewStep(STEP_ACTION_ACTIVATE_PPI,0);

////FN DETECTION
////            if(bogie != 7 /*&& bogie != 8 && bogie != 3*/)
//                InsertNewStep(STEP_ACTION_DEACTIVATE_FN,0);

//            InsertNewStep(STEP_ACTION_ACTIVATE_S2,SENSOR_DELAY);
//            InsertNewStep(STEP_ACTION_DEACTIVATE_S2,BOGIE_DELAY);

////PPI DETECTION
//            if(bogie == 6 || bogie == 9)
//                InsertNewStep(STEP_ACTION_DEACTIVATE_PPI,0);

// //           if(bogie != 2 && bogie != 11)
//  //          InsertNewStep(STEP_ACTION_ACTIVATE_PGI,0);
// //           if(bogie != 2 && bogie != 11)
//  //          InsertNewStep(STEP_ACTION_ACTIVATE_PGE,0);
//            InsertNewStep(STEP_ACTION_ACTIVATE_S2,SENSOR_DELAY);
//            InsertNewStep(STEP_ACTION_DEACTIVATE_S2,BOGIE_DELAY);
//  //          InsertNewStep(STEP_ACTION_DEACTIVATE_PGI,0);
//   //         InsertNewStep(STEP_ACTION_DEACTIVATE_PGE,0);

//        }


//        InsertNewStep(STEP_ACTION_DESTROY_ZT1_ITI,800);

//        InsertNewStep(STEP_ACTION_FREE_ZT1,800);

//        InsertNewStep(STEP_ACTION_FREE_ZT1_APPROACH,800);

	return RET_OK;
}

unsigned int CSimulationScenario::DestroyScenario()
{
	for(int i = 0; i < mScenarioStepsList.size(); i++)
	{
		delete mScenarioStepsList.at(i);
	}
	mScenarioStepsList.clear();
	return RET_OK;
}
unsigned int CSimulationScenario::Start()
{
	emit ExecuteNextStep(mScenarioStepsList.at(mCurStep));
	mScenarioTimer->start(mScenarioStepsList.at(mCurStep)->StepDelayMillisecs);
	return RET_OK;
}
unsigned int CSimulationScenario::Reset()
{
	mScenarioTimer->stop();
	mCurStep = 0;
	return RET_OK;
}

void CSimulationScenario::ScenarioTimerExpired()
{
	if(mCurStep == mScenarioStepsList.size())	//the simulation is finished
	{
		Reset();
		emit ScenarioCompleted();
		return;
	}

	emit ExecuteNextStep(mScenarioStepsList.at(mCurStep));
	mScenarioTimer->start(mScenarioStepsList.at(mCurStep)->StepDelayMillisecs);
	mCurStep++;

}

//Cette fonction ajoute un événement dans la liste.  Le paramètre Delay correspond
//au nombre de millisecondes de délai entre l'exécution de cet événement et l'exécution
//de l'événement subséquent.  Un délai de 0 correspond au délai le plus court que la boucle
//d'exécution est capable de générer.
//Ex.: InsertNewStep(STEP_ACTION_REGISTER_ZT1_ITI,300);
//Activera l'entrée itinéraire ZT1 dans le simulateur et l'étape suivante sera
//exécutée 300ms plus tard.
//NOTE: Les délais sont approximatifs et gagnent de la précision lorsque le programme
//roule sur un ordinateur plus puissant.
unsigned int CSimulationScenario::InsertNewStep(unsigned int StepID, int Delay)
{
	CSimulationStep *NewStep = new CSimulationStep;

	NewStep->StepAction = StepID;
	NewStep->StepDelayMillisecs = Delay;
	mScenarioStepsList.append(NewStep);

	return mScenarioStepsList.size();
}
