

#include "mscmainwindow.h"
#include "ui_mcsmainwindow.h"

#include "windowmenu.h"

#include <QInputDialog>
#include <QStyleFactory>
#include <QMdiSubWindow>
#include <QDebug>
#include <QSettings>
#include <QTimer>
#include <QFile>
#include <QTextStream>
#include <QInputDialog>
#include <QFileDialog>
#include <QDesktopWidget>
#include <QPainter>
#include <QFileInfo>
#include <QActionGroup>
#include <QLabel>
#include <QImage>
#include <QVector>
#include <QSpinBox>
#include <QCursor>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QDirIterator>
#include <QDebug>
#include <QFormLayout>
#include <QGridLayout>
#include <QDesktopWidget>
#include <QComboBox>
#include <QInputDialog>
#include <QStyleFactory>
#include <QMessageBox>

#include "DockManager.h"
#include "DockWidget.h"
#include "DockAreaWidget.h"
#include "DockAreaTitleBar.h"
#include "DockAreaTabBar.h"
#include "FloatingDockContainer.h"
#include "DockComponentsFactory.h"

//#include <QtScript/QScriptEngine>
//#include <QtScriptTools/QScriptEngineDebugger>

#include <QPluginLoader>
#include <QtPlugin>
#include <QLibraryInfo>

#include "ads_workbench.h"
#include "ads_debug.h"
#include "adsmonitorwidget.h"
#include "ads_rawmsgwidget.h"
#include "ads_pluginloader.h"

#include "ads_driver1553.h"

#define SETT_FILE "./gmcs.ini"
#define SETT_LAYOUT_FILE "./gmcs_layout.ini"

#if 0
//static SmallMimicMainWindow* theMainWindow;
//static QScriptEngine* theScriptEngine;
//static QScriptEngineDebugger* theScriptDebugger;


class AdsScriptEngine
{
public:
  static void importScriptExtension(const QString& name)
  {
    static bool ext_already_listed;
    /*QScriptValue sres=*/theScriptEngine->importExtension(name);
    if (theScriptEngine->hasUncaughtException())
    {
      qDebug()<<"Error importing script extension: "<<name;
      if (!ext_already_listed)
      {
        qDebug()<<"Available Script Extensions are: "<<theScriptEngine->availableExtensions();
        ext_already_listed=true;
      }
    }
    else
      qDebug()<<"Script extension imported: "<<name;
  }
  static void loadFle(const QString& name)
  {
    QFile scriptFile(name);
    if (!scriptFile.open(QIODevice::ReadOnly))
      return;
    QTextStream stream(&scriptFile);
    QString contents = stream.readAll();
    scriptFile.close();
    theScriptEngine->evaluate(contents, name);
  }

};

static void importScriptEtension(const QString& name)
{
  AdsScriptEngine::importScriptExtension(name);
}

#endif

class McsMainWindow::Private: public IAdsWorkBench
{
public:
  McsMainWindow& w;
  QMainWindow* hostWindow;

  AdsMonitorWidget* adsMon;

  IAdsApplication* app;

  QString defIniFile;

  QComboBox& cbRunState;
  //QGridLayout& lyRawData;
  QActionGroup& grpBusCtrl;
  QActionGroup& grpBusMon;

  QPixmap imgVcrRec;
  QPixmap imgVcrStop;
  QPixmap imgVcrPause;
  QPixmap imgMonRun;
  QPixmap imgMonAcq;

  QIcon iconMonOff;
  QIcon iconMonRunning;
  QIcon iconMonError;
  QIcon iconMonSomeErrors;

  ads::CDockWidget* appDockWidget;

  QVector<ads::CDockWidget*> dockedWidgets;

  AdsRawDataView rawDataView;

  //Mouse Management
  typedef QMap<int, IAdsMouseGrabber*> mouse_grabber_map_t;

  mouse_grabber_map_t mouse_grabber_map;
  IAdsMouseGrabber* activeGrabber;
  QPoint grabberBeginPos;

  ads::CDockManager* DockManager;

  void installMouseGrabber(int k, IAdsMouseGrabber& grabber)
  {
    mouse_grabber_map[k]=&grabber;
  }
  virtual QMainWindow& mainWindow()
  {
    return w;
  }

  virtual void addAppDockWidget(QWidget* wd, const QString& name)
  {
      if (wd==0)
      {
        return;
      }

      //auto wdock= new QDockWidget(name); //, &w);
      //wdock->setObjectName(name);
      //wd->setParent(wdock);
      //wdock->setWidget(wd);

      auto wdock=new ads::CDockWidget(wd->objectName());
      wdock->setWidget(wd); //, ads::CDockWidget::ForceNoScrollArea);

      DockManager->addDockWidgetTab(ads::RightDockWidgetArea, wdock);

      //w.addDockWidget(Qt::RightDockWidgetArea, wdock); //Qt::RightDockWidgetArea, wdock);

      if (appDockWidget==0)
      {
          //w.addDockWidget(Qt::LeftDockWidgetArea, wdock); //Qt::RightDockWidgetArea, wdock);
          appDockWidget=wdock;
      }
      else
      {
           //w.tabifyDockWidget(appDockWidget, wdock);
           //appDockWidget=wdock;
      }
      dockedWidgets.push_back(wdock);
  }

  virtual QTabWidget* getTabArea()
  {
    return 0; //w.ui->tabWidget;
  }

  virtual void addShortcut(QAction *act)
  {
    w.ui->menuShortcut->addAction(act);
  }

  bool activateMouseGrabber(int k)
  {
    if (activeGrabber)
    {
      abortMouseGrabber();
      return true;
    }

    if (mouse_grabber_map.contains(k))
    {
      //qDebug()<<"Ativate Grabber";

      grabberBeginPos=QCursor::pos();
      QRect r=QApplication::desktop()->screenGeometry(grabberBeginPos);
      QCursor::setPos(r.center());
      activeGrabber=mouse_grabber_map[k];
      activeGrabber->activate(QCursor::pos());

      const QCursor* const c=activeGrabber->getCursor();

      if (c)
        w.grabMouse(*c);

      if (activeGrabber->needMouseTraking())
        w.setMouseTracking(true);

      return true;
    }
    return true;
  }
  void abortMouseGrabber()
  {
    //qDebug()<<"Abort Grabber";
    if (activeGrabber)
      activeGrabber->abort();
    w.setMouseTracking(false);
    w.releaseMouse();
    activeGrabber=0;
  }

  void deactivateMouseGrabber()
  {
    if (activeGrabber)
    {
      //qDebug()<<"Decativate Grabber";
      activeGrabber->deactivate();
      w.setMouseTracking(false);
      w.releaseMouse();
      activeGrabber=0;
      QCursor::setPos(grabberBeginPos);
    }
  }

  Private(McsMainWindow& parent):
      w(parent),
      hostWindow(&parent),
      adsMon(0),
      cbRunState(*new QComboBox),
      //lyRawData(*new QGridLayout),
      grpBusCtrl(*new QActionGroup(&parent)),
      grpBusMon(*new QActionGroup(&parent))
  {
  }

  void initialize()
  {
    //hostWindow=0;
    defIniFile="./default.mcs";

    QPixmap base(":/trolltech/styles/commonstyle/images/dvd-32.png");
    QPixmap baseMon(":/trolltech/styles/commonstyle/images/viewdetailed-32.png");

    imgVcrRec=base;
    imgVcrStop=base;
    imgVcrPause=base;

    const int sz=32-24;
    {
      QPixmap tmp(":/trolltech/styles/commonstyle/images/media-pause-32.png");

      QPainter p(&imgVcrPause);
      p.drawPixmap(sz, sz, tmp);
    }
    {
      QPixmap tmp(":/trolltech/styles/commonstyle/images/media-play-32.png");

      QPainter p(&imgVcrRec);
      p.drawPixmap(sz, sz, tmp);
    }
    {
      QPixmap tmp(":/trolltech/styles/commonstyle/images/media-stop-32.png");

      QPainter p(&imgVcrStop);
      p.drawPixmap(sz, sz, tmp);
    }

    {
      QPixmap tmp(32, 32);

      {
        tmp.fill(Qt::gray);
        //QPainter p(&tmp);
        //p.setPen(Qt::black);
        //p.setBrush(Qt::gray);
        //p.drawEllipse(16, 16, 15, 15);
        iconMonOff.addPixmap(tmp);
      }
      {
        tmp.fill(Qt::green);
        //QPainter p(&tmp);
        //p.setPen(Qt::black);
        //p.setBrush(Qt::green);
        //p.drawEllipse(16, 16, 15, 15);
        iconMonRunning.addPixmap(tmp);
      }
      {
        tmp.fill(Qt::red);
        //QPainter p(&tmp);
        //p.setPen(Qt::black);
        //p.setBrush(Qt::red);
        //p.drawEllipse(16, 16, 15, 15);
        iconMonError.addPixmap(tmp);
      }
      {
        tmp.fill(Qt::yellow);
        //QPainter p(&tmp);
        //p.setPen(Qt::black);
        //p.setBrush(Qt::red);
        //p.drawEllipse(16, 16, 15, 15);
        iconMonSomeErrors.addPixmap(tmp);
      }

    }

    {
      imgMonRun=baseMon;
      imgMonAcq=baseMon;


      {
        QPixmap tmp(":/trolltech/styles/commonstyle/images/media-play-32.png");
        QPainter p(&imgMonRun);
        p.drawPixmap(sz, sz, tmp);
      }
      {
        QPixmap tmp(":/trolltech/styles/commonstyle/images/standardbutton-save-32.png");
        QPainter p(&imgMonAcq);
        p.drawPixmap(sz, sz, tmp);
      }
    }

    rawDataView.initialize(0);
    for(int i=0; i<32; ++i)
      w.addDataWidget(rawDataView.wRawData[i], i);

    activeGrabber=0;
    app=0;

    grpBusCtrl.setExclusive(false);
    grpBusCtrl.setExclusive(false);

    cbRunState.addItems(
            QStringList()<<"NULL"<<"DEVICE ERR"<<"READY"<<"HALT"<<"RUNNING"<<"No RESPONSE"<<"MSG ERRORS"<<"MONITOR");
    cbRunState.setCurrentIndex(0);
    cbRunState.setEnabled(false);
    //cbRunState.setEditable(true);
    cbRunState.setStyleSheet(
      "  QComboBox { padding: 0 0 0 2px;} "
      "  :disabled { color: black; font: bold; }"
      "  ::drop-down { "
      "  position: absolute;"
      "  left: 0;"
      "  subcontrol-origin: content;"
      "  border-style: none;"
      "  width: 0px;"
      "  border-width: 0;"
      " }");
    QFont f=cbRunState.font();
    f.setBold(true);
    cbRunState.setFont(f);
    /*
    cbRunState.setItemData(0, Qt::gray, Qt::BackgroundRole);
    cbRunState.setItemData(1, Qt::red, Qt::BackgroundRole);
    cbRunState.setItemData(3, Qt::white, Qt::BackgroundRole);
    cbRunState.setItemData(4, Qt::green, Qt::ForegroundRole); //Qt::BackgroundRole);
    */
  }
  ~Private()
  {
    //if (adsMon)
    //  delete adsMon;
  }
};

#if 0
static IAdsWorkBench* mcsWorkbenchInstance;

IAdsWorkBench& IAdsWorkBench::instance()
{
  if (!mcsWorkbenchInstance)
    abort();
  return *mcsWorkbenchInstance;
}
#endif

McsMainWindow::McsMainWindow(QMainWindow *hostWin) :
  QMainWindow(0),
  ui(new Ui::McsMainWindow),
  p_(*new McsMainWindow::Private(*this))
{
  //mcsWorkbenchInstance=&p_;

  p_.hostWindow=hostWin ? hostWin : this;


  ui->setupUi(this);

  p_.initialize();

  //setStyleSheet("QMainWindow::separator { background-color: darkgray; width: 2px; height: 2px; }");

  ui->actionLoad->setIcon(QIcon(":/qt-project.org/styles/commonstyle/images/standardbutton-open-16.png"));
  ui->actionReload_default->setIcon(QIcon(":/qt-project.org/styles/commonstyle/images/file-16.png"));
  ui->actionSave->setIcon(QIcon( ":/qt-project.org/styles/commonstyle/images/standardbutton-save-16.png"));
  ui->actionSave_As->setIcon((QIcon(":/qt-project.org/styles/commonstyle/images/newdirectory-16.png")));
  ui->actionQuit->setIcon(QIcon(":/qt-project.org/styles/commonstyle/images/standardbutton-close-16.png"));

  ui->actionBusRun->setIcon(QIcon(":/qt-project.org/styles/commonstyle/images/media-play-16.png"));
  ui->actionBusOneFrame->setIcon(QIcon(":/qt-project.org/styles/commonstyle/images/media-skip-forward-16.png"));
  ui->actionBusStop->setIcon(QIcon(":/qt-project.org/styles/commonstyle/images/media-pause-16.png"));

  ui->actionVCR_Rec->setIcon(p_.imgVcrRec);
  ui->actionVCR_Pause->setIcon(p_.imgVcrPause);
  ui->actionVCR_Stop->setIcon(p_.imgVcrStop);
  ui->actionVCR_Rec->setVisible(false);
  ui->actionVCR_Pause->setVisible(false);
  ui->actionVCR_Stop->setVisible(false);

  ui->actionBusOneFrame->setVisible(false);
  ui->actionBusMonitorAcq->setVisible(false);

  ui->actionMonitorStatus->setIcon(p_.iconMonOff);
  ui->actionBusMonitor->setIcon(p_.imgMonRun);
  ui->actionBusMonitorAcq->setIcon(p_.imgMonAcq);
  ui->actionBusMonitorReset->setIcon(QIcon(":/qt-project.org/styles/commonstyle/images/refresh-32.png"));

  ui->actionDeviceReset->setIcon(QIcon(":/qt-project.org/styles/commonstyle/images/refresh-32.png"));
  ui->actionDevice_Info->setIcon(QIcon(":/qt-project.org/styles/commonstyle/images/refresh-32.png"));

  p_.grpBusCtrl.addAction(ui->actionBusRun);
  p_.grpBusCtrl.addAction(ui->actionBusOneFrame);
  p_.grpBusCtrl.addAction(ui->actionBusStop);

  p_.grpBusCtrl.addAction(ui->actionBusMonitor);

  p_.grpBusMon.addAction(ui->actionBusMonitorAcq);
  p_.grpBusMon.addAction(ui->actionVCR_Rec);
  p_.grpBusMon.addAction(ui->actionVCR_Pause);
  p_.grpBusMon.addAction(ui->actionVCR_Stop);

#if 0
  mScriptMenu=new QMenu("Script", this);

  mScriptMenu->addAction("Load...", this, SLOT(loadScript()));
  mScriptMenu->addAction("Eval...", this, SLOT(evalScript()));
  mScriptMenu->addAction("Script Debugger", this, SLOT(showScriptDebugger()));
  mScriptMenu->addSeparator();

  menuBar()->addMenu(mScriptMenu);
#endif
  WindowMenu* wm=new WindowMenu(tr("&Windows"), this);
  wm->addSeparator();
  wm->addAction("Style...", this, SLOT(selectStyle()));
  //wm->setMdi(ui->mdiArea);
  menuBar()->addMenu(wm);
  //wm->setTabWidget(ui->tabWidget);
  ui->tabWidget->setVisible(false);
  ui->tabWidget->setEnabled(false);

  //theScriptEngine=new QScriptEngine(this);
  //theScriptDebugger=new QScriptEngineDebugger(this);
  //theScriptDebugger->attachTo(theScriptEngine);
  //theScriptDebugger->setAutoShowStandardWindow(true);

  //theScriptDebugger->standardWindow()->show();
    ui->mainToolBar->insertWidget(ui->actionBusRun, &p_.cbRunState);

    updateBusState(true, false, false);

    //ui->tabWidget->setTabIcon(0, QIcon(":/trolltech/qmessagebox/images/qtlogo-64.png"));

    ui->dockWidget->setVisible(false);

    updateDefaultFile(p_.defIniFile);

    {
      QMainWindow::DockOptions d=dockOptions();
      d&= ~QMainWindow::AnimatedDocks;
      d|=QMainWindow::AllowNestedDocks;
      d|=QMainWindow::AllowTabbedDocks;

      setDockOptions(d);

      setAnimated(false);
    }

    AdsDebug::log_print("Avionic Data Smart Starting...");

    ads::CDockManager::setConfigFlag(ads::CDockManager::FocusHighlighting, true);
    ads::CDockManager::setConfigFlag(ads::CDockManager::OpaqueSplitterResize, false);
    ads::CDockManager::setConfigFlag(ads::CDockManager::OpaqueUndocking, false);
    ads::CDockManager::setConfigFlag(ads::CDockManager::DragPreviewIsDynamic, false);
    ads::CDockManager::setConfigFlag(ads::CDockManager::DragPreviewShowsContentPixmap, false);
    ads::CDockManager::setConfigFlag(ads::CDockManager::DragPreviewHasWindowFrame, false);

    p_.DockManager = new ads::CDockManager(this);

  //Conan
  {
      ui->menuDebug->addAction("Conan", this, SLOT(showConan(void)));
  }

  this->statusBar()->setVisible(false);

  //this->setWindowFlags(Qt::Widget);
  QTimer::singleShot(0, this, SLOT(postInit()));
}

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



void McsMainWindow::postInit()
{
  //AdsDebug::createDebugWindows(this);

  //QScriptValue scriptWin = theScriptEngine->newQObject(this);
  //theScriptEngine->globalObject().setProperty("ads", scriptWin);

  /*
  importScriptEtension("qt.core");
  importScriptEtension("qt.gui");
  importScriptEtension("qt.network");
  importScriptEtension("qt.xml");
  importScriptEtension("qt.uitools");
  */
  QString startScript;

  QSettings s(SETT_FILE, QSettings::IniFormat);
  s.beginGroup("SystemConfig");
  bool enable_debug=s.value("debug", true).toBool();
  enable_debug=true;

  QVariant v=s.value("LibraryPaths");
  if (v.canConvert(QVariant::StringList))
  {
    QStringList sl=v.toStringList();
    foreach(QString p, sl)
      QCoreApplication::addLibraryPath(p);
    if (enable_debug)
      qDebug()<<"Library Paths: "<<QCoreApplication::libraryPaths();
  }
  if (enable_debug)
    qDebug()<<QCoreApplication::applicationDirPath();

  if (s.value("scriptEnable", true).toBool())
  {
    v=s.value("scriptImportExtension");
    if (v.canConvert(QVariant::StringList))
    {
      QStringList sl=v.toStringList();
      //foreach(QString p, sl)
      //  importScriptEtension(p);
    }

    //startScript=s.value("startupScript", "./gmcs_init.qs").toString();
  }

  QString avb_driver=s.value("avbDriver").toString();
  s.endGroup();

  IAvbDriver* the_avb_driver=AdsPluginLoader::loadAvbDriver(avb_driver, &s);
  if (the_avb_driver)
    Ads1553Manager::setDriver(the_avb_driver);
  else
    exit(0);


  //widget BusMonitor alla schermata principale
  p_.adsMon=new AdsMonitorWidget(this);
  p_.addAppDockWidget(p_.adsMon, "Bus Monitor");

  //ui->tabWidget->addTab(p_.adsMon, QIcon(":/images/images/emac-icon32.png"), "Bus Monitor");
  //QDockWidget* dw=new QDockWidget("Bus Monitor");
  //addDockWidget(Qt::LeftDockWidgetArea, dw);

  connect(&Ads1553Manager::instance(), SIGNAL(messageListChanged()), SLOT(_onMessageListChanged()));
  connect(&Ads1553Manager::instance(), SIGNAL(runStatusChanged(Ads1553Manager::run_sts_t)), SLOT(_onRunStatusChanged(Ads1553Manager::run_sts_t)));
  connect(&Ads1553Manager::instance(), SIGNAL(commStatusChanged(Ads1553Manager::com_sts_t)), SLOT(updateComStatus(Ads1553Manager::com_sts_t)));
  connect(ui->comboBox_SelectMsg, SIGNAL(currentIndexChanged(int)), SLOT(_onRawMessageSlection_changed(int)));
  _onMessageListChanged();

  if (!startScript.isEmpty())
  {
    QFile f(startScript);
    f.open(QIODevice::ReadOnly);
    if (!f.isReadable())
      qDebug()<<"Cannot open script script "<<startScript;
    else
    {
      qDebug()<<"Running initialization script "<<startScript;
      QTextStream stream(&f);
      QString program=stream.readAll();

      ///*QScriptValue val=*/theScriptEngine->evaluate(program, startScript);
    }
  }


  p_.app=AdsCreateApplicationInstance(p_);

  //restoreSettings();
  QString devName=Ads1553Manager::instance().getDriver()->getDeviceName();
  QString appTitle("");
  QString icdTitle("");

  if (p_.app)
  {
    appTitle=p_.app->getAppTitle();
    icdTitle=p_.app->getIcdName();

    //setWindowTitle(windowTitle()+": "+QString(p_.app->getAppTitle()));
    p_.app->restoreSettings();
    updateDefaultFile(p_.app->defaultSettingsFilename());
  }

  QString tmp=windowTitle()+": "+appTitle+"-"+icdTitle+" ["+devName+"]";
  setWindowTitle(tmp);
  //updateDefaultFile(p_.defIniFile);

  QTimer::singleShot(0, this, SLOT(postInit2()));
}

void McsMainWindow::postInit2()
{
  AdsDebug::createDebugWindows(p_.hostWindow); //this);
  AdsDebug::instance().startMonitoring();
  //Ads1553Manager::instance().run();
  p_.adsMon->updateDataList();

  bool ok=restoreSettings();
  if (!ok)
  {
      //ads::CDockWidget* wd=p_.dockedWidgets[0];
      for(int i=1; i<p_.dockedWidgets.size(); ++i)
      {
          //tabifyDockWidget(wd, p_.dockedWidgets[i]);
          //wd=p_.dockedWidgets[i];
      }
  }

  //grabGesture(Qt::PanGesture);
  //grabGesture(Qt::PinchGesture);
  //grabGesture(Qt::SwipeGesture);
}

void McsMainWindow::addDataWidget(QWidget * w, int wnum)
{
  ui->dataLayout->addWidget(w, 1+(wnum/2), wnum % 2);
}

void McsMainWindow::updateBusState(bool err, bool bc_run, bool mon_run)
{
  static int p_r_sts=-1;

  if (err)
  {
    p_.grpBusCtrl.setDisabled(true);
    p_.grpBusMon.setDisabled(true);

    p_.cbRunState.setCurrentIndex(0);

    //ui->actionMonitorStatus->setIcon(p_.iconMonError);
    p_r_sts=-1;
  }
  else if (bc_run!=p_r_sts)
  {
      p_r_sts=bc_run;

      if (!p_.grpBusCtrl.isEnabled())
        p_.grpBusCtrl.setEnabled(true);

      ui->actionBusMonitor->setChecked(mon_run);

      if (bc_run)
      {
          //if (!ui->actionBusRun->isChecked())
          {
              p_.cbRunState.setCurrentIndex(4);
              ui->actionBusRun->setChecked(true);
              ui->actionBusOneFrame->setChecked(false);
              ui->actionBusOneFrame->setEnabled(false);
              //ui->actionMonitorStatus->setIcon(p_.iconMonRunning);
          }

      }
      else if (mon_run)
      {
          p_.cbRunState.setCurrentIndex(7);
          ui->actionBusRun->setChecked(false);
          ui->actionBusOneFrame->setChecked(false);
          ui->actionBusOneFrame->setEnabled(true);
      }
      else
      {
          //if (ui->actionBusRun->isChecked())
          {
            p_.cbRunState.setCurrentIndex(3);
            ui->actionBusRun->setChecked(false);
            ui->actionBusOneFrame->setChecked(false);
            ui->actionBusOneFrame->setEnabled(true);
            //ui->actionMonitorStatus->setIcon(p_.iconMonOff);
          }

      }
  }
}

void McsMainWindow::updateDefaultFile(const QString & f)
{
  QString tmp="Reload Default ("+f+")";

  QFileInfo fi(f);

  ui->actionReload_default->setText(tmp);
  ui->actionReload_default->setEnabled(fi.isReadable());
}

void McsMainWindow::saveSettings()
{
  QSettings s(SETT_LAYOUT_FILE, QSettings::IniFormat);

  s.beginGroup("MainWindow");
    s.setValue("windowState", QMainWindow::saveState());
    s.setValue("geometry", saveGeometry());

    s.setValue("DockingState", p_.DockManager->saveState());

    //s.setValue("defInit", p_.defIniFile);
  s.endGroup();

  s.beginGroup("DbgWindows");
  s.setValue("dbgWin", ui->actionShow_monitor->isChecked());
  s.endGroup();
}

bool McsMainWindow::restoreSettings()
{
  //QFileInfo f(SETT_LAYOUT_FILE);

  bool settings_readable=QFileInfo(SETT_LAYOUT_FILE).isReadable();
  if (settings_readable)
  {
    QSettings s(SETT_LAYOUT_FILE, QSettings::IniFormat);

    s.beginGroup("DbgWindows");

    if (s.value("dbgWin").toBool())
        ui->actionShow_monitor->trigger(); //setChecked(true);
    s.endGroup();

    s.beginGroup("MainWindow");

    restoreGeometry(s.value("geometry").toByteArray());
    restoreState(s.value("windowState").toByteArray());

    //QString tmp=s.value("defInit").toString();
    //if (!tmp.isEmpty())
    //  p_.defIniFile=tmp;
    //p_.DockManager->restoreState(s.value("DockingState").toByteArray());
    s.endGroup();
  }

  if (p_.app)
    p_.app->restoreSettings();

  return settings_readable;
}

static QList<QDialog*> openDlgLst;

bool McsMainWindow::event(QEvent *evn)
{
  if (evn->type()==QEvent::Gesture)
  {
/*
    QGestureEvent* gevn=static_cast<QGestureEvent*>(evn);
    if (QGesture *swipe = gevn->gesture(Qt::SwipeGesture))
      qDebug()<<"Gesture: swipe"; //swipeTriggered(static_cast<QSwipeGesture *>(swipe));
    else if (QGesture *pan = gevn->gesture(Qt::PanGesture))
      qDebug()<<"Gesture: pan"; //panTriggered(static_cast<QPanGesture *>(pan));
    if (QGesture *pinch = gevn->gesture(Qt::PinchGesture))
      qDebug()<<"Gesture: pinch"; //pinchTriggered(static_cast<QPinchGesture *>(pinch));
    else
      qDebug()<<"Gesture ?";
*/
    return true;
  }
  return QMainWindow::event(evn);
}

bool McsMainWindow::close()
{
    saveSettings();
    if (p_.app)
      p_.app->saveSettings();

    return QMainWindow::close();
}

void McsMainWindow::closeEvent(QCloseEvent */*evn*/)
{
  /*
  if (!closeDocument())
    evn->ignore();
  else
  {
    wbSaveState();

    ui->mdiArea->closeAllSubWindows();

    if (p_.prj)
    {
      p_.prj->stop();
    }

    theScriptDebugger->standardWindow()->close();
    delete theScriptDebugger;

    evn->accept();
  }
  */

  saveSettings();

  //int r=QMessageBox::question(this, "Avionics 1553", "Save message data?", QMessageBox::Yes, QMessageBox::No|QMessageBox::Default);
  //
  //if (p_.app && (r==QMessageBox::Yes))
  //  p_.app->saveSettings();

  Ads1553Manager::instance().shutdown();

  //if (theScriptDebugger)
  //{
  //  theScriptDebugger->standardWindow()->close();
  //}
  {
    QDialog* d;
    foreach(d, openDlgLst)
    {
      if (d && d->isVisible())
        d->hide();
    }
  }
}


void McsMainWindow::includeScript(const QString& /*name*/)
{
  //AdsScriptEngine::loadFle(name);
}

void McsMainWindow::importExtension(const QString& /*name*/)
{
  //AdsScriptEngine::importScriptExtension(name);
}

void McsMainWindow::evalScript()
{
  QString str=QInputDialog::getText(this, "Ads Script eval", "Eval:");
  //if (!str.isEmpty())
  //  theScriptEngine->evaluate(str);
}

void McsMainWindow::loadScript()
{
  QStringList sl=QFileDialog::getOpenFileNames(this, "Load scripts", QString(), "Scripts (*.qs);; All Files (*.*)");
  foreach(const QString& s, sl)
  {
    QFile f(s);
    f.open(QIODevice::ReadOnly);
    if (!f.isReadable())
      qDebug()<<"Cannot open script "<<s;
    else
    {
      qDebug()<<"Loading script "<<s;
      QTextStream stream(&f);
      QString program=stream.readAll();

      ///*QScriptValue val=*/theScriptEngine->evaluate(program, s);
    }
  }
}

#include "plugindialog.h"

void McsMainWindow::showScriptDebugger()
{
#if 0
  if (theScriptDebugger==0)
  {
    theScriptDebugger=new QScriptEngineDebugger;
    theScriptDebugger->attachTo(theScriptEngine);
    theScriptDebugger->setAutoShowStandardWindow(true);
  }
  //ui->mdiArea->addSubWindow(theScriptDebugger->standardWindow())->show(); //->show();
  theScriptDebugger->standardWindow()->show();
#endif
}

void McsMainWindow::selectStyle()
{
  QStringList styleList=QStyleFactory::keys();
  styleList<<"(default)";
  bool ok;
  QString res=QInputDialog::getItem(this, QString("Windows Style"), QString("Select the UI style:"), styleList, 0, false, &ok);
  if (ok && !res.isEmpty())
  {
    //setStyleByName(res);
    if (res==QString("(default)"))
    {
      QSettings s("./mcs_sett.ini", QSettings::IniFormat);
      s.remove("uiStyle");
    }
    else
    {
      QStyle* s=QApplication::setStyle(res);
      if (s)
      {
        QSettings s("./mcs_sett.ini", QSettings::IniFormat);
        s.setValue("uiStyle", res);
      }
    }
  }
}

void McsMainWindow::setStyleByName(const QString& style_name)
{
  QApplication::setStyle(style_name);
}

//Mouse & Keyboard
void McsMainWindow::keyPressEvent(QKeyEvent *e)
{
  QMainWindow::keyPressEvent(e);

  p_.activateMouseGrabber(e->key());

}

void McsMainWindow::keyReleaseEvent(QKeyEvent *e)
{
  QMainWindow::keyReleaseEvent(e);

  p_.deactivateMouseGrabber();
}

void McsMainWindow::mousePressEvent(QMouseEvent *evn)
{
  if (p_.activeGrabber)
    p_.activeGrabber->mousePress(evn);

  QMainWindow::mousePressEvent(evn);
}

void McsMainWindow::mouseReleaseEvent(QMouseEvent *evn)
{
  if (p_.activeGrabber)
    p_.activeGrabber->mouseRelease(evn);

  QMainWindow::mouseReleaseEvent(evn);
}

void McsMainWindow::mouseMoveEvent(QMouseEvent *evn)
{
  if (p_.activeGrabber)
    p_.activeGrabber->mouseMove(evn);

  QMainWindow::mouseMoveEvent(evn);
}

void McsMainWindow::wheelEvent(QWheelEvent * evn)
{
  if (p_.activeGrabber)
    p_.activeGrabber->mouseWheel(evn);

  QMainWindow::wheelEvent(evn);

}


void McsMainWindow::on_actionShow_monitor_triggered()
{
    AdsDebug::createDebugWindows(this);
    AdsDebug::instance().startMonitoring();

    ui->actionShow_monitor->setCheckable(true);
    ui->actionShow_monitor->setChecked(true);
    ui->actionShow_monitor->setEnabled(false);
}

void McsMainWindow::on_actionQT_Dump_Objects_triggered()
{
  dumpObjectTree();
}

void McsMainWindow::on_actionQT_Dump_Resources_triggered()
{
  QDirIterator it(":", QDirIterator::Subdirectories);
  while (it.hasNext())
    qDebug() << it.next();
}

void McsMainWindow::on_rawShowHex_stateChanged(int s)
{
  bool hex=s==Qt::Checked;

  p_.rawDataView.setHexMode(hex);
}

void McsMainWindow::_onRunStatusChanged(Ads1553Manager::run_sts_t sts)
{
  updateBusState(sts<Ads1553Manager::sts_ready, sts & Ads1553Manager::sts_bc_running, sts & Ads1553Manager::sts_mon_running);
}

void McsMainWindow::_onRawMessageSlection_changed(int i)
{
  //int i=ui->comboBox_SelectMsg->currentIndex();

  Ads1553MsgQ* msg=(Ads1553MsgQ*)ui->comboBox_SelectMsg->itemData(i).toUInt();
  const ads_1553msg_t* const rawInfo=msg ? msg->rawInfo() : 0;

  p_.rawDataView.connect(msg);

  if (rawInfo)
  {
    QString tmp;

    avb_1553_terminal_t* dst=rawInfo->desc.target;
    avb_1553_terminal_t* src=rawInfo->desc.target_rtrt_tx;
    if (rawInfo->desc.tr==avb_tx)
    {
        avb_1553_terminal_t* tmp=src;
        src=dst;
        dst=tmp;

    }
    tmp=QString("%1(%2)-%3(%4)-%5-%6-%7")
        .arg(src->nickName)
        .arg(src->adr)
        .arg(dst->nickName)
        .arg(dst->adr)
        .arg(rawInfo->desc.tr ? 'T' : 'R')
        .arg(rawInfo->desc.sa)
        .arg(rawInfo->desc.wc);
    if (rawInfo->desc.moninal_frequency>0)
      tmp+=QString("[%1Hz]").arg(rawInfo->desc.moninal_frequency);
    //else if (rawInfo->desc.moninal_frequency<0)
    //  tmp+=QString("[<%1Hz]").arg(-rawInfo->desc.moninal_frequency);

    ui->msgCode->setText(tmp);
    ui->groupBox_RawData->setTitle(rawInfo->desc.longName);
  }
}

void McsMainWindow::_onMessageListChanged()
{
  int n=Ads1553Manager::instance().numOfMessages();
  ui->comboBox_SelectMsg->clear();
  ui->comboBox_SelectMsg->addItem("<no-msg>", 0);
  for(int i=0; i<n; ++i)
  {
    Ads1553MsgQ* msg=Ads1553Manager::instance().getMsgObj(i);
    ui->comboBox_SelectMsg->addItem(msg->objectName(), (unsigned int)msg);
  }
  ui->comboBox_SelectMsg->setCurrentIndex(0);
}

void McsMainWindow::on_actionBusRun_triggered(bool checked)
{
  if (checked)
  {
      if (ui->actionBusMonitor->isChecked())
          Ads1553Manager::instance().run_monitor(); //ui->actionBusMonitor->trigger();
      else          
          Ads1553Manager::instance().run();
  }
  else
    Ads1553Manager::instance().stop();
}

void McsMainWindow::on_actionBusStop_toggled(bool /*checked*/)
{
    //if (checked)
    //    Ads1553Manager::instance().stop();
}

void McsMainWindow::on_actionBusOneFrame_triggered(bool checked)
{
    if (checked)
    {
        if (ui->actionBusMonitor->isChecked())
            Ads1553Manager::instance().run_monitor(); //ui->actionBusMonitor->trigger();
        else
            Ads1553Manager::instance().run(false);
    }
}

void McsMainWindow::on_actionBusMonitor_changed()
{
   p_.grpBusMon.setEnabled(ui->actionBusMonitor->isChecked());
}

void McsMainWindow::on_actionBusMonitor_triggered(bool /*checked*/)
{
#if 0
    if (checked)
        Ads1553Manager::instance().run_monitor();
    else
    {
        if (!ui->actionBusRun->isChecked())
          Ads1553Manager::instance().stop_monitor();
    }
#endif
}

void McsMainWindow::on_actionDump_Ads_Data_triggered()
{
  int n=AdsDataManager::logicDataCount();
  AdsDebug::log_print(QString("Ads Logic Data: %1").arg(n));
  for(int i=0; i<n; ++i)
  {
    AdsLogicData* const d=AdsDataManager::getLogicData(i);
    if (!d)
      break;
    AdsDebug::log_print(QString("  %1").arg(d->objectName()));
  }
}

void McsMainWindow::on_actionDump_Ads_Action_triggered()
{
  int n=AdsDataManager::dataActionCount();
  AdsDebug::log_print(QString("Ads Data Action: %1").arg(n));
  for(int i=0; i<n; ++i)
  {
    AdsDataAction* const d=AdsDataManager::getDataAction(i);
    if (!d)
      break;
    AdsDebug::log_print(QString("  %1").arg(d->objectName()));
  }
}

void McsMainWindow::cursorGoto(int x, int y, unsigned int /*flags*/)
{
   IAdsMouseGrabber* g=p_.mouse_grabber_map.value(Qt::Key_Control, 0);
   if (g)
       g->cursorGotoXY(x, y);
}

void McsMainWindow::on_actionMonitorStatus_triggered()
{
    //ui->tabWidget->setCurrentWidget(p_.adsMon);
}

void McsMainWindow::updateComStatus(Ads1553Manager::com_sts_t sts)
{
  static Ads1553Manager::com_sts_t old_s=Ads1553Manager::sts_comm_null;

  //enum com_sts_t { sts_comm_null=0, sts_comm_device_err, sts_comm_idle, sts_comm_ok, sts_comm_some_errors, sts_comm_error};
  if (old_s==sts)
    return;
  old_s=sts;
  switch(sts)
  {
  case Ads1553Manager::sts_comm_null:
  case Ads1553Manager::sts_comm_idle:
    ui->actionMonitorStatus->setIcon(p_.iconMonOff);
    break;
  case Ads1553Manager::sts_comm_ok:
    ui->actionMonitorStatus->setIcon(p_.iconMonRunning);
    break;
  case Ads1553Manager::sts_comm_some_errors:
    ui->actionMonitorStatus->setIcon(p_.iconMonSomeErrors);
    break;
  default:
    ui->actionMonitorStatus->setIcon(p_.iconMonError);
    break;
  }

}

//#include "objectcontroller.h"
#include "qadsplot.h"
#include "QStandardItemModel"
#include "QStandardItem"
#include "QTreeView"

static void populateList(QStandardItem& sl, QObject* obj, bool showUnnamed, int level)
{
  //static unsigned int obj_count;

  if (!obj)
    return;

  //if (level==0)
  //  obj_count=0;

  //QString indent=QString("%1: %2").arg(obj_count).arg(' ', level*4);
  QStandardItem* item;
  if (!obj->objectName().isEmpty() || showUnnamed)
  {

    QString name=obj->objectName().isEmpty() ? obj->metaObject()->className() : obj->objectName();
    item=new QStandardItem(name);
    item->setData((uint)obj);
    item->setToolTip(obj->metaObject()->className());
    sl.appendRow(item);
  }
  else
    return;

  const QObjectList& list=obj->children();
  foreach(QObject* c, list)
    populateList(*item, c, showUnnamed, level+1);
}

void McsMainWindow::on_actionQT_Properties_triggered()
{
#if 0
  static ObjectInspectorDialog* ocw;
  if (!ocw)
  {
    ocw=new ObjectInspectorDialog(this);
    ocw->registerObject(this);
    ocw->registerObject(qApp);

    openDlgLst.append(ocw);
  }
  ocw->show();
  //QStringList strLst;
  //QList<QObject*> objLst;
  QStandardItemModel sl;

  bool showUnnamed=true; //appProperties.showUnnameObjects();

  populateList(*sl.invisibleRootItem(), qApp, showUnnamed, 0);
  populateList(*sl.invisibleRootItem(), this, showUnnamed, 0);

  //QString res=QInputDialog::getItem(this, QString("Object Properties"), QString("Select the Object:"), strLst, 0, false, &ok);
  QTreeInputDialog d("Select Object to inspect");
  d.setModel(&sl);
  d.setParentSelectable(true);
  if (d.exec()==QDialog::Accepted)
  {
    QObject* obj=(QObject*)d.w->currentIndex().data(Qt::UserRole+1).toUInt();
    if (obj)
    {
      QString dName=QString("Properties: %1").arg(obj->objectName());
      ObjControlDialog dlg(dName, obj, false, this);
      dlg.exec();
    }
  }
  sl.clear();
#endif
}

//#include <Conan.h>

void McsMainWindow::showConan()
{
/*
  static conan::ConanWidget* widget;
  if (!widget)
  {
    widget=new conan::ConanWidget;
    widget->AddRootObject(qApp);
    widget->AddRootObject(this);
    //widget.AddRootObject (someOtherObject); // optional
  }  
  widget->show ();
*/
}

void McsMainWindow::on_actionLoad_triggered()
{
    QString tmp=QFileDialog::getOpenFileName(this,
                                            "MCS: Load data",
                                            QString(),
                                            "INI (*.ini);;All files (*.*)");
    if (tmp.isEmpty())
        return;
  p_.app->restoreSettings(tmp);
}

void McsMainWindow::on_actionReload_default_triggered()
{
    p_.app->restoreSettings();
}

void McsMainWindow::on_actionSave_triggered()
{
  p_.app->saveSettings();
}

void McsMainWindow::on_actionSave_As_triggered()
{
    QString tmp=QFileDialog::getSaveFileName(this,
                                            "MCS: Save data",
                                            QString(),
                                            "INI (*.ini);;All files (*.*)");
    if (tmp.isEmpty())
        return;

    p_.app->saveSettings(tmp);

}

QMainWindow* GrifoMcsMainWindow(QMainWindow* parent)
{
    return new McsMainWindow(parent);
}
