#include "grifosnuform.h"
#include "ui_grifosnuform.h"

#include <QDockWidget>
#include <QHBoxLayout>
#include <QPushButton>
#include <QTimerEvent>
#include <QAction>

#include "ads_workbench.h"

#include "grifoflightsimulator.h"

#include "g346_common.h"

#include "icd_g346.h"
#include "gc_math.h"

using namespace grifo_icd;

class GrifoSNUSimulator::Private
{
public:
  GrifoFlightSimulator& fSim;

  bool wInstalled;

  Private():
      fSim(*new GrifoFlightSimulator),
      wInstalled(false)
  {
  }
};

GrifoSNUSimulator::GrifoSNUSimulator(QObject *parent):
    QObject(parent),
    p_(*new Private)
{
}

void GrifoSNUSimulator::simButtonToggled(bool /*x*/)
{
}

void GrifoSNUSimulator::timerEvent(QTimerEvent * /*evn*/)
{
}

GrifoSNUSimulator::~GrifoSNUSimulator()
{
  delete &p_;
}

void GrifoSNUForm::crsToWaypoint(int w)
{
    static Ads1553Manager& mng=Ads1553Manager::instance();
    static Ads1553MsgQ* msgB6=mng.getMsgObj("B6");
    static Ads1553MsgQ* msgA3=mng.getMsgObj("A3");

    msg_graphic_setting_t* gs=(msg_graphic_setting_t*)msgA3->getBuffer();

    //waypoint_lat_sel_qual_t* wlat;
    //waypoint_lon_code_t* wlon;

    if ((w<0) || (w>2))
        return;

#if 0
    switch (w)
    {
        case 0:
            wlat=&(gs->waypoint_01_lat_sel_qual);
            wlon=&(gs->waypoint_01_lon_code);
            break;
        case 1:
            wlat=&(gs->waypoint_02_lat_sel_qual);
            wlon=&(gs->waypoint_02_lon_code);
            break;
        case 2:
            wlat=&(gs->waypoint_03_lat_sel_qual);
            wlon=&(gs->waypoint_03_lon_code);
            break;
    }


    waypoint_lat_sel_qual_t tlat=*wlat;
    waypoint_lon_code_t tlon=*wlon;
#endif
    waypoint_lat_sel_qual_t& tlat=gs->waypoints.wp[w].waypoint_lat_sel_qual;
    waypoint_lon_code_t& tlon=gs->waypoints.wp[w].waypoint_lon_code;

    msg_settings_tellback_t* b6=(msg_settings_tellback_t*)msgB6->getBuffer();

    //long crsLat = msgB6->data32(ICD_WOFFSETOF(msg_settings_tellback_t, crs_lat));
    //long crsLon = msgB6->data32(ICD_WOFFSETOF(msg_settings_tellback_t, crs_long));

    //msgA3->setData32NoSignal(ICD_WOFFSETOF(msg_graphic_setting_t, waypoint_01_lat_sel_qual), crsLat);
    //msgA3->setData32NoSignal(ICD_WOFFSETOF(msg_graphic_setting_t, waypoint_01_lon_code), crsLon);
    //int32_t ilat=crsLat*ICD1553_GEOPOS_RAD_LSB/ICD1553_SEMICIRCLE2_LSB;
    //int32_t ilon=crsLon*ICD1553_GEOPOS_RAD_LSB/ICD1553_SEMICIRCLE2_LSB;

    float lat=b6->crs_lat.get();
    float lon=b6->crs_long.get();

    //int32_t ilat = lat/ICD1553_SEMICIRCLE2_LSB;
    //int32_t ilon = lon/ICD1553_SEMICIRCLE2_LSB;

    tlat.waypoint_lat.set(lat);
    tlon.waypoint_lon.set(lon);

   /* msgA3->setData32NoSignal(
                  w*4+ICD_WOFFSETOF(msg_graphic_setting_t, waypoint_01_lat_sel_qual),
                  tlat.raw);
    msgA3->setData32NoSignal(
                  w*4+ICD_WOFFSETOF(msg_graphic_setting_t, waypoint_01_lon_code),
                  tlon.raw);*/
#if 1
    msgA3->setDataNoSignal(
              ICD_WOFFSETOF(msg_graphic_setting_t, waypoints.wp[w].waypoint_lat_sel_qual),
              *reinterpret_cast<uint32_t*>(&tlat.raw[0]));
    msgA3->setDataNoSignal(
              1+ICD_WOFFSETOF(msg_graphic_setting_t, waypoints.wp[w].waypoint_lat_sel_qual),
              *reinterpret_cast<uint32_t*>(&tlat.raw[1]));
    msgA3->setDataNoSignal(
              ICD_WOFFSETOF(msg_graphic_setting_t, waypoints.wp[w].waypoint_lon_code),
              *reinterpret_cast<uint32_t*>(&tlon.raw[0]));
    msgA3->setDataNoSignal(
              1+ICD_WOFFSETOF(msg_graphic_setting_t, waypoints.wp[w].waypoint_lon_code),
              *reinterpret_cast<uint32_t*>(&tlon.raw[1]));
#endif
#if 0
    msgA3->setData32NoSignal(
              ICD_WOFFSETOF(msg_graphic_setting_t, waypoints.wp[w].waypoint_lat_sel_qual),
              *reinterpret_cast<uint32_t*>(&tlat.raw[0]));
    msgA3->setData32NoSignal(
              ICD_WOFFSETOF(msg_graphic_setting_t, waypoints.wp[w].waypoint_lon_code),
              *reinterpret_cast<uint32_t*>(&tlon.raw[0]));
#endif

#if 0
    switch (w)
    {
        case 0:
            msgA3->setData32NoSignal(
                      ICD_WOFFSETOF(msg_graphic_setting_t, waypoint_01_lat_sel_qual),
                      tlat.raw);
            msgA3->setData32NoSignal(
                      ICD_WOFFSETOF(msg_graphic_setting_t, waypoint_01_lon_code),
                      tlon.raw);
            break;
        case 1:
            msgA3->setData32NoSignal(
                  ICD_WOFFSETOF(msg_graphic_setting_t, waypoint_02_lat_sel_qual),
                  tlat.raw);
            msgA3->setData32NoSignal(
                  ICD_WOFFSETOF(msg_graphic_setting_t, waypoint_02_lon_code),
                  tlon.raw);
            break;
        case 2:
            msgA3->setData32NoSignal(
                  ICD_WOFFSETOF(msg_graphic_setting_t, waypoint_03_lat_sel_qual),
                  tlat.raw);
            msgA3->setData32NoSignal(
                  ICD_WOFFSETOF(msg_graphic_setting_t, waypoint_03_lon_code),
                  tlon.raw);
            break;
    }
#endif

}

GrifoSNUForm::GrifoSNUForm(QWidget *parent) :
    QScrollArea(parent),
    ui(new Ui::GrifoSNUForm),
    sim(this)
{
    ui->setupUi(this);

    ui->tbToWaypoint->addAction(ui->actionToWaypoint_1);
    ui->tbToWaypoint->addAction(ui->actionToWaypoint_2);
    ui->tbToWaypoint->addAction(ui->actionToWaypoint_3);
    ui->actionToWaypoint_1->setData(0);
    ui->actionToWaypoint_2->setData(1);
    ui->actionToWaypoint_3->setData(2);

    ui->comboBoxSynchMode->addItem("Synch Without DW");
    ui->comboBoxSynchMode->addItem("Synch With DW");

    connect(ui->cbSmart, &QCheckBox::stateChanged, this,
            [this](int state)
    {
        grifo_sim_enable.inu_smart=state;
    });

    connect(ui->cbLinkSpoiCursor, &QCheckBox::stateChanged, this,
            [this](int state)
    {
        grifo_sim_enable.link_spoi_to_cursor=state==Qt::Checked;
#if 0
        if (state)
        {
            ui->cbLatLonSim->setEnabled(true);
            if (ui->cbLatLonSim->checkState()!=Qt::Unchecked)
                grifo_sim_enable.inu_smart=2;
            else
                grifo_sim_enable.inu_smart=1;
        }
        else
            grifo_sim_enable.inu_smart=0;
#endif
    });

    connect(ui->cbLatLonSim, &QCheckBox::stateChanged, this,
            [this](int state)
    {
        if (ui->cbSmart->checkState()!=Qt::Unchecked)
        {
                grifo_sim_enable.inu_smart=state ? 2 : 1;
        }
    });

    connect(ui->tbCrsToSpoi, &QToolButton::clicked, this,
            [this]()
    {
        //copy lat/lon cursor to lat/lon spoi
        static Ads1553Manager& mng=Ads1553Manager::instance();
        static Ads1553MsgQ* msgB6=mng.getMsgObj("B6");
        static Ads1553MsgQ* msgA4=mng.getMsgObj("A4");

        {
            long crslat = msgB6->data32(ICD_WOFFSETOF(msg_settings_tellback_t, crs_lat));
            long crslon = msgB6->data32(ICD_WOFFSETOF(msg_settings_tellback_t, crs_long));
            msgA4->setData32NoSignal(ICD_WOFFSETOF(msg_nav_data_and_cursor_t, spoi_lat), crslat);
            msgA4->setData32NoSignal(ICD_WOFFSETOF(msg_nav_data_and_cursor_t, spoi_lon), crslon);


        }
        //msgA4->setData32NoSignal(ICD_WOFFSETOF(msg_nav_data_and_cursor_t, spoi_lat), msgB6->data32(ICD_WOFFSETOF(msg_settings_tellback_t, crs_lat)));
        //msgA4->setData32NoSignal(ICD_WOFFSETOF(msg_nav_data_and_cursor_t, spoi_lon), msgB6->data32(ICD_WOFFSETOF(msg_settings_tellback_t, crs_long)));

    });

    connect(ui->actionToWaypoint_1, &QAction::triggered, this,
            [this]()
    {
        crsToWaypoint(0);
    });
    connect(ui->actionToWaypoint_2, &QAction::triggered, this,
            [this]()
    {
        crsToWaypoint(1);
    });
    connect(ui->actionToWaypoint_3, &QAction::triggered, this,
            [this]()
    {
        crsToWaypoint(2);
    });


}

GrifoSNUForm::~GrifoSNUForm()
{
    delete ui;
}

void GrifoSNUForm::on_pbFlySim_clicked()
{
  if (!sim.p_.wInstalled)
    IAdsWorkBench::instance().mainWindow().addDockWidget(Qt::RightDockWidgetArea, &sim.p_.fSim);
  sim.p_.fSim.show();
}

void GrifoSNUForm::on_cbStopTimetag_clicked(bool checked)
{
  grifo_sim_enable.a5_inhibit_timetag=grifo_sim_enable.a4_inhibit_timetag=checked;
}

bool GrifoSNUForm::generateSyncTimetag() const
{
  return !ui->cbStopSyncTimetag->isChecked();
}

void GrifoSNUForm::postInit()
{
    ui->cbSmart->setCheckState(grifo_sim_enable.inu_smart ? Qt::Checked : Qt::Unchecked); //static_cast<Qt::CheckState>(grifo_sim_enable.inu_smart));
    ui->cbLatLonSim->setCheckState(grifo_sim_enable.inu_smart>1 ? Qt::Checked : Qt::Unchecked); //static_cast<Qt::CheckState>(grifo_sim_enable.inu_smart));
    ui->cbLinkSpoiCursor->setChecked(grifo_sim_enable.link_spoi_to_cursor);
}

void GrifoSNUForm::on_tbCrsToSpoi_clicked()
{

}

void GrifoSNUForm::on_wanderAngle_valueChanged(double arg1)
{
    grifo_sim_enable.wander_angle=gc_math::deg_to_rad(arg1);
}

void GrifoSNUForm::on_magneticVariation_valueChanged(double arg1)
{
    grifo_sim_enable.magnetic_variation=gc_math::deg_to_rad(arg1);
}

void GrifoSNUForm::on_sp_ads_A5_rate_yaw_valueChanged(double arg1)
{
    grifo_sim_enable.ptaz_variation=gc_math::deg_to_rad(arg1);
}

void GrifoSNUForm::on_navDrift_valueChanged(double arg1)
{
    grifo_sim_enable.nav_drift=gc_math::deg_to_rad(arg1);
}

void GrifoSNUForm::on_simpleSimEnable_toggled(bool checked)
{
    grifo_sim_enable.simple_sim=checked ? 1 : 0;
}

void GrifoSNUForm::on_kTTPtaz_valueChanged(int arg1)
{
    grifo_sim_enable.ttptaz_offset=arg1;
}

void GrifoSNUForm::on_kTT_valueChanged(int arg1)
{
    grifo_sim_enable.tt_offset=arg1;
}

void GrifoSNUForm::on_kTTPitch_valueChanged(int arg1)
{
    grifo_sim_enable.ttpitch_offset=arg1;
}

void GrifoSNUForm::on_kTTRoll_valueChanged(int arg1)
{
    grifo_sim_enable.ttroll_offset=arg1;
}
