#pragma once

#include "abstractfactory.h"
#include <QObject>
#include <QString>
#include <QImage>
#include <iostream>
#include <vector>

class Effect;

class Cell;

class Unit : public QObject {
    Q_OBJECT

public:
    explicit Unit(QString parameters);

    virtual ~Unit() {}

    //---------------------------------------------//
    //---------Basic traits getters section--------//
    //---------------------------------------------//

	double getExperience();
    int getLevel();
    int getInitiative();

    int getIntelligence();
    int getStrength();
    int getAgility();

    int getActivityPoints();
    int getStartingActivityPoints();

    int getHealthPoints();
  	void setHealthPoints(int value);
    int getMaxHealthPoints();

    int getMagicDefence();
    int getPhysicDefence();

    int getCost();
    void setCost(int value);
    virtual bool isCharacter();

    std::vector<QString> getParentSpecs();
    std::vector<QString> getUpgradeSpecs();

    //---------------------------------------------//
    //------------Unit location section------------//
    //---------------------------------------------//

    Cell* getLocation();
    void setLocation(Cell* to);

	double getRealX();
	void setRealX(double x);

	double getRealY();
	void setRealY(double y);

    //---------------------------------------------//
    //--------Effect processing & calling----------//
    //---------------------------------------------//

    void operateEffectList();

    void add(Effect*);

    void remove(std::vector<Effect*>::iterator);

    void remove(Effect*);

    std::vector<Effect*>::iterator beginIteratorEffectsList();

    std::vector<Effect*>::iterator endIteratorEffectsList();

    //---------------------------------------------//
    //----------------GUI section------------------//
    //---------------------------------------------//

    QString getUnitId() const;
    QString getUnitName() const;
    QString getUnitDescr() const;
    QString getUnitBaseClassId() const;
    std::vector<QString> getUnitTraits() const;
    QImage getUnitIcon() const;

    //---------------------------------------------//
    //-----------Parameters load section-----------//
    //---------------------------------------------//

private:
    void loadUnitName(QString unit_folder);
    void loadUnitDescr(QString unit_folder);
    void loadUnitBaseClass(QString unit_folder);
    void loadUnitTraits(QString unit_folder);
    void loadUnitIcon(QString unit_folder);
    void loadUnitPrevSpecs(QString unit_folder);
    void loadUnitUpgradeSpecs(QString unit_folder);

public:
    bool operator <(const Unit &b) {
        if (base_class_id_ != b.base_class_id_)
            return base_class_id_ < b.base_class_id_;
        return unit_id_ < b.unit_id_;
    }

protected:
    std::vector <Effect*> effects_;

    //personal information
    int cost_;

    std::vector<QString> parent_specs_;
    std::vector<QString> upgrade_specs_;

    double experience_;
    int level_;
    std::string race_; //lower case

    //actions and events
    double initiative_;
    int activity_points_;

    //movement
    Cell* location_;
    double real_x_;
    double real_y_;

    //attack action
    int agility_;
    int intelligence_;
    int strength_;
    int starting_activity_points_;

    //durability
    int health_points_;
    int max_health_points_;
    int magic_defence_;  //less or equal 40
    int physic_defence_; //less or equal 40

    // GUI values
    QString race_id_;
    QString unit_id_;

    QString unit_name_;
    QString unit_descr_;
    QString base_class_id_;
    QImage unit_icon_;
};
