/*******************************************************************************
*                                                                              *
* Société de Transports de Montréal.                                    	   *
* 2012                                                                         *
*                                                                              *
* Projet Zones Tests                                                           *
*                                                                              *
*                                                                              *
*                                                                              *
*******************************************************************************/
/*
    Description:
    Classe de base des définitions des différentes stations.

*/

/* ************************************************************************** */
/* Revision:
### 20121210 JFM
    Verision d'origine.

### YYYYMMDD Description du besoin ou du bug
    Description du changement.
 */

/* ************************************************************************** */
#include "Station.h"

CStation::CStation()
{
    mZT1ApproachCDV = mZT1CDV = mZT1AlarmAutoAcquireCDV = mZT1SubsequentCDV = 0;
	mZT2ApproachCDV = mZT2CDV = mZT2AlarmAutoAcquireCDV = 0;
    mStationInputMasks.InputZT1_AltITIMask = 0;//Useful for Simulator only
}
CStation::~CStation()
{
	for(int i = 0; i < mCDVList.size(); i++)
		delete mCDVList.at(i);

	mCDVList.clear();
}

unsigned int CStation::CheckStationKey(unsigned int ExternalInputs)
{
	unsigned int key = ExternalInputs;
	unsigned int checkkey = mStationPhysicalKey;
    unsigned int mask = mStationInputMasks.InputStationIDMask;
	key &= mask;
	if(key != checkkey)
    {
        CEngLog::instance()->AddLogString(QString("").sprintf("Incohérence de la clef physique.  Physique: 0x%x, Attendue: 0x%x",key,mStationPhysicalKey),1);
		return RET_ERROR;
    }
    CEngLog::instance()->AddLogString(QString("").sprintf("Clef physique de la station cohérente: 0x%x",key),3);

    return RET_OK;
}

unsigned int CStation::BuildCDVList()
{
	if(BuildStationCDVList() == RET_OK)
	{
		return true;
	}
    mStationInputMasks.InputZT1_StdITIMask = mStationInputMasks.InputZT1ITIMask;    //Useful for Simulator only

	return false;
}


bool CStation::IsZT1ApproachCDVOccupied()
{
	if(mZT1ApproachCDV)
		return mZT1ApproachCDV->IsOccupied();

	return false;
}

bool CStation::IsZT1ApproachPresent()
{
    if(mZT1ApproachCDV == mZT1CDV)
        return false;

    return true;
}

bool CStation::IsZT1CDVOccupied()
{

	if(mZT1CDV)
		return mZT1CDV->IsOccupied();

	return false;
}

int CStation::GetCurrentITI()
{
    return ZT_PRIMARY_ITI;  //Dans les stations avec un seul itinéraire, toujours renvoyer l'itinérarie principal.
}

bool CStation::IsZT1AnalysisFinished()
{
    //Normally, the ZT1 analysis ends when the train quits the ZT1 CDV.
    return !IsZT1CDVOccupied();
}

bool CStation::IsZT1SubsequentCDVOccupied()
{
    if(mZT1SubsequentCDV)
        return mZT1SubsequentCDV->IsOccupied();

    return false;
}

bool CStation::IsZT2CDVOccupied()
{
	if(mZT2CDV)
		return mZT2CDV->IsOccupied();

	return false;
}

bool CStation::IsCIZT1ITIActive(unsigned int ExtInputData)
{
    return ((ExtInputData & mStationInputMasks.InputZT1ITIMask) != 0);
}

bool CStation::IsCIZT2ITIActive(unsigned int ExtInputData)
{
    return ((ExtInputData & mStationInputMasks.InputZT2ITIMask) != 0);
}

bool CStation::IsZT1AlarmAutoAcquireCDVOccupied()
{
	if(mZT1AlarmAutoAcquireCDV)
		return mZT1AlarmAutoAcquireCDV->IsOccupied();

	return false;
}

bool CStation::IsZT2AlarmAutoAcquireCDVOccupied()
{
	if(mZT2AlarmAutoAcquireCDV)
		return mZT2AlarmAutoAcquireCDV->IsOccupied();


	return false;
}

bool CStation::IsZT2ApproachCDVOccupied()
{
	if(mZT2ApproachCDV)
		return mZT2ApproachCDV->IsOccupied();

	return false;
}

//NOTE: Reimplement this function in the station class if necessary (for instance, the
//Montmorency station has 2 ZT1 itineraries that change inputs masks according to
//which itinerary is commanded.
unsigned int CStation::UpdateStationMasks(unsigned int ExtInputData)
{
	Q_UNUSED(ExtInputData)
    mStationInputMasks.InputZT1_StdITIMask = mStationInputMasks.InputZT1ITIMask;
	return RET_OK;
}

unsigned int CStation::UpdateCDVs(unsigned int ExtInputData)
{
	//Update CDVs states.
	for(int CDV = 0; CDV < mCDVList.size(); CDV++)
	{
		mCDVList.at(CDV)->ComputeCDVState(ExtInputData,mStationInputMasks.InputZT1ITIMask,mStationInputMasks.InputZT2ITIMask);
	}

	return RET_OK;
}

bool CStation::StationHasZT2()
{
    return mStationHasZT2;
}

GenericInputMasks_t *CStation::GetInputMasks()
{
//	qDebug("CStation get input masks");
	return &mStationInputMasks;
}

GenericAnalogAcquisitionChannels_t *CStation::GetAnalogAcqChannels()
{
	return &mAnalogAcqChannels;
}
