#include "ButtonEditor.h"
#include "OneButton.h"
#include "OneSample.h"
#include "SampleGraph.h"
#include "AardMain.h"
#include "SampleTable.h"
#include <QDebug>
#include <QHeaderView>
#include <QTimer>

ButtonEditor::ButtonEditor(
   QAction * init_record_action,
   AardMain * parent,
   Qt::WindowFlags f)
 : QDialog(parent, f),
   current_button(NULL),
   record_action(init_record_action),
   my_main(parent),
   first_paint(true),
   must_draw_graphs(false),
   draw_diff_graph(false),
   aardRemoteIsOpen(false) {

   ui.setupUi(this);
   ui.tableWidget->SetButtonEditor(this);
   connect(ui.finishedButton, SIGNAL(clicked(bool)),
           this, SLOT(doFinish(bool)));
   connect(ui.zoomInButton, SIGNAL(clicked(bool)),
           this, SLOT(doZoomIn(bool)));
   connect(ui.zoomOutButton, SIGNAL(clicked(bool)),
           this, SLOT(doZoomOut(bool)));
   connect(ui.deleteButton, SIGNAL(clicked(bool)),
           this, SLOT(doDeleteSample(bool)));
   connect(ui.recordingCheckBox, SIGNAL(stateChanged(int)),
           this, SLOT(doRecordToggle(int)));
   connect(record_action, SIGNAL(toggled(bool)), this,
           SLOT(doRecordActionChanged(bool)));
   connect(ui.diffCheckBox, SIGNAL(stateChanged(int)),
           this, SLOT(doGraphDiffChanged(int)));
   connect(ui.sendButton, SIGNAL(clicked(bool)),
           this, SLOT(doSend()));
   connect(ui.tableWidget, SIGNAL(currentCellChanged(int,int,int,int)),
           this, SLOT(seeSelectionChange()));
   connect(my_main, SIGNAL(aardRemoteStatusChange(bool)),
           this, SLOT(seeAardRemoteChange(bool)));
   ui.tableWidget->setColumnCount(2);
   ui.tableWidget->verticalHeader()->hide();
   QStringList headers;
   headers << "Length" << "Graph";
   ui.tableWidget->setHorizontalHeaderLabels(headers);
   ui.tableWidget->horizontalHeader()->setStretchLastSection(true);
   enableDisableButtons();
}

ButtonEditor::~ButtonEditor() {
}

void
ButtonEditor::doEditButton(OneButton * the_button) {
   if (the_button != NULL) {
      ui.buttonNameLabel->setText(the_button->text());
   }
   ui.recordingCheckBox->setCheckState(
      record_action->isChecked() ? Qt::Checked : Qt::Unchecked);
   ui.recordingCheckBox->setEnabled(record_action->isEnabled());
   current_button = the_button;
   ui.tableWidget->setRowCount(0);
   if (current_button != NULL) {
      current_button->SetEditor(this);
      for (unsigned int i = 0; i < current_button->NumSamples(); ++i) {
         DrawSample(i, (*current_button)[i]);
      }
   }
   exec();
   if (current_button != NULL) {
      current_button->SetEditor(NULL);
   }
   current_button = NULL;
}

void
ButtonEditor::doNewSample() {
   unsigned int cur_rows = ui.tableWidget->rowCount();
   while (cur_rows < current_button->NumSamples()) {
      DrawSample(cur_rows, (*current_button)[cur_rows]);
      ++cur_rows;
   }
}

void
ButtonEditor::doSend() {
   int sampnum = ui.tableWidget->currentRow();
   if (sampnum < (int)current_button->NumSamples()) {
      my_main->SendFrequency(current_button->ModulationKiloHertz());
      my_main->SendSample((*current_button)[sampnum]);
   }
}

void
ButtonEditor::doDeleteSample(bool /* checked */) {
   int nth = ui.tableWidget->currentRow();
   ui.tableWidget->setRowCount(0);
   current_button->RemoveSample(nth);
   for (unsigned int i = 0; i < current_button->NumSamples(); ++i) {
      DrawSample(i, (*current_button)[i]);
   }
   enableDisableButtons();
}

void
ButtonEditor::doFinish(bool /* checked */) {
   accept();
}

void
ButtonEditor::doZoomIn(bool /* checked */) {
   qDebug() << "doZoomIn";
}

void
ButtonEditor::doZoomOut(bool /* checked */) {
   qDebug() << "doZoomOut";
}

void
ButtonEditor::doRecordToggle(int state) {
   if (current_button != NULL) {
      bool old_checked = record_action->isChecked();
      bool new_checked = (state == Qt::Checked);
      if (old_checked != new_checked) {
         record_action->setChecked(new_checked);
      }
   }
}

void
ButtonEditor::doRecordActionChanged(bool checked) {
   if (current_button != NULL) {
      int old_state = ui.recordingCheckBox->checkState();
      int new_state = checked ? Qt::Checked : Qt::Unchecked;
      if (old_state != new_state) {
         ui.recordingCheckBox->setCheckState((Qt::CheckState)new_state);
      }
   }
}

void
ButtonEditor::doDrawGraphs() {
   must_draw_graphs = false;
   unsigned int cur_rows = ui.tableWidget->rowCount();
   for (unsigned int i = 0; i < cur_rows; ++i) {
      QWidget * wp = ui.tableWidget->cellWidget(i, 1);
      if (wp != NULL) {
         wp->update();
      }
   }
}

void
ButtonEditor::doGraphDiffChanged(int state) {
   bool new_graph_diff = (state == (int)Qt::Checked);
   if (new_graph_diff != draw_diff_graph) {
      draw_diff_graph = new_graph_diff;
      ScheduleDrawGraphs();
   }
}

void
ButtonEditor::seeSelectionChange() {
   enableDisableButtons();
}

void
ButtonEditor::seeAardRemoteChange(bool is_open) {
   aardRemoteIsOpen = is_open;
   enableDisableButtons();
}

void
ButtonEditor::DrawSample(unsigned int row_number, OneSample * sample) {
   unsigned int cur_rows = ui.tableWidget->rowCount();
   if (row_number >= cur_rows) {
      ui.tableWidget->setRowCount(row_number + 1);
   }
   QTableWidgetItem * it = ui.tableWidget->item(row_number, 0);
   if (it == NULL) {
      it = new QTableWidgetItem;
      ui.tableWidget->setItem(row_number, 0, it);
   }
   it->setText(QString("%1 / %2").arg(sample->Length())
                                 .arg(sample->TotalTime()));
   ui.tableWidget->setCellWidget(row_number, 1,
                                 new SampleGraph(this,
                                                 row_number,
                                                 ui.tableWidget));
   ScheduleDrawGraphs();
}

void
ButtonEditor::ScheduleDrawGraphs() {
   if (! must_draw_graphs) {
      QTimer::singleShot(0, this, SLOT(doDrawGraphs()));
      must_draw_graphs = true;
   }
}

void
ButtonEditor::enableDisableButtons() {
   bool empty_selection = (ui.tableWidget->currentItem() == NULL);
   record_action->setEnabled(aardRemoteIsOpen);
   ui.recordingCheckBox->setEnabled(aardRemoteIsOpen);
   ui.sendButton->setEnabled(aardRemoteIsOpen && (! empty_selection));
   ui.deleteButton->setEnabled(! empty_selection);
}
