#ifndef AardMain_h
#define AardMain_h

#include <QMainWindow>
#include <QXmlDefaultHandler>
#include "ui_aardlearn.h"
#include "LibAard.h"
#include <vector>

class Blinky;
class QTimer;
class RenameRemote;
class QFileDialog;
class OneButton;
class OneSample;
class QTextStream;
class RemoteTable;
class ButtonEditor;
class QSocketNotifier;
class LogWindow;
class QInputDialog;

// AardMain is the main window class for the AardLearn IR code learner utility
// program. Pretty much all the gui elements are operated from here as well
// as reading and writing saved config files.
//
// The config files are stored in xml format, and we inherit from
// QXmlDefaultHandler as well as QMainWindow so we can get the xml parser
// callbacks.
//
class AardMain : public QMainWindow, public QXmlDefaultHandler {

   Q_OBJECT

public:

   AardMain();

   virtual
   ~AardMain();

   // Override the QXmlDefaultHandler routines required to read in the xml
   // config files we write.

   virtual bool
   startDocument();

   virtual bool
   startElement(const QString        & namespaceURI,
                const QString        & localName,
                const QString        & qName,
                const QXmlAttributes & atts);

   virtual bool
   endElement(const QString & namespaceURI,
              const QString & localName,
              const QString & qName);

   virtual bool
   characters(const QString & ch);

   virtual bool
   endDocument();

   virtual QString
   errorString() const;

   virtual bool
   fatalError(const QXmlParseException & exception);

   int
   OptionalAttributeValue(const QXmlAttributes & atts,
                          const QString        & qName,
                          int                    defval,
                          bool                 * ok);

   void
   SendFrequency(int khz);

   void
   SendSample(OneSample * samp);

   ButtonEditor *
   getButtonEditor();

signals:
   void aardRemoteStatusChange(bool is_open);

private slots:

      // Open /dev/file for AardRemote device.
      //
   void
   doOpenAardRemote();

      // Import IR data from other format IR files used by other
      // remote systems.
      //
   void
   doImport();

      // Popup the dialog used to display and modify individual button
      // recorded samples.
      //
   void
   doButtonDetails();

      // Create a new tab with a spreadsheet for defining the buttons in
      // a new remote.
      //
   void
   doNewRemote();

      // Open a saved xml config file.
      //
   void
   doOpenConfig();

      // Save all the recorded data in xml format.
      //
   void
   doSaveConfig();

      // Save config with a different name.
      //
   void
   doSaveConfigAs();

      // Delete the current remote definition.
      //
   void
   doDeleteRemote();

      // Delete the current button in the current remote.
      //
   void
   doDeleteButton();

      // Delete all remote definitions, re-initialize to start state.
      //
   void
   doClose();

      // Record samples for current button of current remote.
      //
   void
   doRecordingToggle(bool checked);

      // This routine is hooked to a timer to poll for data while
      // in recording mode.
      //
   void
   doRecordData();

      // Change th name of the current remote.
      //
   void
   doRenameRemote();

      // Bring up log window.
      //
   void
   doViewLog();

private:

      // Utility routine to create a new remote definition spreadsheet
      // and add it to the top level tab widget.
      //
   void
   initNewTab();

      // Utility routine to delete all the remotes.
      //
   void
   DeleteAllTabs();

      // Utility routine to popup file browser dialog for getting
      // name of config file to read or write.
      //
   bool
   GetConfigFileName(bool for_reading);

      // Write current definitions to config_file_name
      //
   void
   WriteConfigFile();

      // Write one remote spreadsheet to the config file.
      //
   void
   WriteRemote(QTextStream & outstr, QString tab_name, RemoteTable * remote);

      // Write one button definition to the config file.
      //
   void
   WriteButton(QTextStream & outstr, QString button_name, OneButton * button);

      // Write one button IR sample to the config file.
      //
   void
   WriteSample(QTextStream & outstr, OneSample * sample);

      // Try to make sense of the collected data, return true if the
      // analysis routines find sensible patterns that enable button
      // recognition, false if the situation appears hopeless.
      //
   bool
   AnalyzeData();

   void
   CopyData();

   void
   RestoreCopy();

   static int remote_num;

   LibAard           aard_device;
   QSocketNotifier * aard_notify;

   Blinky *      blinky;

   std::vector<unsigned short> recording;

   RenameRemote * rename_dialog;

   QFileDialog * file_dialog;

   QString config_file_name;

   QFileDialog * dev_dialog;

   QString dev_name;

   Ui::AardLearn ui;

   RemoteTable * reading_remote;
   OneButton * reading_button;
   QString reading_characters;
   QString reader_error;
   bool first_element;
   int reader_current_tab;
   int reader_col0_width;
   int reader_col1_width;
   int reader_current_row;

   ButtonEditor * button_editor;

   LogWindow * log_window;
};

#endif // AardMain_h
