/*******************************************************************************
*                                                                              *
* Société de Transports de Montréal.                                    	   *
* 2012                                                                         *
*                                                                              *
* Projet Zones Tests                                                           *
*                                                                              *
*                                                                              *
*                                                                              *
*******************************************************************************/
/*
    Description:
	Page principale de la ZT.  C'est sur cette dernière que tout est affiché.

*/

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

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

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


#include "ZTPage.h"
#include <QPainter>
#include "GlobalDefine.h"
#include <QDialog>
#include <QMainWindow>
#include "Zonetest.h"
#include <QDateTime>
#include "ZTVersion.h"
#include "SwitchCDVItem.h"



CZTPage::CZTPage(QGraphicsWidget *Parent)
{
//	Q_UNUSED(Parent)
    setGeometry(0,0,SCREEN_RES_WIDTH,SCREEN_RES_HEIGHT);

	mProgramHandle = 0;
	mZTSimulatorPtr = 0;

	QGraphicsTextItem *SoftVersion = new QGraphicsTextItem(this);
	QFont TextFont;
	TextFont.setPointSize(15);
	TextFont.setBold(true);
	SoftVersion->setFont(TextFont);
	SoftVersion->setPlainText(QString().sprintf("Version: %s",ZT_SOFT_VERSION));
	SoftVersion->setZValue(1);
	SoftVersion->adjustSize();
	SoftVersion->setPos(800,2);

	QGraphicsTextItem *ZTStartDateTime = new QGraphicsTextItem(this);
	ZTStartDateTime->setFont(TextFont);
	QString StartDateTime = "ZT démarrée le: ";
	StartDateTime += QDateTime::currentDateTime().toString("yyyy/MM/dd - hh:mm");
	ZTStartDateTime->setPlainText(StartDateTime);
	ZTStartDateTime->setZValue(1);
	//ZTStartDateTime->adjustSize();
	ZTStartDateTime->setPos(200,675);

	mTimeDisplayText = new QGraphicsTextItem(this);
	mTimeDisplayText->setPos(400,2);
//	QFont TextFont;
//	TextFont.setPointSize(15);
//	TextFont.setBold(true);
	mTimeDisplayText->setFont(TextFont);
	mTimeDisplayText->setZValue(1);
//	mTimeDisplayText->adjustSize();

	mToolsPushButton = new CPushButton(this,"./Images/tools.png");
    mToolsPushButton->setPos(25,650);
    mToolsPushButton->resize(50,50);
	connect( mToolsPushButton, SIGNAL( clicked(CPushButton*) ), this, SLOT( SettingsButtonPressed() ) );

    mZTLogPushButton = new CPushButton(this,"./Images/log.png");
    mZTLogPushButton->setPos(10,570);
    mZTLogPushButton->resize(65,65);
    connect( mZTLogPushButton, SIGNAL( clicked(CPushButton*) ), this, SLOT( ShowZTLogButtonPressed() ) );

	CPushButton *LogsPushButton = new CPushButton(this,"./Images/Save-icon.png");
    LogsPushButton->setPos(10,490);
	LogsPushButton->resize(65,65);
	connect( LogsPushButton, SIGNAL( clicked(CPushButton*) ), this, SLOT(LogsButtonPressed()) );

    mExitPasswordPrompt = new CPasswordPrompt(Parent);
    mExitPasswordPrompt->setZValue(2);
    mExitPasswordPrompt->hide();
    connect(mExitPasswordPrompt,SIGNAL(PasswordValid()),this,SLOT(ExitPasswordValid()));
    connect(mExitPasswordPrompt,SIGNAL(Canceled()),this,SLOT(ExitPasswordInvalid()));

	mTimeDisplayTimer = new QTimer();
	connect(mTimeDisplayTimer,SIGNAL(timeout()),this,SLOT(UpdateTime()));
	mTimeDisplayTimer->setSingleShot(false);
	mTimeDisplayTimer->start(1000);

	mStatusBar = new CStatusBar(this);
	mStatusBar->setPos(0,715);

	mEventsBar = new CEventsBar(this);
	mEventsBar->setPos(0,715+mStatusBar->boundingRect().height());

	mZT1EquipmentWidget = new CZT1EquipmentWidget(this);
	mZT1EquipmentWidget->setPos(512,150);

    mZT2EquipmentWidget = new CZT2EquipmentWidget(this);
	mZT2EquipmentWidget->setPos(150,150);

    mDeckRect = new QGraphicsRectItem(this);
    mDeckRect->hide();
    mDeckRect->setBrush(QBrush(Qt::Dense4Pattern));
    mDeckRect->setPen(QPen(Qt::transparent));

    mIsZT2Present = true;

	mZT1Stats = new CZT1StatsZone(this);
    mZT1Stats->setPos(mZT1EquipmentWidget->pos().x() + 70 ,100+mZT1EquipmentWidget->boundingRect().height() + 80);

    mZT2Stats = new CZT2StatsZone(this);
    mZT2Stats->setPos(mZT2EquipmentWidget->pos().x() + 30,100+mZT2EquipmentWidget->boundingRect().height()+80);

	mZT1DisplayTimer.start();
}

unsigned int CZTPage::SetZTSimulator(CZTSimulator *Ptr)
{
	if(Ptr == 0)
		return RET_ERROR;

	mZTSimulatorPtr = Ptr;
	mZTSimulatorPtr->setParentItem(this);
	mZTSimulatorPtr->setFlag(QGraphicsItem::ItemIsSelectable);
	mZTSimulatorPtr->setFlag(QGraphicsItem::ItemIsMovable);
	mZTSimulatorPtr->setFlag(QGraphicsItem::ItemSendsGeometryChanges);
    mZTSimulatorPtr->setGeometry(200,400,640,480);
	mZTSimulatorPtr->Show();

	return RET_OK;
}

void CZTPage::SettingsButtonPressed()
{
	mProgramHandle->OptionsMenuPageSelected();
}

void CZTPage::ShowZTLogButtonPressed()
{
    mProgramHandle->ShowZTLogViewerPage();
}

unsigned int CZTPage::SetStationName(QString Name)
{
	QGraphicsTextItem *StationName = new QGraphicsTextItem(this);
	QFont TextFont;
	TextFont.setPointSize(18);
	TextFont.setBold(true);
	StationName->setFont(TextFont);
	StationName->setPlainText(Name);
	StationName->setZValue(1);
	StationName->adjustSize();
	StationName->setPos(50,2);
	return RET_OK;
}

void CZTPage::UpdateTime()
{
	QDateTime time = QDateTime::currentDateTime();
	mTimeDisplayText->setPlainText(time.toString("yyyy/MM/dd   hh:mm:ss"));

}

void CZTPage::LogsButtonPressed()
{
	mProgramHandle->LogsPageSelected();
}


unsigned int CZTPage::SetCDVList(QList<CCDV *> *CDVListPtr)
{
	if(CDVListPtr == 0)
		return RET_ERROR;

	mCDVList = CDVListPtr;
	if(mCDVList->size() == 0)
		return RET_ERROR;

	mCDVItemsList.clear();

    int DeckPositionY = -1, DeckPositionX = -1, DeckWidth = 0;

	//Create CDV graphical items list,
	//adjust all their position on screen and
	//set parameters
//	unsigned int LastPos = 0;
    bool scale = false;
    if(mCDVList->size() > 9)
    {
        scale = true;
    }

	for(int i = 0; i < mCDVList->size(); i++)
	{
		int x = 0, y = 70;
        int WaysSpacing = 10;
		CCDVItem *NewCDVGraphicalItem;
//		CCDV *temp = mCDVList->at(i);
		if(mCDVList->at(i)->GetCDVType() == CDV_NORMAL_TYPE)
		{
			NewCDVGraphicalItem = new CCDVItem(mCDVList->at(i),this);
		}
		else
		{
			NewCDVGraphicalItem = new CSwitchCDVItem(mCDVList->at(i),this);

		}

        if(scale)
        {
            NewCDVGraphicalItem->resize(70,NewCDVGraphicalItem->rect().height());
        }

		NewCDVGraphicalItem->SetParameters(mCDVList->at(i)->GetLabel());
		mCDVItemsList.append(NewCDVGraphicalItem);
        x = (mCDVList->at(i)->GetCDVGraphicalPos() * NewCDVGraphicalItem->geometry().width())+90;
		if(mCDVList->at(i)->GetCDVWay() == 2)
            y += WaysSpacing+NewCDVGraphicalItem->geometry().height();
//		NewCDVGraphicalItem->setPos(i*NewCDVGraphicalItem->geometry().width()+90,70);
		NewCDVGraphicalItem->setPos(x,y);
		NewCDVGraphicalItem->setZValue(3);

        if(mCDVList->at(i)->IsCDVDeck() == true)
        {
            if(DeckPositionX == -1)
            {
                DeckPositionX = x/* + (NewCDVGraphicalItem->geometry().width()/2)*/;
            }
            DeckWidth += NewCDVGraphicalItem->geometry().width();

            if(mCDVList->at(i)->GetCDVWay() == 1)
            {
                DeckPositionY = y - 30;
            }
            else
            {
                DeckPositionY = y +NewCDVGraphicalItem->geometry().height() + 5;
            }
        }
	}

    if(DeckPositionX != -1)
    {
        mDeckRect->setRect(0,0,DeckWidth,20);
        mDeckRect->setPos(DeckPositionX,DeckPositionY);
        mDeckRect->show();
    }
    else
        mDeckRect->hide();

	return RET_OK;
}


unsigned int CZTPage::UpdateCDVDisplay(int CDVIndex)
{
	if(CDVIndex >= mCDVItemsList.size())
		return RET_ERROR;

	if(CDVIndex < 0 || CDVIndex >= mCDVItemsList.size())
	{
		for(int i = 0; i < mCDVItemsList.size(); i++)
		{
			mCDVItemsList.at(i)->UpdateState();
		}
	}
	else
		mCDVItemsList.at(CDVIndex)->UpdateState();

	return RET_OK;
}

unsigned int CZTPage::SetZTStatus(unsigned int NbPass, unsigned int NbTriggers, unsigned int ZT1Active, unsigned int ZT2Active)
{
	mStatusBar->SetNbPass(NbPass);
	mStatusBar->SetNbTriggers(NbTriggers);
//    if(ZT1Active == true)
//        mStatusBar->SetZT1Status(SB_ZT_ACTIVE_STATUS);
//    else
//        mStatusBar->SetZT1Status(SB_ZT_INACTIVE_STATUS);
	mStatusBar->SetZT1Status(ZT1Active);

    if(mIsZT2Present == true)
    {
//        if(ZT2Active == true)
//        {
//            mStatusBar->SetZT2Status(SB_ZT_ACTIVE_STATUS);
//        }
//        else
//        {
//            mStatusBar->SetZT2Status(SB_ZT_INACTIVE_STATUS);
//        }
		mStatusBar->SetZT2Status(ZT2Active);
    }
    else
    {
        mStatusBar->SetZT2Status(SB_ZT_NOT_PRESENT_STATUS);
    }

	if(ZT1Active == SB_ZT_ACTIVE_STATUS)
	{
		mZT1EquipmentWidget->SetActivation(true);
	}
	else
	{
		mZT1EquipmentWidget->SetActivation(false);
	}


	if(ZT2Active == SB_ZT_ACTIVE_STATUS)
	{
		mZT2EquipmentWidget->SetActivation(true);
	}
	else
	{
		mZT2EquipmentWidget->SetActivation(false);
	}

	return RET_OK;
}

unsigned int CZTPage::SetZT1Data(CZT1ThreadData *Data, bool ForceDisplay)
{
	if(Data == 0)
		return RET_ERROR;

	//Unless specified by the ForceDisplay flag, limit refresh rate to 24 fps (~42 milliseconds)
	if(ForceDisplay == false && mZT1DisplayTimer.elapsed() < 42)
	{
		return RET_OK;
	}

	mZT1EquipmentWidget->SetState((bool)Data->mS1,(bool)Data->mS2,(bool)Data->mFN,(bool)Data->mPG,(bool)Data->mPG,(bool)Data->mPInt,(bool)Data->mPExt);
	mZT1Stats->UpdateStats(Data);
	mZT1DisplayTimer.start();

	return RET_OK;

}

unsigned int CZTPage::SetZT1TrainData(int TrainType, QList<qint16> TrainComposition)
{
    //This is a low frequency stats update (only once for every train), so no timer filtering is necessary.
    mZT1Stats->SetTrainParameters(TrainType,TrainComposition);
    return RET_OK;
}

unsigned int CZTPage::SetZT2Data(CZT2ThreadData *Data)
{
    if(Data == 0)
        return RET_ERROR;
    mZT2EquipmentWidget->SetState(Data->mS1,Data->mPPInt,Data->mPPExt);
    mZT2Stats->UpdateStats(Data);

    return RET_OK;
}

unsigned int CZTPage::SetZT2TrainData(int TrainType, QList<qint16> TrainComposition)
{
    //This is a low frequency stats update (only once for every train), so no timer filtering is necessary.
    mZT2Stats->SetTrainParameters(TrainType,TrainComposition);
    return RET_OK;
}

unsigned int CZTPage::SetZT1ActivationState(bool ZT1Activated)
{
    if(ZT1Activated)
	{
	//	mZT1EquipmentWidget->SetActivation(true);
		mZT1Stats->SetLastActivationDateTime();
	}
    else
	{
	//	mZT1EquipmentWidget->SetActivation(false);
	}

	return RET_OK;
}
unsigned int CZTPage::SetZT2ActivationSTate(bool ZT2Activated)
{
    if(ZT2Activated)
	{
//		mZT2EquipmentWidget->SetActivation(true);
		mZT2Stats->SetLastActivationDateTime();
	}
    else
	{
//		mZT2EquipmentWidget->SetActivation(false);
	}
    return RET_OK;
}

unsigned int CZTPage::ResetZT1Stats()
{
	mZT1Stats->Reset();
	return RET_OK;
}

unsigned int CZTPage::ResetZT2Stats()
{
    mZT2Stats->Reset();
    return RET_OK;
}

unsigned int CZTPage::SetEventListPtr(QList<CEvent *> *ListPtr)
{
	mEventsBar->mEventsList = ListPtr;
	return RET_OK;
}

unsigned int CZTPage::UpdateEventsList()
{
	mEventsBar->UpdateEventsList();
	return RET_OK;
}
unsigned int CZTPage::RequestExitPassword()
{
    mExitPasswordPrompt->RequestPassword();
    return RET_OK;
}

void CZTPage::ExitPasswordValid()
{
    mProgramHandle->ProgramExitRequest();
}

void CZTPage::ExitPasswordInvalid()
{
    mExitPasswordPrompt->hide();
}

unsigned int CZTPage::SetZT2Presence(bool IsPresent)
{
    if(IsPresent == true)   //The page is already initialized with ZT2 present
        return RET_OK;

    mZT2Stats->hide();
    mZT2EquipmentWidget->hide();
    mStatusBar->SetZT2Status(SB_ZT_NOT_PRESENT_STATUS);
    mIsZT2Present = false;
    return RET_OK;
}

unsigned int CZTPage::SetModbusPresent(bool IsPresent)
{
    if(IsPresent == true)
    {
        mStatusBar->SetCCModbusState(SB_MODBUS_CONNECTED);
    }
}

void CZTPage::ModbusCCConnected()
{
    mStatusBar->SetCCModbusState(SB_MODBUS_CONNECTED);
}

void CZTPage::ModbusCCDisconnected()
{
    mStatusBar->SetCCModbusState(SB_MODBUS_DISCONNECTED);
}

void CZTPage::ModbusSEIConnected()
{
    mStatusBar->SetSEIModbusState(SB_MODBUS_CONNECTED);
}

void CZTPage::ModbusSEIDisconnected()
{
    mStatusBar->SetSEIModbusState(SB_MODBUS_DISCONNECTED);
}

void CZTPage::ModbusHistorienConnected()
{
    mStatusBar->SetHistorienModbusState(SB_MODBUS_CONNECTED);

}

void CZTPage::ModbusHistorienDisconnected()
{
    mStatusBar->SetHistorienModbusState(SB_MODBUS_DISCONNECTED);
}
