#include "Sphere.h"
#include "Thor.h"
#include "Vector3D.h"
#include "Material.h"
#include "Light.h"
#include <QMainWindow>
#include <QFile>

/// это определение является флагом записи/чтения XML
#define XML true
/// это определение является флагом записи/чтения бинарного файла
#define Bin false

/// это определение является флагом записи
#define WR true
/// это определение является флагом чтения
#define RE false

//class QFile;
/**
@class Serializer
Базовый класс сериализации, содержит конструктор, деструктор,
3 члена данных, 6 методов и 7 чистых виртуальных методов.
*/
class Serializer
{
public:
        /// этот член - указатель на файл сериализации
        QFile * File;
        /// этот член - переменная-флаг записи/чтения файла сериализации: 'false' для чтения, 'true' для записи
        bool readWrite;
        /// этот член - формат сохранения данный в файл сериализации: 'false' для XML, 'true' для бинарника
        bool format;

        /// этот член - имя файла сериализации
        QString FileName;

        /// Конструктор
        Serializer();
        /// Деструктор
        ~Serializer();

        /// Чисто виртуальный метод, начинающий сериализацию.
        /// @param  FileName – имя файла сериализации
        /// @return флаг - получилось ли начать сериализацию
        virtual bool Start(QString FileName) = 0;

        /// Чисто виртуальный метод, сериализующий строку.
        /// @param  Value – строка для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "String")
        virtual void SerStr(char * Value, char * Name = "String") = 0;
        /// Чисто виртуальный метод, сериализующий логическую переменную.
        /// @param  Value – логическая переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Bool")
        virtual void SerBool(bool &Value, char * Name = "Bool") = 0;
        /// Чисто виртуальный метод, сериализующий целочисленную переменную.
        /// @param  Value – целочисленная переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Int")
        virtual void SerInt(int &Value, char * Name = "Int") = 0;
        /// Чисто виртуальный метод, сериализующий вещественную переменную.
        /// @param  Value – вещественная переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Float")
        virtual void SerFloat(float &Value, char * Name = "Float") = 0;
        /// Чисто виртуальный метод, сериализующий трехмерный вектор.
        /// @param  Value – трехмерный вектор для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Vector")
        virtual void SerVec(Vector3D &Value, char * Name = "Vector") = 0;
        /// Метод, сериализующий парасетры экрана.
        /// @param  Width – ширина экрана в пикселах
        /// @param  Height – высота экрана в пикселах
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Screen")
        void SerPic(int &Width, int &Height, char *Name = "Screen");
        /// Метод, сериализующий положение камеры.
        /// @param  Camera – трехмерный вектор для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Camera")
        void SerCam(Vector3D &Camera, char * Name = "Camera");
        /// Метод, сериализующий Материал объекта.
        /// @param  Material – параметр типа Материал для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Material")
        void SerMat(Mater &Material, char * Name = "Material");
        /// Метод, сериализующий Сферу.
        /// @param  Sph – параметр типа Сфера для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Sphere")
        void SerSph(Sphere &Sph, char *Name = "Sphere");
        /// Метод, сериализующий Тор.
        /// @param  Th – параметр типа Тор для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Thor")
        void SerThor(Thor &Th, char *Name = "Thor");
        /// Метод, сериализующий источник света.
        /// @param  Li – параметр типа Источник света для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Light")
        void SerLight(Light &Li, char *Name = "Light");

        /// Чисто виртуальный метод, заканчивающий сериализацию.
        virtual void End() = 0;
};


/**
@class XMLS
Производный класс от класса Serializer, отвечающий за сериализацию параметров сцены в XML файл,
содержит конструктор, деструктор, 3 члена данных, 7 методов.
*/
class XMLS : public Serializer
{
public:
        /// Конструктор
	XMLS();
        /// Деструктор
	~XMLS();

        /// Метод, начинающий сериализацию.
        /// @param  FileName – имя файла сериализации
        /// @return флаг - получилось ли начать сериализацию
        bool Start(QString FileName);

        /// Метод, сериализующий строку.
        /// @param  Value – строка для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "String")
        void SerStr(char * Value, char * Name = "String");
        /// Метод, сериализующий логическую переменную.
        /// @param  Value – логическая переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Bool")
        void SerBool(bool &Value, char * Name = "Bool");
        /// Метод, сериализующий целочисленную переменную.
        /// @param  Value – целочисленная переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Int")
        void SerInt(int &Value, char * Name = "Int");
        /// Метод, сериализующий вещественную переменную.
        /// @param  Value – вещественная переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Float")
        void SerFloat(float &Value, char * Name = "Float");
        /// Метод, сериализующий трехмерный вектор.
        /// @param  Value – трехмерный вектор для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Vector")
        void SerVec(Vector3D &Value, char * Name = "Vector");

        /// Метод, заканчивающий сериализацию.
        void End();
};

/**
@class XMLL
Производный класс от класса Serializer, отвечающий за получение параметров сцены из XML файла,
содержит конструктор, деструктор, 3 члена данных, 7 методов.
*/
class XMLL : public Serializer
{
public:
        /// Конструктор
        XMLL();
        /// Деструктор
        ~XMLL();

        /// Метод, начинающий сериализацию.
        /// @param  FileName – имя файла сериализации
        /// @return флаг - получилось ли начать сериализацию
        bool Start(QString FileName);

        /// Метод, сериализующий строку.
        /// @param  Value – строка для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "String")
        void SerStr(char * Value, char * Name = "String");
        /// Метод, сериализующий логическую переменную.
        /// @param  Value – логическая переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Bool")
        void SerBool(bool &Value, char * Name = "Bool");
        /// Метод, сериализующий целочисленную переменную.
        /// @param  Value – целочисленная переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Int")
        void SerInt(int &Value, char * Name = "Int");
        /// Метод, сериализующий вещественную переменную.
        /// @param  Value – вещественная переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Float")
        void SerFloat(float &Value, char * Name = "Float");
        /// Метод, сериализующий трехмерный вектор.
        /// @param  Value – трехмерный вектор для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Vector")
        void SerVec(Vector3D &Value, char * Name = "Vector");

        /// Метод, заканчивающий сериализацию.
        void End();
};

/**
@class BinS
Производный класс от класса Serializer, отвечающий за сериализацию параметров сцены в бинарный файл,
содержит конструктор, деструктор, 3 члена данных, 7 методов.
*/

class BinS : public Serializer
{
public:
    /// Конструктор
    BinS();
    /// Деструктор
    ~BinS();

        /// Метод, начинающий сериализацию.
        /// @param  FileName – имя файла сериализации
        /// @return флаг - получилось ли начать сериализацию
        bool Start(QString FileName);

        /// Метод, сериализующий строку.
        /// @param  Value – строка для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "String")
        void SerStr(char * Value, char * Name = "String");
        /// Метод, сериализующий логическую переменную.
        /// @param  Value – логическая переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Bool")
        void SerBool(bool &Value, char * Name = "Bool");
        /// Метод, сериализующий целочисленную переменную.
        /// @param  Value – целочисленная переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Int")
        void SerInt(int &Value, char * Name = "Int");
        /// Метод, сериализующий вещественную переменную.
        /// @param  Value – вещественная переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Float")
        void SerFloat(float &Value, char * Name = "Float");
        /// Метод, сериализующий трехмерный вектор.
        /// @param  Value – трехмерный вектор для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Vector")
        void SerVec(Vector3D &Value, char * Name = "Vector");

        /// Метод, заканчивающий сериализацию.
        void End();
};

/**
@class BinL
Производный класс от класса Serializer, отвечающий за получение параметров сцены из бинарного файла,
содержит конструктор, деструктор, 3 члена данных, 7 методов.
*/
class BinL : public Serializer
{
public:
    /// Конструктор
    BinL();
    /// Деструктор
    ~BinL();

        /// Метод, начинающий сериализацию.
        /// @param  FileName – имя файла сериализации
        /// @return флаг - получилось ли начать сериализацию
        bool Start(QString FileName);

        /// Метод, сериализующий строку.
        /// @param  Value – строка для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "String")
        void SerStr(char * Value, char * Name = "String");
        /// Метод, сериализующий логическую переменную.
        /// @param  Value – логическая переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Bool")
        void SerBool(bool &Value, char * Name = "Bool");
        /// Метод, сериализующий целочисленную переменную.
        /// @param  Value – целочисленная переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Int")
        void SerInt(int &Value, char * Name = "Int");
        /// Метод, сериализующий вещественную переменную.
        /// @param  Value – вещественная переменная для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Float")
        void SerFloat(float &Value, char * Name = "Float");
        /// Метод, сериализующий трехмерный вектор.
        /// @param  Value – трехмерный вектор для сериализации
        /// @param  Name – имя сериализуемого элемента(по умолчанию "Vector")
        void SerVec(Vector3D &Value, char * Name = "Vector");

        /// Метод, заканчивающий сериализацию.
        void End();
};
