#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include "about.h"
#include "communication/decoder.h"
#include "communication/portcontroller.h"
#include "guipertinency.h"
#include "imageworker.h"
#include "pending.h"
#include "roiwindow.h"
#include "sensor/cmos.h"
#include "setregswindow.h"
#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow {
  Q_OBJECT

public:
  explicit MainWindow(QWidget *parent = nullptr);
  ~MainWindow();

  PortController *getPort() { return this->port; }
  CMOS *getSensor() { return this->sensor; }

private:
  PortController *port;      // communication port
  Decoder *decoder;          // decoder
  CMOS *sensor;              // sensor representation
  ImageWorker *img;          // image worker
  Pending *pendingControler; // pending values control
  GUIpertinency *pert;       // pertinency control

  std::vector<double>
      fps; // latest fps list (shown fps is average from this list)

  double computeFitScale(bool area);      // compute fit window image scale
  double computeFitWidthScale(bool area); // compute fit width image scale

private slots:
  // port control
  void loadPorts();
  void openPort();
  void closePort();
  void portStatus(bool, bool);

  // image scale
  void scaleChanged(int index);
  void arbScaleChanged(int arg1);
  void catchWheelEvent(int);
  void imageViewResize();
  void imageViewLResize();

  // catch sensor parameter update
  void catchSensorUpdate(uint8_t);

  // gain changed
  void onGainChange(bool);

  // save and load
  void saveImage();
  void saveImageLine();
  void saveLineData();
  void saveCMOS();
  void loadCMOS();

  // show registers window
  void setRegs();

  // image capture
  void snapShot();
  void startContinuos();
  void stopContinuos();

  // set sensor parameters
  void sendAEC();
  void sendAGC();
  void sendHDR();
  void sendBright();
  void sendGain();
  void sendExposure();
  void sendBin();
  void sendFlip();
  void setROIShow(); // show ROI window
  void setAll();
  void sendTest();
  void setDefaultSett();

  // image size aligned
  void alignedSize(void);

  // speed test
  void speedTest();

  // refresh parameters
  void refreshBinSkip(void);
  void binSkipSelect(QString);

  // linear mode
  void lineModeSelectChanged(int);
  void setLineSelectMode();
  void setLine();
  void lineSelectChanged(int);

  // show about window
  void showAbout();

  // show fps
  void catchFPS(double);

signals:
  void requestRedrawAreaMode(void); // request image redraw area mode
  void requestRedrawLine(void);     // request selected line redraw
  void requestRedrawLineArea(void); // request image redraw linear mode

  void requestSetViewScale(double);    // set image view scale area mode
  void requestSetViewScaleL(double);   // set image view scale linear mode
  void requsetUpdateViewScale(double); // update image view scale

  void clearAllDecoder(void); // clear buffer in decoder request

  // needed as they are in single GUI element
  void refreshBinning(void); // refresh binning
  void refreshSkip(void);    // refresh skip

private:
  Ui::MainWindow *ui;        // ui
  About *about;              // about window
  setRegsWindow *regsWindow; // registers window
  ROIWindow *roiWindow;      // ROI setting window
};

#endif // MAINWINDOW_H
