#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <math.h>

 #include <QMainWindow>

 class QAction;
 class QMenu;
 class QVBoxLayout;
 class QHBoxLayout;
 class QLabel;
 class QLayout;

 class Vector3D
 {
 public:
         float X, Y, Z;

         Vector3D()
         {
             X = 0;
             Y = 0;
             Z = 0;
         }
         Vector3D(const float x, const float y, const float z)
         {
                 X = x;
                 Y = y;
                 Z = z;
         }
         Vector3D(const Vector3D &V)
         {
                 X = V.X;
                 Y = V.Y;
                 Z = V.Z;
         }
         Vector3D operator+ (const Vector3D &V)
         {
                 return Vector3D(X + V.X, Y + V.Y, Z + V.Z);
         }
         Vector3D operator+= (const Vector3D &V)
         {
                 return Vector3D(X += V.X, Y += V.Y, Z += V.Z);
         }
         Vector3D operator* (const float t)
         {
                 return Vector3D(t * X, t * Y, t * Z);
         }
         Vector3D operator- (const Vector3D &V)
         {
                 return Vector3D(X - V.X, Y - V.Y, Z - V.Z);
         }
         Vector3D operator - ()
         {
                 return Vector3D(-X, -Y, -Z);
         }
         float operator* (Vector3D &V)
         {
                 return (X*V.X + Y*V.Y + Z*V.Z);
         }
         float Length()
         {
                 return sqrt(X*X + Y*Y + Z*Z);
         }
         float SqrLen()
         {
                 return (X*X + Y*Y + Z*Z);
         }
         Vector3D NormVect()
         {
                 float d = Length();
                 return Vector3D(X/d, Y/d, Z/d);
         }



 };

 class Mater
 {
 public:
     // diffuse color = ambient color = specular color = colour
         Vector3D Reflectivity;
         Vector3D Specular;
         Vector3D Colour;

         Mater(){}
         Mater(Mater &Mat)
            {
             Reflectivity = Mat.Reflectivity;
             Colour = Mat.Colour;
            }
         void SetRef(const Vector3D Ref)
            {Reflectivity = Ref;}
         void SetSpe(const Vector3D Spe)
            {Specular = Spe;}
         void SetCol(const Vector3D Col)
            {Colour = Col;}

         Vector3D GetRef()
            {return Reflectivity;}
         Vector3D GetSpe()
            {return Specular;}
         Vector3D GetCol()
            {return Colour;}
 };

 class Sphere
 {
 public:
         Vector3D Position;
         float Radius;

         Mater Material;

         Sphere()
         {
            Radius = 1.0f;
         }
         void SetPos(const Vector3D &Pos)
            {Position = Pos;}
         void SetRad(const float Rad)
            {Radius = Rad;}
         void SetMater(Mater &Mat)
            {Material = Mat;}
         Vector3D GetPos()
            {return Position;}
         float GetRad()
            {return Radius;}
         Mater GetMater()
            {return Material;}

 };

 class Thor
 {
 public:
        Vector3D PosCen;
        float Width, Radius;

        Mater Material;

        Thor()
         {
         }
        void SetPosCen(const Vector3D Pos)
            {PosCen = Pos;}
        void SetWid(const float Wid)
            {Width = Wid;}
        void SetRad(const float Rad)
            {Radius = Rad;}
        void SetMater(Mater Mat)
            {Material = Mat;}

        Vector3D GetPosCen()
            {return PosCen;}
        float GetWid()
            {return Width;}
        float GetRad()
            {return Radius;}
        Mater GetMater()
            {return Material;}

 };

 class Cylinder
 {
 public:
         Vector3D PosCentr;
         float Radius;
         float Leng;

         Mater Material;

         Cylinder()
         {
            Radius = 1.0f;
         }
         void SetLen(const float Len)
            {Leng = Len;}
         void SetPosCentr(const Vector3D &Pos)
            {PosCentr = Pos;}
         void SetRad(const float Rad)
            {Radius = Rad;}
         void SetMater(Mater &Mat)
            {Material = Mat;}
         Vector3D GetPos()
            {return PosCentr;}
         float GetRad()
            {return Radius;}
         float GetLen()
            {return Leng;}

 };


 class Light
 {
 public:
         Vector3D Position;
         Vector3D Colour;
         float ConstAttenuation, LinearAttenuation, QuadricAttenuation;

         Light()
         {
            ConstAttenuation = 0.0f;
            LinearAttenuation = 0.0f;
            QuadricAttenuation = 0.0f;
         }
         void SetPos(const Vector3D &Pos)
            {Position = Pos;}
         void SetColor(const Vector3D &Col)
            {Colour = Col;}
         void SetConst(const float c)
            {ConstAttenuation = c;}
         void SetLinear(const float l)
            {LinearAttenuation = l;}
         void SetQuadric(const float q)
            {QuadricAttenuation = q;}
         Vector3D GetPos()
            {return Position;}
         Vector3D GetColor()
            {return Colour;}
         float GetConst()
            {return ConstAttenuation;}
         float GetLinear()
            {return LinearAttenuation;}
         float GetQuadric()
            {return QuadricAttenuation;}
 };

 class Ray
 {
 public:
         Vector3D Start, Direction;

         Ray(){}
         Ray(Vector3D &Start0, Vector3D &Look)
         {
            Start = Start0;
            Direction = -Look + Start;
            Direction = Direction.NormVect();
         }
         ~Ray(){}
         float GetDirLen()
         {
             return (Direction.SqrLen());
         }
         Vector3D GetDir()
            {return Direction;}
 };


 class MainWindow : public QMainWindow
 {
     Q_OBJECT

 public:
     MainWindow();
     ~MainWindow();


 private slots:
     void exit();


 private:
     void createActions();
     void createMenus();
     void createStatusBar();
     void makeFigures();
     void makeLights(); 
     void Paint();
     void AntiAliasing();
     void wash(QImage*, int, int, int, double*, bool);
     void zoom2();
     void countDistances(Vector3D, int, int); 
     float countMinDist(Vector3D, int*, const bool, const bool, const bool, const bool, const bool);
     Vector3D countLites(Vector3D, Vector3D, Vector3D, Light);
     void keyPressEvent(QKeyEvent* pe);
     void wheelEvent(QWheelEvent* pe);
     void mousePressEvent(QMouseEvent* pe); // нажатие клавиши мыши
     void mouseMoveEvent(QMouseEvent* pe);
     void mouseReleaseEvent(QMouseEvent * pe);

     QWidget *window;
     //QTabWidget *tabWidget;
     QLabel *labelIm;
     QPixmap *image;
     QImage *curImage;
     Vector3D **RGBCol;
     QPoint ptrMousePosition; // координата указателя мыши
     Mater Material1, Material2, Material3;
     Sphere Sphere1, Sphere2;
     Cylinder Cylinder1, Cylinder2;
     Thor Thor1, Thor2, Thor3;
     Light Light1, Light2;
     Vector3D CamPos;
     int Wid, Hey;
     bool AntiAl;

     QVBoxLayout *mainLayout;

     QMenu *fileMenu;
     QAction *exitAct;
 };

 #endif
