
#include "g346_common.h"

#include "g346_a1a2.h"

#include "icd_g346.h"
using namespace grifo_icd;

void GrifoMsg_A1B6::startProtection()
{
    dSymbInt.setFromUser(127);
}

GrifoMsg_A1B6::GrifoMsg_A1B6():
      dIfGain("if_gain"),
      dSymbInt("video_intensity"),
      dChSel("channel"),
      dCrsTbX("tb_crs_x"),
      dCrsTbY("tb_crs_y"),
      dCrsTbRange("tb_crs_range"),
      dCrsTbAzimuth("tb_crs_azimuth"),
      dCrsTbLat("tb_crs_lat"),
      dCrsTbLon("tb_crs_lon"),
      dTimeMark("time_mark"),
      dParamId("PARAM_ID"),
      dCodedParamId("CODED_PARAM_ID")


{
  Ads1553MsgQ* a1=Ads1553Manager::instance().getMsgObj("A1");
  Ads1553MsgQ* b6=Ads1553Manager::instance().getMsgObj("B6");

  {
      GRIFO_ADS_MAP(dRadarFail, "rdr_fail", msg_settings_tellback_t, health_status, radar_fails_status_field_t, *b6);
      GRIFO_ADS_MAP(dAntennaFail, "and_fail", msg_settings_tellback_t, health_status, servoloop_status_t, *b6);
      GRIFO_ADS_MAP(dPpsFail, "pps_fail", msg_settings_tellback_t, health_status, trasmitter_status_t, *b6);
      GRIFO_ADS_MAP(dLcuFail, "lcu_fail", msg_settings_tellback_t, health_status, pedestal_status_t, *b6);
      GRIFO_ADS_MAP(dRepFail, "px_fail", msg_settings_tellback_t, health_status, processor_status_t, *b6);
      GRIFO_ADS_MAP(dAesaFail, "aesa_fail", msg_settings_tellback_t, health_status, servoloop_status_t, *b6);

      GRIFO_ADS_MAP(dRepOvertemp, "rep_overt", msg_settings_tellback_t, health_status, processor_over_temperature_alarm_field_t, *b6);
      GRIFO_ADS_MAP(dPpsOvertemp, "pps_overt", msg_settings_tellback_t, health_status, transmitter_over_temperature_alarm_field_t, *b6);
      GRIFO_ADS_MAP(dAntOvertemp, "ant_overt", msg_settings_tellback_t, health_status, servoloop_over_temperature_alarm_field_t, *b6);
      GRIFO_ADS_MAP(dLcuOvertemp, "lcu_overt", msg_settings_tellback_t, health_status, pressurization_status_field_t, *b6);
  }

  GRIFO_ADS_MAP(dTimeMark, "time_mark", msg_rdr_settings_and_parameters_t, date_of_mission, mission_time_mark_field_t, *a1);
  actTimeMark.setObjectName("act_TimeMark");
  actTimeMark.attachTo(&dTimeMark);
  actTimeMark.setActionValue(0, 1);

  GRIFO_ADS_MAP(dTgtHistory, "tgt_history", msg_rdr_settings_and_parameters_t, settings, tgt_history_level_field_t, *a1);
  GRIFO_ADS_MAP(dTgtHistoryTB, "tgt_history_tb", msg_settings_tellback_t, settings, tgt_history_level_field_t, *b6);

  GRIFO_ADS_MAP(dAltBlock, "alt_block", msg_rdr_settings_and_parameters_t, settings, altitude_block_field_t, *a1);
  GRIFO_ADS_MAP(dAltBlockTB, "alt_block_tb", msg_settings_tellback_t, settings, altitude_block_field_t, *b6);

  //GRIFO_ADS_MAP(dTgtHistoryTB, "tgt_historyTB", msg_rdr_settings_and_parameters_t, rdr_settings_t, tgt_history_level_field_t, *b6);

  dSymbInt.attachToMsg(a1, ICD_WOFFSETOF(msg_rdr_settings_and_parameters_t, settings));
  dSymbInt.setFormat(symb_intensity_field_t::start_bit, symb_intensity_field_t::set_mask);

  dSymbIntTB.setDataName("video_intensity_tb");
  dSymbIntTB.attachToMsg(b6, ICD_WOFFSETOF(msg_rdr_settings_and_parameters_t, settings));
  dSymbIntTB.setFormat(symb_intensity_field_t::start_bit, symb_intensity_field_t::set_mask);

  dIfGain.attachToMsg(a1, ICD_WOFFSETOF(msg_rdr_settings_and_parameters_t, gains_and_chgrp));
  dIfGain.setFormat(if_gain_field_t::start_bit, if_gain_field_t::set_mask);
  dIfGain.setRange(0, 127);
  dIfGainTB.setDataName("if_gain_tb");
  dIfGainTB.attachToMsg(b6, ICD_WOFFSETOF(msg_rdr_settings_and_parameters_t, gains_and_chgrp));
  dIfGainTB.setFormat(if_gain_field_t::start_bit, if_gain_field_t::set_mask);


  //dChSel.attachToMsg(a1, 1);
  //dChSel.setFormat(0, 0xFF);
  //dChSel.setRange(0, 60);


  GRIFO_ADS_MAP(dChSel, "channel", msg_rdr_settings_and_parameters_t, frequency, frq_channel_field_t, *a1);

  for(int i=0; i<num_of_groups; ++i)
  {
    QString tmp(QString("ch_grp_%1").arg(i+1));
    dChGrp[i].setDataName(tmp);
    dChGrp[i].attachToMsg(a1, 1);
    dChGrp[i].setFormat(13-i, 1);

    tmp=QString("ch_grp_tb_%1").arg(i+1);
    dChGrpTB[i].setDataName(tmp);
    dChGrpTB[i].attachToMsg(b6, 1);
    dChGrpTB[i].setFormat(13-i, 1);

  }

  GRIFO_ADS_MAP(dParamId, "PARAM_ID", msg_rdr_settings_and_parameters_t, param_id, param_num_field_t, *a1);
  GRIFO_ADS_MAP(dParamEnable, "PARAM_TRANSF", msg_rdr_settings_and_parameters_t, param_id, param_enable_field_t, *a1);
  GRIFO_ADS_MAP(dParamTxRx, "PARAM_TXRX", msg_rdr_settings_and_parameters_t, param_id, param_tx_field_t, *a1);
  GRIFO_ADS_MAP(dParamValue, "param_value", msg_rdr_settings_and_parameters_t, param_value_2, param_int_field_t, *a1);

  GRIFO_ADS_MAP(dParamIdTB, "PARAM_ID_TB", msg_settings_tellback_t, param_id, param_num_field_t, *b6);
  GRIFO_ADS_MAP(dParamEnableTB, "PARAM_TRANSF_TB", msg_settings_tellback_t, param_id, param_enable_field_t, *b6);
  GRIFO_ADS_MAP(dParamTxRxTB, "PARAM_TXRX_TB", msg_settings_tellback_t, param_id, param_tx_field_t, *b6);
  GRIFO_ADS_MAP(dParamValueTB, "PARAM_VALUE_TB", msg_settings_tellback_t, param_value_2, param_int_field_t, *b6);


  actParamTransf.setObjectName("act_ParamTransf");
  actParamTransf.attachTo(&dParamEnable);
  actParamTransf.setActionValue(icd1553::PAR_TRANSF_ACTIVE, icd1553::PAR_TRANSF_NOT_ACTIVE, 2);

  //GRIFO_ADS_MAP(dCodedParamId, "CODED_PARAM_ID", msg_rdr_settings_and_parameters_t, param_id, param_num_field_t, *a1);

  GRIFO_ADS_MAP_SCALED(dAzCentreTB, "tb_az_centre", msg_settings_tellback_t, az_scan_centre, semicircle_t, *b6, GC_K_RAD_TO_DEG);
  GRIFO_ADS_MAP_SCALED(dElCentreTB, "tb_el_centre", msg_settings_tellback_t, el_scan_centre, semicircle_t, *b6, GC_K_RAD_TO_DEG);

  GRIFO_ADS_MAP(dBeaconCodeTB, "beacon_code_tb", msg_settings_tellback_t, beacon, becon_code_field_t, *b6);
  GRIFO_ADS_MAP(dBeaconDelayTB, "beacon_delay_tb", msg_settings_tellback_t, beacon, becon_delay_field_t, *b6);

  GRIFO_ADS_MAP(dFreqAgility, "FREQ_AGILITY", msg_rdr_settings_and_parameters_t, frequency, frq_agility_field_t, *a1);
  GRIFO_ADS_MAP(dFreqAgilityTb, "FREQ_AGILITY_TB", msg_rdr_settings_and_parameters_t, frequency, frq_agility_field_t, *b6);

  GRIFO_ADS_MAP(dChSelTb, "CHANNEL_TB", msg_rdr_settings_and_parameters_t, frequency, frq_channel_field_t, *b6);

  GRIFO_ADS_MAP(dPrfLookup, "PRF_LOOKUP", msg_rdr_settings_and_parameters_t, settings, prf_lookup_selection_field_t, *a1);
  GRIFO_ADS_MAP(dPrfLookupTb, "PRF_LOOKUP_TB", msg_rdr_settings_and_parameters_t, settings, prf_lookup_selection_field_t, *b6);

  GRIFO_ADS_MAP(dLprfThreshold, "LPRF_THRESHOLD", msg_rdr_settings_and_parameters_t, frequency, lprf_threshold_high_field_t, *a1);
  GRIFO_ADS_MAP(dLprfThresholdTb, "LPRF_THRESHOLD_TB", msg_rdr_settings_and_parameters_t, frequency, lprf_threshold_high_field_t, *b6);

  GRIFO_ADS_MAP(dGndTgtRejRadVel, "GND_TGT_REJ_RAD_VEL", msg_rdr_settings_and_parameters_t, settings, ground_reject_vel_high_field_t, *a1);
  GRIFO_ADS_MAP(dMinDetGndTgtRadVel, "MIN_DET_GND_TGT_RAD_VEL", msg_rdr_settings_and_parameters_t, settings, min_dectect_ground_radial_vel_high_field_t, *a1);

  GRIFO_ADS_MAP(dAleBlanking, "ALE_BLANKING", msg_rdr_settings_and_parameters_t, settings, ale_blanking_disable_field_t, *a1);

  GRIFO_ADS_MAP(dMovingTargetGain, "moving_target_gain", msg_rdr_settings_and_parameters_t, gains_and_chgrp, moving_target_gain_field_t, *a1);
  GRIFO_ADS_MAP(dMovingTargetGainTb, "moving_target_gain_tb", msg_settings_tellback_t, gains_and_chgrp, moving_target_gain_field_t, *b6);

  GRIFO_ADS_MAP(dFreqGroupSel, "FREQ_GROUPING_SELECTION", msg_rdr_settings_and_parameters_t, gains_and_chgrp, frequency_grouping_field_t, *a1);
  GRIFO_ADS_MAP(dFreqGroupSelTb, "FREQ_GROUPING_SELECTION_TB", msg_rdr_settings_and_parameters_t, gains_and_chgrp, frequency_grouping_field_t, *b6);

  GRIFO_ADS_MAP(dWaveform, "WAVE_INTER_SEL", msg_rdr_settings_and_parameters_t, frequency, frq_waveform_interleave_field_t, *a1);
  GRIFO_ADS_MAP(dWaveformTb, "WAVE_INTER_SEL_TB", msg_rdr_settings_and_parameters_t, frequency, frq_waveform_interleave_field_t, *b6);

  GRIFO_ADS_MAP(dAcIndentifier, "AC_IDENTIFIER", msg_rdr_settings_and_parameters_t, ac_id, ac_identifier_t, *a1);


  dCrsTbX.setFormat(crs_pixel_pos_field_t::start_bit, crs_pixel_pos_field_t::set_mask);
  dCrsTbX.attachToMsg(b6, ICD_WOFFSETOF(msg_settings_tellback_t, crs_x));

  dCrsTbY.setFormat(crs_pixel_pos_field_t::start_bit, crs_pixel_pos_field_t::set_mask);
  dCrsTbY.attachToMsg(b6, ICD_WOFFSETOF(msg_settings_tellback_t, crs_y));

  GRIFO_ADS_MAP_SCALED(dCrsTbRange, "TB_CRS_RANGE", msg_settings_tellback_t, crs_range, crs_slave_range_t, *b6, GC_K_METERS_TO_FEETS);
  GRIFO_ADS_MAP_SCALED(dCrsTbAzimuth, "TB_CRS_AZIMUTH", msg_settings_tellback_t, crs_azimuth, semicircle_t, *b6, GC_K_RAD_TO_DEG);
  GRIFO_ADS_MAP_SCALED(dCrsTbLat, "TB_CRS_LAT", msg_settings_tellback_t, crs_lat, latlong_t, *b6, GC_K_RAD_TO_DEG);
  GRIFO_ADS_MAP_SCALED(dCrsTbLon, "TB_CRS_LON", msg_settings_tellback_t, crs_long, latlong_t, *b6, GC_K_RAD_TO_DEG);

  GRIFO_ADS_MAP(dSarEnableStatus, "tb_sar_enabled", msg_settings_tellback_t, crs_x, normal_sar_enabled_selector_tellback_field_t, *b6);

  dSymbInt.setFromUser(127);
  dIfGain.setFromUser(127);

  dAltBlock.setFromUser(McsG346AltBlock::NORMAL);
}

void GrifoMsg_A1B6::sendRawParamater(int id, unsigned int value)
{
    if (id>=0)
    {
        dParamTxRx.setFromUser(0);
        dParamId.setFromUser(id);
        dParamValue.setFromUser((int)value);
        dParamEnable.setFromUser(icd1553::PAR_TRANSF_ACTIVE);
    }
    else
        dParamEnable.setFromUser(icd1553::PAR_TRANSF_NOT_ACTIVE);
}

void GrifoMsg_A1B6::b6_rdr_status_sync_message_routine(const void* data)
{
    //GrifoBiteForm& bf=GrifoBiteForm::instance();
    GrifoBiteForm::setAsynchHealthStatus(data);
}

void GrifoMsg_A1B6::b6_rdr_status_async_message_routine(Ads1553MsgQ *msg)
{
  {
      GrifoBiteForm& bf=GrifoBiteForm::instance();


      const msg_settings_tellback_t& sts=*reinterpret_cast<const msg_settings_tellback_t*>(msg->getBuffer());

      bf.setHealthStatus(sts.health_status.raw);
  }

  if (!grifo_sim_enable.rdr)
    return;

  //Ads1553MsgQ& a1=*Ads1553Manager::instance().getMsgObj("A1");
  Ads1553MsgQ& a4=*Ads1553Manager::instance().getMsgObj("A4");
  Ads1553MsgQ& b6=*msg; //*Ads1553Manager::instance().getMsgObj("B6");

  const msg_nav_data_and_cursor_t& nav=*reinterpret_cast<const msg_nav_data_and_cursor_t*>(a4.getBuffer());

  static msg_settings_tellback_t stb;
  bool write_it=false;

#if 0
  if (stb.spare[1]!=a1.data(1))
  {
    write_it=true;
    stb.spare[1]=a1.data(1);
  }
#endif


  if (nav.validity_and_slew.ant_slew_valid.get())
  {
    stb.el_scan_centre.set_raw(nav.el_antenna_demand.get_raw());
    write_it=true;
  }

  if (nav.validity_and_slew.crs_rate_invalid.get()) //crs_rate_valid.get())
  {

    int x=stb.crs_x.pos.get();
    int y=stb.crs_y.pos.get();

    double rx=nav.acq_crs_x.rate.get();
    double ry=nav.acq_crs_y.rate.get();

    rx*=0.040;
    ry*=0.040;

    x+=rx;
    y+=ry;

    if (x<0)
      x=0;
    else if (x>575)
      x=575;
    if (y<0)
      y=0;
    else if (y>575)
      y=575;
    stb.crs_x.pos.set(x);
    stb.crs_y.pos.set(y);
    write_it=true;
  }

  if (write_it)
  {
     avb_1553_data_buffer_t* raw=reinterpret_cast<avb_1553_data_buffer_t*>(&stb);
     Ads1553Manager::instance().writeDeviceBuffer(b6, *raw); //*(avb_1553_data_buffer_t*)(&stb));
  }

}


class ExpectedTransitionCheck: public Ads1553MessageCheck
{
public:
  msg_rdr_operation_command_t prev;
  ExpectedTransitionCheck()
  {
    info.name="EXPTRANS";
    info.description="Expected Transition";

    expected=false;
    memset(&prev, 0, sizeof prev);
  }
  void execute(avb_1553_mon_decoded_t &decoded)
  {
    msg_rdr_operation_command_t* msg=reinterpret_cast<msg_rdr_operation_command_t*>(&decoded.data[0]);

    if (msg->rdr_mode_command.raw!=prev.rdr_mode_command.raw)
    {
      if ((msg->rdr_mode_command.master_mode.get()!=prev.rdr_mode_command.master_mode.get()) ||
          ((msg->rdr_mode_command.des_ctrl.get()!=NOT_VALID) && (prev.rdr_mode_command.des_ctrl.get()==NOT_VALID)))

      {
        if (expected)
        {
          ++info.fails;
          info.lastFailReason="not served transition";
        }
        expected=true;
        info.delayTime=decoded.timetag;
        ++info.checks;
        updated(*this);
      }
      prev.rdr_mode_command.raw=msg->rdr_mode_command.raw;
    }

  }

  bool expected;
};

class TransitionCheck: public Ads1553MessageCheck
{
public:
  TransitionCheck(ExpectedTransitionCheck& exp_):
      exp(exp_)
  {
    info.name="TRANSITION";
    info.description="Transition Time & delay";
    old_t=false;
  }
  void execute(avb_1553_mon_decoded_t &decoded)
  {
    msg_rdr_status_tellback_t* msg=reinterpret_cast<msg_rdr_status_tellback_t*>(&decoded.data[0]);

    if (!old_t)
    {
      if (msg->mode.transition_status.get())
      {
        start_time=decoded.timetag;
        if (exp.expected)
        {
          exp.expected=false;
          info.delayTime=start_time-exp.delayTime();
          if (info.delayTime>80000)
          {
            ++info.fails;
            info.lastFailReason="too late";
          }
        }
        old_t=true;
      }
    }
    else
    {
      if (!msg->mode.transition_status.get())
      {
        info.durationTime=decoded.timetag-start_time;
        ++info.checks;
        if (info.durationTime>350000)
        {
          ++info.fails;
          info.lastFailReason="too long";
        }
        old_t=false;
        updated(*this);
      }
    }
  }

  bool old_t;
  unsigned long start_time;

  ExpectedTransitionCheck& exp;
};


class ConcreteActSmartLockonBegin: public AdsDataAction
{
public:
  ConcreteActSmartLockonBegin(GrifoMsg_A2B7& cx_):
    AdsDataAction(0, "ACT_SMARTLOCK_BEGIN"),
    cx(cx_)
  {
  }

  virtual void execute(bool /*active=true*/)
  {
    if (cx.dModeTB.getValue()==RWS)
    {
      if (cx.dLockSts.getValue()==DS_SAM)
      {
        //Set cursor DTT = true
      }
    }
    else if (cx.dModeTB.getValue()==VS)
    {
      cx.dSpot.setFromUser(true);
    }
  }
  GrifoMsg_A2B7& cx;
};

class ConcreteActSmartLockonEnd: public AdsDataAction
{
public:
  ConcreteActSmartLockonEnd(GrifoMsg_A2B7& cx_):
    AdsDataAction(0, "ACT_SMARTLOCK_END"),
    cx(cx_)
  {
  }

  virtual void execute(bool /*active=true*/)
  {
    if (cx.dModeTB.getValue()==RWS)
    {
      if (cx.dLockSts.getValue()==DS_SAM)
      {
        //Set cursor DTT = false
      }
      cx.actLockon.execute();
    }
    else if (cx.dModeTB.getValue()==VS)
    {
      cx.actLockon.execute();
      cx.dSpot.setFromUser(false);
    }
  }
  GrifoMsg_A2B7& cx;
};

//concreteActSmartLockonEnd=ConcreteActSmartLockonEnd(msg, msgTB);

void GrifoMsg_A2B7::startProtection()
{
    dSilence.setFromUser(1);
    dStby.setFromUser(1);
}

GrifoMsg_A2B7::GrifoMsg_A2B7():
    //dStby("stby"),
    dSilence("silence"),
    dMode("rdr_mode"),
    dLockon("des_ctrl"),
    dLockSts("lock_sts"),
    dRangeScale("range_scale"),
    dRwsSub("rws_sub_mode"),
    dBars("bars"),
    dWidth("width"),
    dModeTB("mode_tb"),
    dRadiation("rf_status"),
    dEmergency("emergency"),
    dEmergencyTB("emergency_tb"),    
    chkExpTrans(*new ExpectedTransitionCheck),
    chkTransition(*new TransitionCheck(chkExpTrans))
{
  Ads1553MsgQ* a2=Ads1553Manager::instance().getMsgObj("A2");
  Ads1553MsgQ* a1=Ads1553Manager::instance().getMsgObj("A1");
  Ads1553MsgQ* b7=Ads1553Manager::instance().getMsgObj("B7");

  //data_map<msg_rdr_operation_command_t, stby_field_t>(dStby, *msg);
  GRIFO_ADS_MAP(dStby, "stby", msg_rdr_operation_command_t, rdr_mode_command, stby_field_t, *a2);
  GRIFO_ADS_MAP(dStbyTB,"stby_tb", rdr_mode_tellback_t, stby_sts, stby_field_t, *b7);

  GRIFO_ADS_MAP(dSarCrsFeasibility,"sar_crs_tb", msg_rdr_status_tellback_t, param2, sar_feasibility_for_cursor_field_t, *b7);
  GRIFO_ADS_MAP(dSarSpoiFeasibility,"sar_spoi_tb", msg_rdr_status_tellback_t, param2, sar_feasibility_for_spoi_field_t, *b7);

  GRIFO_ADS_MAP(dFreeze, "freeze", msg_rdr_operation_command_t, rdr_mode_command, freeze_field_t, *a2);
  GRIFO_ADS_MAP(dFreezeTB,"freeze_tb", rdr_mode_tellback_t, stby_sts, freeze_field_t, *b7);

  GRIFO_ADS_MAP(dIBit, "IBIT", msg_rdr_operation_command_t, rdr_mode_command, ibit_request_field_t, *a2);
  GRIFO_ADS_MAP(dIBitTB,"IBIT_TB", rdr_mode_tellback_t, stby_sts, ibit_request_field_t, *b7);

  //dStby.setFormat(stby_field_t::start_bit, stby_field_t::set_mask);
  //dStby.attachToMsg(msg, ICD_WOFFSETOF(msg_rdr_operation_command_t, rdr_mode_command));

  GRIFO_ADS_MAP(dExpand,"EXPAND", msg_rdr_operation_command_t, param1, expand_field_t, *a2);
  GRIFO_ADS_MAP(dExpandTB,"EXPAND_TB", msg_rdr_status_tellback_t, param1, expand_field_t, *b7);

  dSilence.setFormat(silence_field_t::start_bit, silence_field_t::set_mask);
  dSilence.attachToMsg(a2, ICD_WOFFSETOF(msg_rdr_operation_command_t, rdr_mode_command));

  dMode.setFormat(rdr_mode_field_t::start_bit, rdr_mode_field_t::set_mask);
  dMode.attachToMsg(a2, ICD_WOFFSETOF(msg_rdr_operation_command_t, rdr_mode_command));

  dModeTB.setFormat(rdr_mode_field_t::start_bit, rdr_mode_field_t::set_mask);
  dModeTB.attachToMsg(b7, ICD_WOFFSETOF(msg_rdr_status_tellback_t, mode));

  dLockon.setFormat(des_control_field_t::start_bit, des_control_field_t::set_mask);
  dLockon.attachToMsg(a2, ICD_WOFFSETOF(msg_rdr_operation_command_t, rdr_mode_command));

  dLockSts.setFormat(rdr_design_sts_field_t::start_bit, rdr_design_sts_field_t::set_mask);
  dLockSts.attachToMsg(b7, ICD_WOFFSETOF(msg_rdr_status_tellback_t, mode));

  GRIFO_ADS_MAP(dRangeScale, "range_scale", msg_rdr_operation_command_t, param1, range_scale_field_t, *a2);
  GRIFO_ADS_MAP(dRangeScaleTB, "range_scale_tb", msg_rdr_status_tellback_t, param1, range_scale_field_t, *b7);

  GRIFO_ADS_MAP(dSpot, "spot", msg_rdr_operation_command_t, param1, spot_selection_field_t, *a2);

  //dRwsSub.attachToMsg(msg, ICD_WOFFSETOF(msg_rdr_operation_command_t, param2));
  //dRwsSub.setFormat(rws_submode_field_t::start_bit, rws_submode_field_t::set_mask);
  GRIFO_ADS_MAP(dRwsSub, "rws_submode", msg_rdr_operation_command_t, param1, rws_submode_field_t, *a2);
  GRIFO_ADS_MAP(dRwsSubTB, "rws_submode_tb", msg_rdr_status_tellback_t, param1, rws_submode_field_t, *b7);

  GRIFO_ADS_MAP(dGmSub, "gm_submode", msg_rdr_operation_command_t, param1, gm_submode_field_t, *a2);
  GRIFO_ADS_MAP(dGmSubTB, "gm_submode_tb", msg_rdr_status_tellback_t, param1, gm_submode_field_t, *b7);

  GRIFO_ADS_MAP(dAcmSub, "acm_submode", msg_rdr_operation_command_t, param1, acm_submode_field_t, *a2);
  GRIFO_ADS_MAP(dAcmSubTB, "acm_submode_tb", msg_rdr_status_tellback_t, param1, acm_submode_field_t, *b7);

  GRIFO_ADS_MAP(dVelocityScale, "velocity_scale", msg_rdr_operation_command_t, param1, velocity_scale_field_t, *a2);

  //velocity_scale_tb_field_t non ritorna la velocità, se si guarda sul documento a pagina 379.
  GRIFO_ADS_MAP(dVelocityScaleTB, "velocity_scale_tb", msg_rdr_status_tellback_t, param1, velocity_scale_tb_field_t, *b7);

  GRIFO_ADS_MAP(dWidth, "scan_width", msg_rdr_operation_command_t, param1, scan_width_field_t, *a2);
  GRIFO_ADS_MAP(dWidthTB, "scan_width_tb", msg_rdr_status_tellback_t, param1, scan_width_tellback_field_t, *b7);

  dBars.attachToMsg(a2, ICD_WOFFSETOF(msg_rdr_operation_command_t, param1));
  dBars.setFormat(bars_num_field_t::start_bit, bars_num_field_t::set_mask);
  GRIFO_ADS_MAP(dBarsTB, "bars_tb", msg_rdr_status_tellback_t, param1, bars_num_field_t, *b7);

  dRadiation.attachToMsg(b7, ICD_WOFFSETOF(msg_rdr_status_tellback_t, mode));
  dRadiation.setFormat(rf_radiation_field_t::start_bit, rf_radiation_field_t::set_mask);

  dEmergency.attachToMsg(a2, ICD_WOFFSETOF(msg_rdr_operation_command_t, rdr_mode_command));
  dEmergency.setFormat(reserved11_field_t::start_bit, reserved11_field_t::set_mask);

  dEmergencyTB.attachToMsg(b7, ICD_WOFFSETOF(msg_rdr_status_tellback_t, mode));
  dEmergencyTB.setFormat(reserved11_field_t::start_bit, reserved11_field_t::set_mask);

  actExpand.setObjectName("act_EXPAND");
  actExpand.attachTo(&dExpand);
  actExpand.setActionValue(0, 1);

  actSTBY.setObjectName("act_STBY");
  actSTBY.attachTo(&dStby);
  actSTBY.setActionValue(0, 1);

  actRWS.setObjectName("act_RWS");
  actRWS.attachTo(&dMode);
  actRWS.setActionValue(RWS);

  actRWS_NAM.setObjectName("act_RWS_NAM");
  actRWS_NAM.attachTo(&dMode, &dRwsSub);
  actRWS_NAM.setActionValue(RWS, RWS_NAM);
  actRWS_ASM.setObjectName("act_RWS_ASM");
  actRWS_ASM.attachTo(&dMode, &dRwsSub);
  actRWS_ASM.setActionValue(RWS, RWS_ASM);

  actTWS.setObjectName("act_TWS");
  actTWS.attachTo(&dMode);
  actTWS.setActionValue(TWS);

  actTS.setObjectName("act_TS");
  actTS.attachTo(&dMode);
  actTS.setActionValue(TS);

  actVS.setObjectName("act_VS");
  actVS.attachTo(&dMode);
  actVS.setActionValue(VS);

  actACM.setObjectName("act_ACM");
  actACM.attachTo(&dMode);
  actACM.setActionValue(ACM);

  actACMCycle.setObjectName("act_ACM_Cycle");
  actACMCycle.attachTo(&dAcmSub);
  actACMCycle.setActionValue(McsG346AcmSub::BORESIGHT, McsG346AcmSub::SLEWABLE);

  actACM_Plus.setObjectName("act_ACM_Plus");
  actACM_Plus.attachTo(&dMode, &dAcmSub);
  actACM_Plus.setActionValue(ACM, McsG346AcmSub::BORESIGHT, McsG346AcmSub::SLEWABLE);

  actRBM.setObjectName("act_RBM");
  actRBM.attachTo(&dMode, &dGmSub);
  actRBM.setActionValue(GM, GM_RBM);
  actDBS.setObjectName("act_DBS");
  actDBS.attachTo(&dMode, &dGmSub);
  actDBS.setActionValue(GM, GM_DBS);

  actBCN_Plus.setObjectName("act_BCN_Plus");
  actBCN_Plus.attachTo(&dMode, &dBars);
  actBCN_Plus.setActionValue(BCN, BARS_1, BARS_2);

  actSEA1.setObjectName("act_SEA1");
  actSEA1.attachTo(&dMode);
  actSEA1.setActionValue(SEA_LOW);

  actSEA2.setObjectName("act_SEA2");
  actSEA2.attachTo(&dMode);
  actSEA2.setActionValue(SEA_HIGH);

  actETET.setObjectName("act_ETET");
  actETET.attachTo(&dMode);
  actETET.setActionValue(MODE_SPARE_14);

  actGMTI.setObjectName("act_GMTI");
  actGMTI.attachTo(&dMode);
  actGMTI.setActionValue(GMTI);

  actAGR.setObjectName("act_AGR");
  actAGR.attachTo(&dMode);
  actAGR.setActionValue(AGR);

  actTA.setObjectName("act_TA");
  actTA.attachTo(&dMode);
  actTA.setActionValue(TA);

  actWA.setObjectName("act_WA");
  actWA.attachTo(&dMode);
  actWA.setActionValue(WA);

  act10NM.setObjectName("act_10NM_1200KTS");
  act10NM.attachTo(&dRangeScale, &dVelocityScale);
  act10NM.setActionValue(NM10, KTS1200);

  act20NM.setObjectName("act_20NM_2400KTS");
  act20NM.attachTo(&dRangeScale, &dVelocityScale);
  act20NM.setActionValue(NM20, KTS2400);

  act40NM.setObjectName("act_40NM");
  act40NM.attachTo(&dRangeScale);
  act40NM.setActionValue(NM40);

  act80NM.setObjectName("act_80NM");
  act80NM.attachTo(&dRangeScale);
  act80NM.setActionValue(NM80);

  act15D.setObjectName("act_15D");
  act15D.attachTo(&dWidth);
  act15D.setActionValue(W15);

  act30D.setObjectName("act_30D");
  act30D.attachTo(&dWidth);
  act30D.setActionValue(W30);

  act60D.setObjectName("act_60D");
  act60D.attachTo(&dWidth);
  act60D.setActionValue(W60);

  actB1.setObjectName("act_B1");
  actB1.attachTo(&dBars);
  actB1.setActionValue(BARS_1);

  actB2.setObjectName("act_B2");
  actB2.attachTo(&dBars);
  actB2.setActionValue(BARS_2);

  actB4.setObjectName("act_B4");
  actB4.attachTo(&dBars);
  actB4.setActionValue(BARS_4);

  actModeCycle.setObjectName("act_ModeCycle");
  actModeCycle.attachTo(&dMode);
  actModeCycle.setActionValue(McsG346Mode::RWS, McsG346Mode::WA);

  actLockon.setObjectName("act_LockOn");
  actLockon.attachTo(&dLockon);
  actLockon.setActionValue(McsG346Lockon::LOCK_ON, McsG346Lockon::NOT_VALID, 2);

  actHptBug.setObjectName("act_HptBug");
  actHptBug.attachTo(&dLockon);
  actHptBug.setActionValue(McsG346Lockon::HPT_BUG, McsG346Lockon::NOT_VALID, 2);

  actLockonDtt.setObjectName("act_LockOnDTT");
  actLockonDtt.attachTo(&dLockon);
  actLockonDtt.setActionValue(McsG346Lockon::LOCK_DTT, McsG346Lockon::NOT_VALID, 2);

  actLockonStt.setObjectName("act_LockOnSTT");
  actLockonStt.attachTo(&dLockon);
  actLockonStt.setActionValue(McsG346Lockon::LOCK_STT, McsG346Lockon::NOT_VALID, 2);

  actLockonSAR.setObjectName("act_LockOnSAR");
  actLockonSAR.attachTo(&dLockon);
  actLockonSAR.setActionValue(McsG346Lockon::EXEC_SAR, McsG346Lockon::NOT_VALID, 2);

  actReject.setObjectName("act_Reject");
  actReject.attachTo(&dLockon);
  actReject.setActionValue(McsG346Lockon::REJECT, McsG346Lockon::NOT_VALID, 4);

  actScaleCycle.setObjectName("act_ScaleCycle");
  actScaleCycle.attachTo(&dRangeScale);
  actScaleCycle.setActionValue(NM160, NM10);

  actZoomIn.setObjectName("act_zoomin");
  actZoomIn.attachTo(&dZoomCommand);
  actZoomIn.setActionValue(McsG346ZoomCommand::ZOOM_IN, McsG346ZoomCommand::NOT_ACTIVE, 2);

  actZoomOut.setObjectName("act_zoomout");
  actZoomOut.attachTo(&dZoomCommand);
  actZoomOut.setActionValue(McsG346ZoomCommand::ZOOM_OUT, McsG346ZoomCommand::NOT_ACTIVE, 2);

  GRIFO_ADS_MAP(dTransition, "TRANSITION", msg_rdr_status_tellback_t, mode, transition_status_field_t, *b7);
  GRIFO_ADS_MAP(dLastAcqFail, "LAST_ACQ_FAIL", msg_rdr_status_tellback_t, mode, last_acq_result_field_t, *b7);
  GRIFO_ADS_MAP(dDegradedPerformanceStatus, "DEGRADED_PERF_STATUS", msg_rdr_status_tellback_t, mode, degraded_performance_field_t, *b7);

  GRIFO_ADS_MAP(dSarAcq, "SAR_ACQUISITION", msg_rdr_operation_command_t, rdr_mode_command, sar_exec_filed_t, *a2);
  GRIFO_ADS_MAP(dSarAcqTB, "SAR_ACQUISITION_TB", msg_rdr_status_tellback_t, mode, sar_acquisition_field_t, *b7);

  GRIFO_ADS_MAP(dBeaconCode, "beacon_code", msg_rdr_settings_and_parameters_t, beacon, becon_code_field_t, *a1);
  GRIFO_ADS_MAP(dBeaconDelay, "beacon_delay", msg_rdr_settings_and_parameters_t, beacon, becon_delay_field_t, *a1);

  GRIFO_ADS_MAP(dPowerUpStopFunctSel, "PWR_UP_STOP_FUNCT_SEL", msg_rdr_operation_command_t, rdr_mode_command, stop_powerup_field_t, *a2);

  GRIFO_ADS_MAP(dSpotFuncSel, "SPOT_FUNC_SEL", msg_rdr_operation_command_t, param1, spot_selection_field_t, *a2);
  GRIFO_ADS_MAP(dSpotFuncSelTB, "SPOT_FUNC_SEL_TB", msg_rdr_status_tellback_t, param1, spot_selection_field_t, *b7);

  GRIFO_ADS_MAP(dZoomCommand, "ZOOM_COMMAND", msg_rdr_operation_command_t, param2, zoom_field_t, *a2);
  GRIFO_ADS_MAP(dZoomCommandTB, "ZOOM_COMMAND_TB", msg_rdr_status_tellback_t, param2, zoom_field_t, *b7);

  GRIFO_ADS_MAP(dSarMapOrientation, "SAR_MAP_ORIENTATION", msg_rdr_operation_command_t, param2, sar_map_orientation_field_t, *a2);
  GRIFO_ADS_MAP(dSarMapOrientationTB, "SAR_MAP_ORIENTATION_TB", msg_rdr_status_tellback_t, param2, sar_map_orientation_field_t, *b7);

  dSilence.setFromUser(1);
  dStby.setFromUser(1);

  a2->addDataCheck(chkExpTrans);
  b7->addDataCheck(chkTransition);

  {
    ConcreteActSmartLockonBegin* concreteActSmartLockonBegin=new ConcreteActSmartLockonBegin(*this);
    ConcreteActSmartLockonEnd* concreteActSmartLockonEnd=new ConcreteActSmartLockonEnd(*this);

    actSmartLockonBegin=concreteActSmartLockonBegin;
    actSmartLockonEnd=concreteActSmartLockonEnd;
  }
}

union b7_cv_t
{
  avb_1553_data_buffer_t buffer;
  msg_rdr_status_tellback_t tb;
};

#include <QDateTime>

void GrifoMsg_A2B7::b7_rdr_status_async_message_routine(Ads1553MsgQ* msg)
{
    static Ads1553MsgQ* a2;
    if (a2==0)
    {
      a2=Ads1553Manager::instance().getMsgObj("A2");
      if (a2==0)
        return;
    }

  {
        static Ads1553MsgQ* a1;
        if (a1==0)
        {
          a1=Ads1553Manager::instance().getMsgObj("A1");
          if (a1==0)
            return;
        }

    QDateTime dt=QDateTime::currentDateTime();

    QDate today=dt.date();

    icd1553::date_of_mission_t date_of_mission;
    date_of_mission.raw=a1->data(5);
    date_of_mission.year_of_mission.set(today.year()-2000);
    date_of_mission.month_of_mission.set(today.month());
    date_of_mission.day_of_mission.set(today.day());

    QTime timenow=dt.time();
    icd1553::time_of_mission_t time_of_mission;
    int sec=timenow.msecsSinceStartOfDay()/2000;//lsb=2 seconds
    time_of_mission.set(sec);

    a1->setDataNoSignal(5, date_of_mission.raw);
    a1->setDataNoSignal(6, time_of_mission);

    GrifoBiteForm::instance().setTimeOfDay(dt);

  }
  //const msg_rdr_status_tellback_t& ststb=
  //    *reinterpret_cast<const msg_rdr_status_tellback_t*>(msg->getBuffer());


  if (!grifo_sim_enable.rdr)
    return;


  static b7_cv_t tb;
  static msg_rdr_status_tellback_t sts;
  static int trans_counter;

  static msg_rdr_operation_command_t cmd;
  static des_control_t old_des=NOT_VALID;

  bool des_changed=(cmd.rdr_mode_command.des_ctrl.get()!=old_des) && (old_des==NOT_VALID);

  old_des=cmd.rdr_mode_command.des_ctrl.get();

  cmd.rdr_mode_command.raw=a2->data(0);
  cmd.param1.raw=a2->data(1);
  cmd.param2.raw=a2->data(2);


  if (cmd.rdr_mode_command.master_mode.get()!=sts.mode.master_mode.get())
  {
    sts.mode.master_mode.set(cmd.rdr_mode_command.master_mode.get());
    sts.mode.design_sts.set(DS_NOT_VALID);

    trans_counter=6;
  }
  else
  {
    if (des_changed)
    {
      trans_counter=6;

      switch(sts.mode.master_mode.get())
      {
      case RWS:
        switch(old_des)
        {
        case LOCK_ON:
          sts.mode.design_sts.set(DS_SAM);
          break;
        case LOCK_ON_STT:
          sts.mode.design_sts.set(DS_STT);
          break;
        case REJECT:
          if (sts.mode.design_sts.get()==DS_SAM)
              sts.mode.design_sts.set(DS_NOT_VALID);
          else if (sts.mode.design_sts.get()==DS_STT)
              sts.mode.design_sts.set(DS_SAM);
          break;
        default:
          break;

        }
        break;

      case TWS:
        break;

      default:
        break;

      }
    }
  }

  sts.mode.stby_sts.set(cmd.rdr_mode_command.stby.get());

  if (cmd.rdr_mode_command.stby.get() || cmd.rdr_mode_command.silence.get())
    sts.mode.rf_radiation.set(false);
  else
    sts.mode.rf_radiation.set(true);

  sts.param1.rws_submode.set(cmd.param1.rws_submode.get());
  sts.param1.acm_submode.set(cmd.param1.acm_submode.get());
  sts.param1.gm_submode.set(cmd.param1.gm_submode.get());
  sts.param1.range_scale.set(cmd.param1.range_scale.get());
  sts.param1.bars_num.set(cmd.param1.bars_num.get());
  sts.param1.scan_width.set((scan_width_tb_t)cmd.param1.scan_width.get());

  switch(cmd.rdr_mode_command.master_mode.get())
  {
  case VS:
    if (cmd.param1.velocity_scale.get()==KTS2400)
      sts.param1.range_scale.set(NM20);
    else
      sts.param1.range_scale.set(NM10);
    break;
  default:
    break;
  }

  if (trans_counter<=0)
  {
    tb.tb.mode.raw=sts.mode.raw;
    tb.tb.param1.raw=sts.param1.raw;
    tb.tb.param2.raw=sts.param2.raw;

    tb.tb.mode.transition_status.set(false);
  }
  else
  {
    tb.tb.mode.transition_status.set(true);
    --trans_counter;
  }

  Ads1553Manager::instance().writeDeviceBuffer(*msg, tb.buffer);
}


void GrifoMsg_A1B6::b8_bite_async_message_routine(Ads1553MsgQ *msg)
{
      GrifoBiteForm& bf=GrifoBiteForm::instance();
      bf.setReport(msg->getBuffer());
}
