#include "ChaletGui.h"
#include "ui_ChaletGui.h"
#include "CChalet.h"
#include "LoraModuleInterface.h"
#include <QWidget>
#include <QDate>
#include "LoraModuleInterfaceData.h"

CChaletGui::CChaletGui(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CChaletGui)
{


    ui->setupUi(this);

    ui->mDoHarakiriButton->setEnabled(false);
    ui->mLogStartDateEdit->setDate(QDate::currentDate());

    mGetFimwVersionButtonColorTimer = new QTimer;
    mGetFimwVersionButtonColorTimer->setSingleShot(true);
    mGetFimwVersionButtonColorTimer->setInterval(500);

    mGetWifiParamsButtonColorTimer = new QTimer;
    mGetWifiParamsButtonColorTimer->setSingleShot(true);
    mGetWifiParamsButtonColorTimer->setInterval(500);


    connect(ui->mWiFiModuleONBtn,SIGNAL(clicked()),this,SLOT(WiFiONButtonClicked()));
    connect(ui->mWiFiModuleOFFBtn,SIGNAL(clicked(bool)),this,SLOT(WiFiOFFButtonClicked()));
    connect(ui->mInverterRelayOFFBtn,SIGNAL(clicked()),this,SLOT(InverterPowerOFFButtonClicked()));
    connect(ui->mInverterRelayONBtn,SIGNAL(clicked(bool)),this,SLOT(InverterPowerONButtonClicked()));
    connect(ui->mRebootCPUBtn,SIGNAL(clicked(bool)),this,SLOT(RebootCPUButtonClicked()));
    connect(ui->mDoHarakiriButton,SIGNAL(clicked(bool)),this,SLOT(DoHarakiriButtonClicked()));
    connect(ui->mEnableHarakiriChkBx,SIGNAL(clicked(bool)),this,SLOT(EnableHarakiriClicked(bool)));
    connect(ui->mGetChaletLogButton,SIGNAL(clicked(bool)),this,SLOT(GetChaletLogsBtnClicked()));
    connect(ui->mWiFiGetRemoteSettingsBtn,SIGNAL(clicked(bool)),this,SLOT(GetDeviceWiFiParamsButtonClicked(bool)));
    connect(ui->mWiFiSetRemoteSettingsBtn,SIGNAL(clicked(bool)),this,SLOT(SetDeviceWiFiParamsButtonClicked(bool)));
    connect(ui->mGetFirmwareVersionBtn,SIGNAL(clicked(bool)),this,SLOT(GetFirmwareVersionBtnClicked()));
    connect(ui->mStartSyslogShellBtn,SIGNAL(clicked(bool)),this,SLOT(StartSyslogShellBtnClicked()));
    connect(ui->mStartTerminalShellBtn,SIGNAL(clicked(bool)),this,SLOT(StartTerminalShellBtnClicked()));
    connect(mGetFimwVersionButtonColorTimer,SIGNAL(timeout()),this,SLOT(GetFirmwVersionBtnColorTimerExpired()));
    connect(mGetWifiParamsButtonColorTimer,SIGNAL(timeout()),this,SLOT(GetWifiParamsBtnColorTimerExpired()));
    connect(ui->mResetCommStatsBtn,SIGNAL(clicked(bool)),this,SLOT(ResetCommStatsBtnClicked()));
    connect(ui->mGetWifiStatusBtn,SIGNAL(clicked(bool)),this,SLOT(GetModuleWifiStatusBtnClicked()));

    mBatteryPlotWidget = new QCustomPlot(ui->mPlotWidget);
    mBatteryPlotWidget->resize(ui->mPlotWidget->size());

    // create graph and assign data to it:
    mBatteryPlotWidget->addGraph();
    mBatteryPlotWidget->addGraph(mBatteryPlotWidget->xAxis,mBatteryPlotWidget->yAxis2);


    // give the axes some labels:
    mBatteryPlotWidget->xAxis->setLabel("time");
    mBatteryPlotWidget->yAxis->setLabel("Volts");
    mBatteryPlotWidget->yAxis2->setLabel("RSSI (dBm)");
    mBatteryPlotWidget->yAxis2->setVisible(true);

    double now = QDateTime::currentDateTime().toSecsSinceEpoch();
    QSharedPointer<QCPAxisTickerDateTime> dateTicker(new QCPAxisTickerDateTime);
    dateTicker->setDateTimeFormat("hh:mm:ss\ndd MMM");
    mBatteryPlotWidget->xAxis->setTicker(dateTicker);
    mBatteryPlotWidget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);

    QDateTime Now = QDateTime::currentDateTime().toLocalTime();

    QDateTime midnight = Now;
    midnight.setTime(QTime(0,0,0));
    QDateTime eod = Now;
    eod.setTime(QTime(23,59,0));

    //mBatteryPlotWidget->xAxis->setRange(0/*QCPAxisTickerDateTime::dateTimeToKey(midnight)*/,QCPAxisTickerDateTime::dateTimeToKey(eod));
//    mBatteryPlotWidget->xAxis->setRange(now, now+(2*3600));
    mBatteryPlotWidget->xAxis->setRange(midnight.toSecsSinceEpoch(), eod.toSecsSinceEpoch());

    mBatteryPlotWidget->yAxis->setRange(12,15);
    mBatteryPlotWidget->yAxis2->setRange(-255,0.0);
    QList<QCPAxis*> xAxis, yAxis;
    xAxis.append(mBatteryPlotWidget->xAxis);
    yAxis.append(mBatteryPlotWidget->yAxis);
    yAxis.append(mBatteryPlotWidget->yAxis2);
    mBatteryPlotWidget->axisRect()->setRangeDragAxes(xAxis,yAxis);
    mBatteryPlotWidget->axisRect()->setRangeZoomAxes(xAxis,yAxis);
    mBatteryPlotWidget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);

    mBatteryPlotWidget->graph(0)->addData(now,13.5);

    mBatteryPlotWidget->replot();

    mFirmVersionDefaultBtnPal = ui->mGetFirmwareVersionBtn->palette();
    mWifiDefaultBtnPal = ui->mGetFirmwareVersionBtn->palette();

    mChaletLastLostReqCount = 0;



    ui->mWiFiModuleStatusLabel->setText("Unknown");
    ui->mInverterRlyStatusLabel->setText("Unknown");
    ui->mCurrentSensorStateLbl->setText("Current Sensor: Unknown state");
    ui->mBatteryVoltageLabel->setText("Battery Voltage: Unknown");
    ui->mBatterySOCLabel->setText("Battery SOC: Unknown");
    ui->mSolarPanelCurrentLabel->setText("Raw Solar Panel Current: Unknown");
    ui->mSolarPanelCurrentCnvLbl->setText("Solar Panel Current (A): Unknown");
    ui->mLostReqPercentLbl->setText("N/A");
    ui->mTotalRxTxRequestsLbl->setText("Chalet Rx req: ??");
    ui->mChaletTemperatureLbl->setText("Temperature: -100)");

    ui->mChaletWifiSelectionRadioBtn->setChecked(true);

}

CChaletGui::~CChaletGui()
{
    delete ui;
    delete mBatteryPlotWidget;
    delete mGetFimwVersionButtonColorTimer;
    delete mGetWifiParamsButtonColorTimer;
}

int CChaletGui::UpdateChaletStatus(CChaletMainStatus Status)
{
    static bool LastToggle = false;
    QString text;

    int Delta = QDateTime::currentDateTime().toSecsSinceEpoch() - Status.mLastLoraStatus.toSecsSinceEpoch();
    ui->mLasCommRequestReceivedLbl->setText(QString("Last response: %1 | %2 seconds ago...").arg(Status.mLastLoraStatus.toString("yyyy-MM-dd-hh:mm:ss")).arg(Delta));

    if(Status.mIsOnline == false)
    {
        ui->mChaletOnlineStatusLbl->setText("OFFLINE");
        QPalette pal = QPalette(ui->mChaletOnlineStatusLbl->palette());
        pal.setColor(QPalette::WindowText,QColor(Qt::red));
        ui->mChaletOnlineStatusLbl->setPalette(pal);

//        ui->mWiFiModuleStatusLabel->setText("Unknown");
//        ui->mInverterRlyStatusLabel->setText("Unknown");
//        ui->mCurrentSensorStateLbl->setText("Current Sensor: Unknown state");
//        ui->mBatteryVoltageLabel->setText("Battery Voltage: Unknown");
//        ui->mBatterySOCLabel->setText("Battery SOC: Unknown");
//        ui->mSolarPanelCurrentLabel->setText("Raw Solar Panel Current: Unknown");
//        ui->mSolarPanelCurrentCnvLbl->setText("Solar Panel Current (A): Unknown");
//        ui->mLostReqPercentLbl->setText("N/A");
//        ui->mTotalRxTxRequestsLbl->setText("Chalet Rx req: ??");
//        ui->mChaletTemperatureLbl->setText("Temperature: -100)");


        return RET_OK;
    }
    else if(ui->mChaletOnlineStatusLbl->text() == "OFFLINE")
    {
        ui->mChaletOnlineStatusLbl->setText("ONLINE");
        QPalette pal = QPalette(ui->mChaletOnlineStatusLbl->palette());
        pal.setColor(QPalette::WindowText,QColor(Qt::darkGreen));
        ui->mChaletOnlineStatusLbl->setPalette(pal);
    }


    switch(Status.mWiFiModuleStatus)
    {
        case WIFI_CONNECTED_STATE:
        {
            text = "Connected";
            break;
        }
        case WIFI_MODULE_OFF_STATE:
        {
            text = "Module OFF";
            break;
        }
        case WIFI_DISCONNECTED_STATE:
        {
            text = "Disconnected";
            break;
        }
        case WIFI_INIT_ERROR_STATE:
        {
            text = "Init. Error";
            break;
        }
        case WIFI_UNKNOWN_STATE:
        default:
        {
            text = "WiFi: Unknown state";
            break;
        }
    }

    ui->mWiFiModuleStatusLabel->setText(text);

    switch(Status.mInverterRelayStatus)
    {
        case CHALET_POWER_RELAY_OFF_STATE:
        {
            text = "OFF";
            break;
        }
        case CHALET_POWER_RELAY_ON_STATE:
        {
            text = "ON";
            break;
        }
        case CHALET_POWER_RELAY_UNKNOWN_STATE:
        default:
        {
            text = "Unknown";
            break;
        }


    }
    ui->mInverterRlyStatusLabel->setText(text);

    switch(Status.mCurrentSensorStatus)
    {
        case CHALET_CURRENT_SENSOR_DEFECT_STATE:
        {
            text = "Current Sensor: DEFECTIVE";
            break;
        }
        case CHALET_CURRENT_SENSOR_OK_STATE:
        {
            text = "Current Sensor: OK";
            break;
        }
        case CHALET_CURRENT_SENSOR_UNKNOWN_STATE:
        default:
        {
            text = "Current Sensor: Unknown state";
            break;
        }


    }
    ui->mCurrentSensorStateLbl->setText(text);



    QString Voltage = QString("Battery Voltage: %1").arg(Status.mBatteryVoltage);
    ui->mBatteryVoltageLabel->setText(Voltage);

    QString Current = QString("Raw Solar Panel Current: %1").arg(Status.mBatteryCurrent - 2);
    ui->mSolarPanelCurrentLabel->setText(Current);

    float ConvertedCurrent = (float)(Status.mBatteryCurrent - 2) * (3.3/1023); //*0.080645; // 3.3/(1023*0.04) = 0.080645;
    ConvertedCurrent /= 0.08;
    QString CnvCurrent = QString("Solar Panel Current (A): %1").arg(ConvertedCurrent);
    ui->mSolarPanelCurrentCnvLbl->setText(CnvCurrent);



    QString SOC = QString("Battery SOC: %1").arg(Status.mBatterySOC);
    ui->mBatterySOCLabel->setText(SOC);

    QString Percent = QString("Lost Requests: %1%").arg(Status.mLostRequestPercentage,0,'f',2);
    ui->mLostReqPercentLbl->setText(Percent);


    QString ChaletRxCnt = QString("Chalet Rx req: %1, Master Tx cmds: %2, Master lost reqs: %3").arg(Status.mTotalNbChaletRxCmds).arg(Status.mTotalMasterTxCmds).arg(Status.mMasterLostRequestCount);
    ui->mTotalRxTxRequestsLbl->setText(ChaletRxCnt);

    if(mChaletLastLostReqCount != Status.mMasterLostRequestCount)
    {
        QString ChaletLostReqStats = QString("Master --> Chalet: %1\nChalet --> Master: %2").arg((Status.mTotalMasterTxCmds-Status.mTotalNbChaletRxCmds)).arg(Status.mMasterLostRequestCount-(Status.mTotalMasterTxCmds-Status.mTotalNbChaletRxCmds));
        ui->mLostReqsStatsLbl->setText(ChaletLostReqStats);
    }
    mChaletLastLostReqCount = Status.mMasterLostRequestCount;

    if(Status.mStatusToggleBit != LastToggle)
    {
        LastToggle = Status.mStatusToggleBit;

        if(ui->mChaletCommActivityLbl->isEnabled())
        {
            ui->mChaletCommActivityLbl->setEnabled(false);
        }
        else
        {
            ui->mChaletCommActivityLbl->setEnabled(true);
        }

        double CurTime = QDateTime::currentDateTime().toSecsSinceEpoch();
        mBatteryPlotWidget->graph(0)->addData(CurTime,Status.mBatteryVoltage);

        mBatteryPlotWidget->replot();
    }

    QString Temperature = QString("Temperature: %1").arg(Status.mChaletTemperature);
    ui->mChaletTemperatureLbl->setText(Temperature);

    return RET_OK;
}

int CChaletGui::UpdateLoraModuleStatus(CLoraModuleInterfaceStatus Status)
{
    if(ui->mLoraModuleCommActivityLbl->isEnabled())
    {
        ui->mLoraModuleCommActivityLbl->setEnabled(false);
    }
    else
    {
        ui->mLoraModuleCommActivityLbl->setEnabled(true);
    }

    QString ModuleStatusTxt = QString("Ambient RSSI: %1 [%3dBm]\nLast Rx RSSI: %2 [%4dBm]").arg(Status.mModuleAmbientRSSI).arg(Status.mModuleLastRxRSSI).arg(-1*(255-Status.mModuleAmbientRSSI)).arg(-1*(255-Status.mModuleLastRxRSSI));
    ui->mLoraIFModuleStatus->setText(ModuleStatusTxt);

    quint32 Add = 0;

    Add += (quint32)(Status.mIPAddress1 & 0x000000FF);
    Add <<= 8;
    Add += (quint32)(Status.mIPAddress2 & 0x000000FF);
    Add <<= 8;
    Add += (quint32)(Status.mIPAddress3 & 0x000000FF);
    Add <<= 8;
    Add += (quint32)(Status.mIPAddress4 & 0x000000FF);
    QHostAddress IP = QHostAddress(Add);

    QString IPString = QString("Lora Module IP Address:").append(IP.toString());
    ui->mLoraModuleIPAddressLbl->setText(IPString);

    if(Status.mModuleLastRxRSSI > 10)  //filter glitches
    {
        double CurTime = QDateTime::currentDateTime().toSecsSinceEpoch();
        mBatteryPlotWidget->graph(1)->addData(CurTime,-1*(255-Status.mModuleLastRxRSSI));

        mBatteryPlotWidget->replot();
    }

    return RET_OK;
}

int CChaletGui::UpdateChaletLogPlot(QByteArray *Log)
{
    int NbRecords;
    CChaletMainStatus CurData;
    QVector<double> x,y;
    QDataStream Strm(Log,QIODevice::ReadOnly);
    Strm.device()->seek(0);

    Strm >> NbRecords;

    if(NbRecords > 0)
    {
        for(int i = 0; i < NbRecords; i++)
        {
            Strm >> CurData;
            x.append(CurData.mThisStatusDateTime.toSecsSinceEpoch());
            y.append(CurData.mBatteryVoltage);
        }
    }

    if(x.size() == 0 || y.size() == 0)
        return RET_ERROR;

    mBatteryPlotWidget->graph(0)->data().clear();
    mBatteryPlotWidget->graph(0)->setData(x,y);
    mBatteryPlotWidget->xAxis->setRange(x.first(),x.last());
    mBatteryPlotWidget->replot();

    return RET_OK;
}

void CChaletGui::WiFiONButtonClicked()
{
    mProgramHandle->WiFiToggleButtonPressed(true);
}
void CChaletGui::WiFiOFFButtonClicked()
{
    mProgramHandle->WiFiToggleButtonPressed(false);
}
void CChaletGui::InverterPowerONButtonClicked()
{
    mProgramHandle->InverterToggleButtonPressed(true);
}
void CChaletGui::InverterPowerOFFButtonClicked()
{
    mProgramHandle->InverterToggleButtonPressed(false);
}

void CChaletGui::DoHarakiriButtonClicked()
{
    mProgramHandle->DoHarakiriButtonClicked(true);
}

void CChaletGui::RebootCPUButtonClicked()
{
    mProgramHandle->RebootCPUButtonPressed();
}
 void CChaletGui::EnableHarakiriClicked(bool checked)
 {
     if(checked)
     {
         ui->mDoHarakiriButton->setEnabled(true);
     }
     else
     {
         ui->mDoHarakiriButton->setEnabled(false);
     }
 }

 int CChaletGui::ChaletCommActivity()
 {
    if(ui->mChaletCommActivityLbl->isEnabled())
    {
        ui->mChaletCommActivityLbl->setEnabled(false);
    }
    else
    {
        ui->mChaletCommActivityLbl->setEnabled(true);
    }
    return RET_OK;
 }

 void CChaletGui::GetChaletLogsBtnClicked()
 {
    QDate StartDate = ui->mLogStartDateEdit->date();
    if(StartDate > QDate::currentDate())
    {
        QMessageBox::critical(this,"Error","Date is in the future!");
        return;
    }
    mProgramHandle->RequestChaletLogs(StartDate);
 }

 void CChaletGui::GetDeviceWiFiParamsButtonClicked(bool state)
 {
    mProgramHandle->RequestDeviceWifiParams();

 }

 void CChaletGui::SetDeviceWiFiParamsButtonClicked(bool state)
 {
     bool UseDHCP = ui->mDHCPEnableChkBx->isChecked();
     if(mProgramHandle->SetDeviceWifiParams(ui->mWiFiIPAddressEditBx->text(),ui->mWiFiGatewayAddressEditBx->text(),UseDHCP,ui->mWifiAccessPtNameEditBx->text(),ui->mWifiPasswordEditBx->text()) == RET_ERROR)
     {
         QMessageBox::critical(this,"IP error","Invalid IP address");
     }
}
 void CChaletGui::UpdateDeviceWiFiParameters(QHostAddress IP, QHostAddress Gateway, QString APName, QString APPassword, bool UseDHCP)
 {
     ui->mWiFiIPAddressEditBx->setText(IP.toString());
     ui->mWiFiGatewayAddressEditBx->setText(Gateway.toString());
     ui->mWifiAccessPtNameEditBx->setText(APName);
     ui->mWifiPasswordEditBx->setText(APPassword);
     ui->mDHCPEnableChkBx->setChecked(UseDHCP);

     QPalette pal = ui->mWiFiGetRemoteSettingsBtn->palette();
     pal.setColor(QPalette::Button, QColor(Qt::green));
     ui->mWiFiGetRemoteSettingsBtn->setAutoFillBackground(true);
     ui->mWiFiGetRemoteSettingsBtn->setPalette(pal);
     ui->mWiFiGetRemoteSettingsBtn->update();

     mGetWifiParamsButtonColorTimer->start();
 }

 void CChaletGui::GetFirmwareVersionBtnClicked()
 {
    mProgramHandle->RequestFirmwareVersion();
 }

 void CChaletGui::ResetCommStatsBtnClicked()
 {
     mChaletLastLostReqCount = 0;
     QString ChaletLostReqStats = QString("Master --> Chalet: 0\nChalet --> Master: 0");
     ui->mLostReqsStatsLbl->setText(ChaletLostReqStats);
     mProgramHandle->RequestClearCommStats();
 }

 void CChaletGui::UpdateFirmwareVersion(QByteArray Version)
 {
     QString VersionString(Version);
     VersionString.prepend("Firmware version: ");
     ui->mFirmwareVersionLabel->setText(VersionString);

     QPalette pal = ui->mGetFirmwareVersionBtn->palette();
     pal.setColor(QPalette::Button, QColor(Qt::green));
     ui->mGetFirmwareVersionBtn->setAutoFillBackground(true);
     ui->mGetFirmwareVersionBtn->setPalette(pal);
     ui->mGetFirmwareVersionBtn->update();

     mGetFimwVersionButtonColorTimer->start();

 }

 void CChaletGui::UpdateDeviceWifiStatus(char WifiState, QHostAddress IP)
 {
     QString Txt = QString("Module IP Address: %1").arg(IP.toString());
     ui->mModuleIPAddressLbl->setText(Txt);
     mModuleIPAddress = IP;
 }

 void CChaletGui::StartSyslogShellBtnClicked()
 {
     //system("c:\\progra~1\\putty\\putty.exe -load \"0-ChaletDuino_Syslog\"");
//     QProcess Putty;
     //QProcess::startDetached("c:\\progra~1\\putty\\putty.exe -load \"0-ChaletDuino_Syslog\"");

     if(mModuleIPAddress.isNull() || mModuleIPAddress.isBroadcast())
     {
         QProcess::startDetached("c:\\progra~1\\putty\\putty.exe -load \"0-ChaletDuino_Syslog\"");
     }
     else
     {
        QString Proc = QString("c:\\progra~1\\putty\\putty.exe -raw -P 87 %1").arg(mModuleIPAddress.toString());
        QProcess::startDetached(Proc);
     }
 }

 void CChaletGui::StartTerminalShellBtnClicked()
 {
//     system("c:\\program files\\putty\\putty.exe -load \"0-ChaletDuino_Terminal\"");
//     QProcess::startDetached("c:\\progra~1\\putty\\putty.exe -load \"0-ChaletDuino_Terminal\"");
     if(mModuleIPAddress.isNull() || mModuleIPAddress.isBroadcast())
     {
         QProcess::startDetached("c:\\progra~1\\putty\\putty.exe -load \"0-ChaletDuino_Terminal\"");
     }
     else
     {
        QString Proc = QString("c:\\progra~1\\putty\\putty.exe -raw -P 85 %1").arg(mModuleIPAddress.toString());
        QProcess::startDetached(Proc);
     }
 }

 void CChaletGui::GetFirmwVersionBtnColorTimerExpired()
 {
     ui->mGetFirmwareVersionBtn->setAutoFillBackground(true);
     ui->mGetFirmwareVersionBtn->setPalette(mFirmVersionDefaultBtnPal);
     ui->mGetFirmwareVersionBtn->update();
 }

 void CChaletGui::GetWifiParamsBtnColorTimerExpired()
 {
     ui->mWiFiGetRemoteSettingsBtn->setAutoFillBackground(true);
     ui->mWiFiGetRemoteSettingsBtn->setPalette(mFirmVersionDefaultBtnPal);
     ui->mWiFiGetRemoteSettingsBtn->update();
 }

 void CChaletGui::GetModuleWifiStatusBtnClicked()
 {
     ui->mModuleIPAddressLbl->setText("Module IP Address: ");
     mProgramHandle->RequestWifiStatus();
 }

 void CChaletGui::WiFiSettingsSelectionChanged()
 {

 }
