// ################################
// ##  Obecna sablona pro listy  ##
// ##      hernich objektu       ##
// ################################

#pragma once
#ifndef CACHE_LIST_H
#define CACHE_LIST_H

#include "common.h"

#include <set>
#include <vector>
#include <deque>
#include <map>

#include "error_handling.h"
#include "independent_constants.h"

// ################################
// ################################

#define NOT_VALID_ID   0

// ################################
// ################################

class dataListObjectClass
{
// tahle trida by asi mela umet neco jako load data from db
// to loadovani z db by mela byt polymorfni funce , kazdy potomek bude mit jinou
protected:
	dtIdentifier   ID_;
public:
	dataListObjectClass()                  { ID_ = NOT_VALID_ID;  };
	virtual       ~dataListObjectClass()   {                      };

	void           setID(unsigned long ID) { ID_ = ID;            };
	unsigned long  getID() const           { return ID_;          };

	virtual void          DB_Load       (  unsigned long ID                ) {  errLogicalError("DB load data function in this class is not implemented");   };
	virtual void          DB_Save       (  unsigned long ID                ) {  errLogicalError("DB store data function in this class is not implemented");  };
	virtual void          DB_Insert     (  unsigned long ID                ) {  errLogicalError("DB insert data function in this class is not implemented"); };

	virtual void          DB_TLoad      (                                  ) {  DB_Load(ID_);           };
	virtual void          DB_TSave      (                                  ) {  DB_Save(ID_);           };
	virtual void          DB_TInsert    (                                  ) {  DB_Insert(ID_);         };

    virtual void          UpdateEvents  (                                  ) {                          };               
};

// ################################
// ################################

enum dataListObjectType
{
    DATA_IS_EMPTY               = 1,
    DATA_IN_DATABASE_ONLY       = 2,
    DATA_IN_MEMORY_ONLY         = 3,
    DATA_IN_DATABASE_INVALID    = 4,
    DATA_SYNCHRONIZED           = 5,
    DATA_DESYNCHRONIZED         = 6
};


class cacheListClass
{
protected:
    typedef std :: pair<dataListObjectType, dataListObjectClass   *>    typedDataListObjectClassPPair;
    typedef std :: vector<typedDataListObjectClassPPair >               typedDataListObjectClassPPairVector;
    typedef std :: set<dtIdentifier               >                     dtIdentifierSet;

	typedDataListObjectClassPPairVector data;
	dtIdentifierSet                     freeIDs;

    virtual  bool isPositionValid                 (dtIdentifier position) const;
    virtual  bool containsData                    (dtIdentifier id                 ) const;
    virtual  dtIdentifier alloc                   ( void                           );
    virtual  bool identifiersReusable             ( void                           ) const { return false; };
    virtual  void expand                          (dtIdentifier id, bool fillFreeId);

	virtual  void           DB_Load               (  unsigned long ID              ) { errLogicalError("DB LOAD NOT IMPLEMENTED"); };
	virtual  void           DB_Insert             (dataListObjectClass* newItem);
	virtual  void           DB_Remove             (  unsigned long ID              ) { errLogicalError("DB REMOVE NOT IMPLEMENTED"); };

	virtual dataListObjectClass * operator []     (unsigned long position          );
	// tohle je private, aby se to nemohlo volat kdekoliv a byl tim vynucen dynamic_cast pomoci getItem
public:
	virtual ~cacheListClass();

    virtual dtIdentifier            insertItem            (dataListObjectClass * newItem);
    virtual void                    deleteItem            (dtIdentifier          id     );
    virtual dataListObjectClass *   access                (dtIdentifier          id     );
    virtual void                    synchronize           (void                         );

    virtual void  DB_Initialize                           (         void                ) { errLogicalError("DB INITIALIZE NOT IMPLEMENTED"); };

    template<typename T>
    T* getItem (unsigned long position) { return dynamic_cast<T*>( operator [](position)); }
    void          getObjectIds                 (std :: deque<dtIdentifier>& ids );
    virtual void  updateEvents                 (void                            ) {} ;
	
	size_t getSize() { return data.size(); }
};

class cacheListEventInitializableClass : public cacheListClass
{
public:
    virtual void  updateEvents                 (void                            );
};

// ################################
// ################################

class cacheRealmsListClass : public cacheListClass
{
private:
    std :: map<std :: string, dtIdentifier> logins;
    std :: map<std :: string, dtIdentifier> names;

	void DB_IternalLoadFromQuery( unsigned long ID );
	virtual  void        DB_Load               (  unsigned long ID              ) sealed;
	virtual  void        DB_Remove             (  unsigned long ID              ) sealed;
public:
    virtual dtIdentifier            insertItem            (dataListObjectClass * newItem);
    virtual void                    deleteItem            (dtIdentifier          id     );

    virtual  void  DB_Initialize (void) sealed;
    unsigned long idByLogin (  const std :: string& login);
    unsigned long idByName  (  const std :: string& login);

    bool loginExists        (  const std :: string& login);
    bool nameExists         (  const std :: string& name);

	virtual ~cacheRealmsListClass() {};
};

// ################################
// ################################

class cacheFortressesListClass : public cacheListEventInitializableClass
{
private:
	void DB_IternalLoadFromQuery( unsigned long ID );
	virtual  void        DB_Load               (  unsigned long ID              ) sealed;
	virtual  void        DB_Remove             (  unsigned long ID              ) sealed;
public:
    virtual  void  DB_Initialize (void) sealed;
	virtual ~cacheFortressesListClass() {};
};

// ################################
// ################################

class cacheFortressClassesListClass : public cacheListClass
{
private:
	virtual  void        DB_Load               (  unsigned long ID              ) sealed;
	virtual  void        DB_Remove             (  unsigned long ID              ) sealed;
public:
    virtual  void  DB_Initialize (void);
	virtual ~cacheFortressClassesListClass() {};
};

// ################################
// ################################

class cacheItemsListClass : public cacheListClass
{
private:
	void DB_IternalLoadFromQuery( unsigned long ID );
	virtual  void        DB_Load               (  unsigned long ID              ) sealed;
	virtual  void        DB_Remove             (  unsigned long ID              ) sealed;

    virtual  bool identifiersReusable             ( void                           ) const { return true; };
public:
    virtual  void  DB_Initialize (void);
	virtual             ~cacheItemsListClass() {};
};

// ################################
// ################################

class cacheItemsPatternsListClass : public cacheListClass
{
public:
    virtual  void                    synchronize           (void                         ) {};
    virtual  void  DB_Initialize (void) sealed;
	virtual  void        DB_Load               (  unsigned long ID              ) sealed;
	virtual             ~cacheItemsPatternsListClass() {};
};

// ################################
// ################################

class cacheNullItemsListClass : public cacheListClass
{
protected:
	virtual dataListObjectClass * operator []  (unsigned long position          );
public:
    virtual void  DB_Initialize                (         void                   ) {}; // nahrava se staticky
	virtual ~cacheNullItemsListClass() {};

    virtual dtIdentifier            insertItem            (dataListObjectClass * newItem) { return 0;    };
    virtual void                    deleteItem            (dtIdentifier          id     ) {};
    virtual dataListObjectClass *   access                (dtIdentifier          id     ) { return NULL; };
    virtual void                    synchronize           (void                         ) {};
};

// ################################
// ################################

class cacheSpaceObjectListClass : public cacheListClass
{
private:
	void DB_IternalLoadFromQuery( unsigned long ID );
	virtual  void        DB_Load               (  unsigned long ID              ) sealed;
	virtual  void        DB_Remove             (  unsigned long ID              ) sealed;
public:
	virtual ~cacheSpaceObjectListClass() {};
    virtual void  DB_Initialize                (           void                 ) sealed;
    virtual dataListObjectClass *   access     (dtIdentifier          id        ) sealed;
};


// ################################
// ################################

#endif