#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <math.h>
#include "Serial.h"
#include "Light.h"
#include "Sphere.h"
#include "Thor.h"
#include "Ray.h"

 #include <QMainWindow>

 class QAction;
 class QMenu;
 class QVBoxLayout;
 class QHBoxLayout;
 class QLabel;
 class QLayout;

 /**
 @class MainWindow
 Наследник класса QMainWindow.
 Класс, описывающий переменные, при помощи которых задается сцена, содержит конструктор,
 деструктор, 27 членов данных и 21 метод.
 */
 class MainWindow : public QMainWindow
 {
     Q_OBJECT

 public:
     /// Конструктор
     MainWindow();
     /// Деструктор
     ~MainWindow();


 public slots:
     /// Слот, отвечающий за сериализацию сцены в формате XML.
     void SerializeInXml();
     /// Слот, отвечающий за сериализацию сцены в Бинарном формате.
     void SerializeInBin();
     /// Слот, отвечающий за загрузку сериализованной сцены из формата XML.
     void LoadFromXml();
     /// Слот, отвечающий за загрузку сериализованной сцены из Бинарного формата.
     void LoadFromBin();
     /// Слот, отвечающий выход из программы.
     void exit();


 public:
     /// Метод, отвечающий за создание действий для кнопок меню.
     void createActions();
     /// Метод, отвечающий за создание меню.
     void createMenus();
     /// Метод, отвечающий за создание статусбара.
     void createStatusBar();
     /// Метод, отвечающий за установку фигур и их свойств.
     void makeFigures();
     /// Метод, отвечающий за установку источников света и их свойств.
     void makeLights(); 
     /// Метод, отвечающий за прорисовку фигур и источников света.
     void Paint();
     /// Метод, отвечающий за реализацию антиалиасинга.
     void AntiAliasing();

     /// Метод, отвечающий за сериализацию сцены.
     /// @param  Serial – параметр-указатель на значение типа Serializer
     /// @return флаг того, получилось ли начать сериализацию
     bool Serializing(Serializer *Serial);
     /// Метод, отвечающий за фильтрацию.
     /// @param  Temp – параметр-указатель на значение типа изображение
     /// @param  koef1 –параметр целого типа, конечная позиция внутреннего цикла по ширине/высоте изображения
     /// @param  koef2 –параметр целого типа, материал конечная позиция внутреннего цикла по высоте/ширине изображения
     /// @param  N – параметр целого типа - половина размера матрицы фильтрации
     /// @param  wind – матрица-столбец фильтрации
     /// @param  a – параметр логического типа, отвечающий за смену местами длины и высоты изображения в циклах
     void wash(QImage *Temp,int koef1, int koef2, int N, double* wind, bool a);

     /// Метод, отвечающий за подсчет расстояний до объектов.
     /// @param  temp – параметр типа трехмерный вектор, отвечающий за текущее положение в пространстве
     /// @param  numObj – параметр-указатель на значение целого типа, отвечающий за номер объекта до которого считается расстояние
     /// @param  b1 – параметр логического типа, отвечающий за подсчет расстояния до сферы1 (может быть константным)
     /// @param  b2 – параметр логического типа, отвечающий за подсчет расстояния до сферы2 (может быть константным)
     /// @param  b3 – параметр логического типа, отвечающий за подсчет расстояния до тора1 (может быть константным)
     /// @param  b4 – параметр логического типа, отвечающий за подсчет расстояния до тора2 (может быть константным)
     /// @param  b5 – параметр логического типа, отвечающий за подсчет расстояния до тора3 (может быть константным)
     /// @return Минимальное расстояние до объектов
     float countMinDist(Vector3D temp, int *numObj, const bool b1, const bool b2, const bool b3, const bool b4, const bool b5);
     /// Метод, отвечающий за учет освещения объектов источниками света.
     /// @param  Dist – параметр типа трехмерный вектор, отвечающий за текущее расстояние до объекта
     /// @param  Color – параметр типа трехмерный вектор, отвечающий за цвет объекта
     /// @param  SpeColor – параметр типа трехмерный вектор, отвечающий за цвет блика объекта
     /// @param  Light0 – параметр типа трехмерный вектор, отвечающий за источник света, влияние которого на объект будет посчитано
     /// @return Цвет в виде трехмерного вектора
     Vector3D countLites(Vector3D Dist, Vector3D Color, Vector3D SpeColor, Light Light0);
     /// Метод, отвечающий за исполизование клавиатуры в приложении.
     /// @param  pe – параметр, отвечающий за текущее нажатие клавиши
     void keyPressEvent(QKeyEvent* pe);
     /// Метод, отвечающий за учет освещения объектов источниками света.
     /// @param  pe – параметр, отвечающий за текущее положение колесика мыши
     void wheelEvent(QWheelEvent* pe);
     /// Метод, отвечающий за учет нажатия левой клавиши мыши.
     /// @param  pe – параметр, отвечающий за текущее положение курсора мыши
     void mousePressEvent(QMouseEvent* pe);
     /// Метод, отвечающий за учет передвижения курсора.
     /// @param  pe – параметр, отвечающий за текущее положение курсора
     void mouseMoveEvent(QMouseEvent* pe);
     /// Метод, отвечающий за учет отжатия левой клавиши мыши.
     /// @param  pe – параметр, отвечающий за текущее положение курсора мыши
     void mouseReleaseEvent(QMouseEvent * pe);

     /// этот член отвечает за виджет главного окна
     QWidget *window;
     /// этот член отвечает за вывод изображения на экран
     QLabel *labelIm;
     /// этот член отвечает за хранение и вывод изображения на экран
     QPixmap *image;
     /// этот член отвечает за обработку изображения
     QImage *curImage;
     /// этот член отвечает за цвета каждого пиксела
     Vector3D **RGBCol;
     /// этот член отвечает за координату указателя мыши
     QPoint ptrMousePosition;
     /// этот член отвечает за свойства первого материала
     Mater Material1;
     /// этот член отвечает за свойства второго материала
     Mater Material2;
     /// этот член отвечает за свойства третьго материала
     Mater Material3;
     /// этот член отвечает за свойства первой сферы
     Sphere Sphere1;
     /// этот член отвечает за свойства второй сферы
     Sphere Sphere2;
     /// этот член отвечает за свойства первого тора
     Thor Thor1;
     /// этот член отвечает за свойства второго тора
     Thor Thor2;
     /// этот член отвечает за свойства третьго тора
     Thor Thor3;
     /// этот член отвечает за свойства первого источника света
     Light Light1;
     /// этот член отвечает за свойства второго источника света
     Light Light2;
     /// этот член отвечает за позицию камеры
     Vector3D CamPos;
     /// этот член отвечает ширину выводимого изображения
     int Wid;
     /// этот член отвечает высоту выводимого изображения
     int Hey;
     /// этот член - флаг использования антиалиасинга
     bool AntiAl;

     /// этот член отвечает главную область на экране
     QVBoxLayout *mainLayout;

     /// этот член отвечает за меню приложения
     QMenu *fileMenu;
     /// этот член отвечает за вызов действия при нажатии на кнопку меню
     QAction *XMLLAct;
     /// этот член отвечает за вызов действия при нажатии на кнопку меню
     QAction *BinLAct;
     /// этот член отвечает за вызов действия при нажатии на кнопку меню
     QAction *exitAct;
     /// этот член отвечает за вызов действия при нажатии на кнопку меню
     QAction *XMLSAct;
     /// этот член отвечает за вызов действия при нажатии на кнопку меню
     QAction *BinSAct;
 };

 #endif
