#pragma once
#include "Jass.h"
#include "MyString.h"
#include "Additional_functions.h"

/*template <class T, size_t N>
struct Container {
	T containmentC[N];
	int vIndexC;
	T &operator[](size_t index)
	{
		vIndexC = index;
		return containmentC[index];
	};
	void operator = (sMyString& vMyString)
	{*/
		//if (vIndex < 0 || vIndex >= vLen) return;
		/*if (vData[vIndex] != NULL)
		{
			*vData[vIndex][0] = vMyArray.fGet(vMyArray.fIndex())[0][0];
			return;
		}
		T vMass;
		if (fSet(vIndex,(T)vMass) == true)
		{
			*vData[vIndex][0] = vMyArray.fGet(vMyArray.fIndex())[0][0];
			return;
		}*/
		/*return;
	};
};*/

template <class T, size_t N>//template<class T>
class sMyArray {
public:
	typedef sMyArray* PMyArray;
private:
	int vvi;
	static const int COUNT_MAX_SIZE_MASS = 8190;
	size_t vHashCode;
	string vStr;
    int vLen;
    //T **vData;
	bool vMassIsPresent[N];
	T **vData;
	int vIndex;
	T vMass;
	//int vIndex2;
	//bool vWait;
	//static const int vIntStrNull = 0x02;
	//string *vStrNull;
public:
	//void fNewMyArray(int vLen_2);
    sMyArray(void)
	{
		vMass[0] = NULL;
		vLen = N;
		vData = new T*[vLen];
		for (vvi = 0; vvi < vLen; vvi++)
		{
			vMassIsPresent[vvi] = false;
		}
	};
    //virtual ~sMyArray(void)
	~sMyArray()
	{
		if ((int)vData < 100) return;
		for (vvi = 0; vvi < vLen; vvi++)
		{
			if (!fNull((unsigned int)vData[vvi]) && !fNull((unsigned int)*(int*)vData[vvi]))
			{
				if (vMassIsPresent[vvi] == TRUE)
				{
					delete vData[vvi];
					//vData[vvi][0] = NULL;
					vData[vvi] = NULL;
					vMassIsPresent[vvi] = false;
				}
			}
			//if (vData[vvi] != NULL) delete vData[vvi];
		}
		delete vData;
		vData = NULL;
	};
    //~sMyArray();
	T* fGet(int vIndex)
	{
		/*if (vStrNull == NULL)
		{
			vStrNull = new string[2];
			*vStrNull[0] = (char)vIntStrNull;
			*vStrNull[1] = '\0';
		}*/
		if ((int)vData <= 100) return NULL;
		if (fNull((unsigned int)vData[vIndex])) return NULL;
		if (vIndex < 0 || vIndex >= vLen) return NULL;//(typeid(T).hash_code() == typeid(string).hash_code() ? "" : NULL);
		if (vData[vIndex] == NULL) return NULL;
		if (vMassIsPresent[vIndex] == FALSE) return NULL;
		return (T*)*vData[vIndex];
	};
	bool fSet(int vIndex, T vSet)
	{
		if ((int)vData < 100) return FALSE;
		if (vIndex < 0 || vIndex >= vLen) return FALSE;
		if (!fNull((unsigned int)vData[vIndex]))//if (vData[vIndex] != NULL)
		{
			if (vMassIsPresent[vIndex] == TRUE)
			{
				delete vData[vIndex][0];
				//vData[vIndex][0] = NULL;
				vData[vIndex] = NULL;
				vMassIsPresent[vIndex] = false;
			}
		}
		T* pMass = (T*)new T;
		vData[vIndex] = pMass;
		vMassIsPresent[vIndex] = true;
		/*if(typeid(T).hash_code() == typeid(string[1]).hash_code())
		{
			vStr = (string)vSet[0];
			string vMassStr[1];
			vMassStr[0] = fCpyStr(vStr);
			string * pMassStr;
			pMassStr = vMassStr;
			*vData[vIndex][0] = ((T*)pMassStr)[0][0];
		}
		else
		{*/
			*vData[vIndex][0] = vSet[0];
		//}
		return TRUE;
	};
	int fLength()
	{
		return vLen;
	};
	/*sMyArray(int vLen_2)
	{
		if (vLen_2 < 1 || vLen_2 > COUNT_MAX_SIZE_MASS) return;
		vLen = vLen_2;
		vData = new T*[vLen];
		for (vvi = 0; vvi < vLen; vvi++)
		{
			vData[vvi] = NULL;
		}
	};*/
	/*sMyArray(const sMyArray& vMyArray)
	{
		if (vMyArray.fLength() < 1 || vMyArray.fLength() > COUNT_MAX_SIZE_MASS) return;
		vLen = vMyArray.fLength();
		vData = new T*[vLen];*/
		/*for (vvi = 0; vvi < vLen; vvi++)
		{
			vData[vvi] = vMyArray[vvi];
		}*/
	//};
	// а вот и наш вариантный прокси
    /*struct proxy_value
    {
        sMyArray const* host_;
        int index_;
        proxy_value(sMyArray* host, int index) : host_(host), index_(index) {}
        
        operator T() const { return host_->fGet<T>(index); }
    };
    
    proxy_value operator[] (int index) const
	{
		this->vIndex = index;
		return proxy_value(this,index);
	};*/
	/*void operator delete(void* pMyArray)
	{
		::operator delete(pMyArray);
	};*/
	T &operator[](size_t vIndex)
	{
		if ((int)vData < 100) return vMass;
		this->vIndex = vIndex;
		if (vIndex < 0 || vIndex >= vLen) return vMass;
		if (vMassIsPresent[vIndex] == true &&
			!fNull((unsigned int)vData[vIndex]))//if (vData[vIndex] != NULL)
		{
			return *fGet(vIndex);
		}
		if (fSet(vIndex,vMass) == false)
		{
			return vMass;
		}
		return *fGet(vIndex);
	};
	/*T& operator[](int vIndex)
	{
		this->vIndex = vIndex;
		if (vData[vIndex] != NULL)
		{
			return fGet(vIndex);
		}
		if (fSet(vIndex,(T)NULL) == false)
		{
			return (T)NULL;
		}
		return fGet(vIndex);
	};*/
	/*const T &operator[](size_t vIndex) const
	{
		if ((int)vData < 100) return vMass;
		if (vIndex < 0 || vIndex >= vLen) return vMass;
		this->vIndex = vIndex;
		if (!fNull((unsigned int)vData[vIndex]))//if (vData[vIndex] != NULL)
		{
			return *fGet(vIndex);
		}
		return vMass;
	};*/
	/*void operator = (T& vT2)
	{
		if (vIndex < 0 || vIndex >= vLen) return;
		//this[vIndex] = vT2;
		if (fSet(vIndex,vT2) == false)
		{
			return;
		}
	};
	void operator = (const char *vStr2)
	{
		fSetStr(vStr2);
	};
	void operator = (char *vStr2)
	{
		fSetStr(vStr2);
	};
	void fSetStr(char *vStr2)
	{
		if (vIndex < 0 || vIndex >= vLen) return;
		//this[vIndex] = sMyString(vStr2);
		if (fSet(vIndex,sMyString(vStr2)) == false)
		{
			return;
		}
	};*/
	/*void operator = (sMyArray& vMyArray)
	{
		if (*vIndex < 0 || *vIndex >= vLen) return;
		if (vData[*vIndex] != NULL)
		{
			*vData[*vIndex][0] = vMyArray.fGet(vMyArray.fIndex())[0][0];
			return;
		}
		T vMass;
		if (fSet(*vIndex,(T)vMass) == true)
		{
			*vData[*vIndex][0] = vMyArray.fGet(vMyArray.fIndex())[0][0];
			return;
		}
		return;
	};*/
	int fIndex()
	{
		return vIndex;
	};
	/*void operator sMyString()
	{
	};
	void operator char *()
	{
	};*/
	//void * operator new(size_t vSize_2);
	//void operator delete(void* pMyArray);
};