#ifndef structsH
#define structsH
//------------------------------------------------------------------------------
#include "stdio.h"
//------------------------------------------------------------------------------
typedef unsigned char uint1;
//------------------------------------------------------------------------------
//цвет с прозрачностью
	struct RfColorRGBA
	{
		float r,g,b,a;
	};
//------------------------------------------------------------------------------
//Плоскость (a,b,c,d - коэфициенты уравнения плоскости)
	struct RfPlaneABCD
	{	float a,b,c,d;
	};
//------------------------------------------------------------------------------
//точка в 3d (если в 0,0,0 начало а это конец то можно назвать вектором)
	struct RfPointXYZ
	{	float x,y,z;
	};
//------------------------------------------------------------------------------
//точка в 3d (если в 0,0,0 начало а это конец то можно назвать вектором)
	struct RcPointXYZ
	{	signed char x,y,z;
	};
//------------------------------------------------------------------------------
//точка в 2d
	struct RfPointXY
	{	float x,y;
	};
//------------------------------------------------------------------------------
	struct RfPointXYZA
	{	RfPointXYZ Point;
		float angle;
	};
//------------------------------------------------------------------------------
	struct RdPointXYZ
	{	double x,y,z;
	};
//------------------------------------------------------------------------------
	struct RdPointXY
	{	double x,y;
	};
//------------------------------------------------------------------------------
	struct RiPointXY
	{	signed int x,y;
	};
//------------------------------------------------------------------------------
	struct RuiPointXY
	{	unsigned int x,y;
	};
//------------------------------------------------------------------------------
	struct RiPointXYZ
	{	int x,y,z;
	};
//------------------------------------------------------------------------------
//рёбра для трёх угольника
	struct RiFacesABC
	{	unsigned int a,b,c;
	};
//------------------------------------------------------------------------------
//рёбра для трёх угольника 16 бит макс 65535 точек
	struct RsFacesABC
	{	unsigned short a,b,c;
	};
//------------------------------------------------------------------------------
//рёбра для четырёх угольника 16 бит макс 65535 точек
	struct RsFacesABCD
	{	unsigned short a,b,c,d;
	};
//------------------------------------------------------------------------------
//использую при разбиении точек по сглаж группе ребра
	struct RbFaceABC
	{
		bool a,b,c;
	};
//------------------------------------------------------------------------------
//вектор (нормаль)
	struct TVector
	{	float x,y,z;
	};
//------------------------------------------------------------------------------
/*	struct TGooglePoint
	{
		int x,y;
		//unsigned int mat;
		RfPointXYZ p1,p2,p3,p4; //координаты краёв квадрата (север в верху против часовой с левого нижнего угла)
		RfPointXYZ pn; //нормаль
		RfPointXY pm1,pm2,pm3,pm4; //координаты материала для каждой точки
	};*/
//------------------------------------------------------------------------------
	//Элемент односвязного списка
	struct RListOne
	{
		RListOne* next; //ссылка на следующий
		unsigned size; //размер данных
		unsigned char* data; //данные
	};
//------------------------------------------------------------------------------
	//номер точки и угол для делоне
	struct RSotrPoint
	{
		int n;
		float angle;
	};
//------------------------------------------------------------------------------
	//треугольник для делоне
	struct RTriangle
	{
		bool del;
		int pnt[3]; //номера точек из списка для построения рёбер
		double cr[3]; //растояния до центральной точки
		RfPointXYZ center; //центральная точка круга при преобразовании по Делоне
		float r;

		//ниже идут переменные ни как не относящиеся к триангуляции Делоне
//		centerMAP :RfPointXYZ; //центральная точка по картовым
		RfPointXYZ centerGPS; //центральная точка по GPS
	};
//------------------------------------------------------------------------------
/*class TCheckData
{
public:
	void OnTime();
};*/
//------------------------------------------------------------------------------
//Расширяемый массив элементов, может выступать в качестве родителя те. удалять элементы при уничтожении списка или при удалении элемента из списка
//Если заданна потоко безопасность то все действия помещаются в критическую секцию
template <class T> class TSimpleList
{
private:
	T* f_NULL; //Чтобы вернуть  NULL если вышел за пределы массива
	T* List; //массив элементов
	unsigned int f_size;//размер массива (без учёта занятых позиций)
	unsigned int f_count;//количество элементов
	unsigned int f_step;//шаг увеличения массива
	//wxCriticalSection* f_critsect;
public:
	bool f_owner; //являеться ли владельцем элементов данный списк

	TSimpleList(unsigned int step=10,bool owner=false/*,bool crit*/)
	{
		if(step==0)step=1;
		f_step=step;
		List=new T[f_step];
		f_size=f_step;
		f_count=0;
		f_owner=owner;
		//if (crit) f_critsect=new wxCriticalSection(); else f_critsect=NULL;
		f_NULL=NULL;
	};
	~TSimpleList()
	{
		if(f_owner) 
			for(unsigned int i=0;i<f_count;i++) 
				delete List[i];
		delete[] List;
	};
	void setSize(unsigned int size) //Заранее задать размер массива
	{
		if(size>f_size)
		{
			T* buf=new T[size];
			for(unsigned int i=0;i<f_count;i++) buf[i]=List[i];
			T* buf0=List; //На всякслучай
			List=buf;
			f_size=size;
			delete buf0;
		}
	};
	unsigned int count() 
	{
		return f_count;
	};
	//Добавить элемент в конец массива
	T add(T item)
	{
		if(f_count<f_size) List[f_count++]=item; 
		else
		{
			T* buf=new T[f_size+=f_step];
			for(unsigned int i=0;i<=f_count;i++) buf[i]=List[i];
			T* buf0=List;
			List=buf;
			delete[] buf0;
			List[f_count++]=item;
		}
		return item;
	};
	T insert(T item,unsigned int pos) //pos - 0..XXX
	{
		if(pos>=f_count)
		{
			if(pos<f_size){List[pos]=item; f_count=pos+1;} //в пустую область
			else //в не выделенную область
			{
				T* buf=new T[pos+1];
				for(unsigned int i=0;i<=f_count;i++) buf[i]=List[i];
				T* buf0=List;
				List=buf;
				delete[] buf0;
				List[pos]=item;
				f_count=pos+1;
			}
		}else//сдвинуть имеющиеся
		{
			add(List[f_count-1]);
			for(unsigned int i=f_count-2;i>pos;i--) 
				List[i]=List[i-1];
			List[pos]=item;
		}
		return item;
	};
	void del(T item) //удаляем элемент и сдвигаем все элементы на 1 в лево
	{
		unsigned int cnt=0;
		bool b=false;
		for(unsigned int i=0;i<f_count;i++)
		{
			//if(List[i]==item){cnt--; b=true;}
			if(List[i]==item){b=true; continue;}
			List[cnt]=List[i];
			cnt++;
		}
		if(b)
		{
			f_count--;
			if(f_owner)delete item;
		}
	};
	bool del(unsigned int pos) //удаляем элемент и сдвигаем все элементы на 1 в лево
	{
		if(pos>=f_count)return false;
		f_count--;
		if(f_owner) delete List[pos];
		for(unsigned int i=pos;i<f_count;i++) List[i]=List[i+1];
		return true;
	};
	bool rem(unsigned int pos) { //Исключить из списка без попытки удаления
		if (pos >= f_count)return false;
		f_count--;
		//if (f_owner) delete List[pos];
		for (unsigned int i = pos; i<f_count; i++) List[i] = List[i + 1];
		return true;
	}
	T& get(unsigned int i)
	{	if(i>=f_count) {return (T&)f_NULL;} 
		return List[i];
	};
	T& operator[](unsigned int i)
	{	if(i>=f_count) {return (T&)f_NULL;}  
		return List[i];
	};
	bool Pos(T item,unsigned int &pos) //Узнать позицию элемента в массиве
	{
		for(unsigned int i=0;i<f_count;i++)
			if(List[i]==item) { pos=i; return true; }
		return false;
	};
	//Очистить массив с уменьшением размерности до одного шага увеличения массива (если владелец удалить элементы)
	void clear()
	{
		unsigned int cnt=f_count; 
		f_count=0;
		if(f_owner) for(unsigned int i=0;i<cnt;i++)	delete List[i];
		T* tmp=List;
		f_size=f_step;
		List=new T[f_step];
		delete[] tmp;
	};
};
//------------------------------------------------------------------------------
//простой список не являющийся владельцем своих элементов (можно задавать реальные обьекты а не ссылки)
template <class T> class TSimpleList2
{
private:
	T* List; //массив элементов
	unsigned int f_size;//размер массива
	unsigned int f_count;//количество элементов
	unsigned int f_step;//шаг увеличения массива
public:
	TSimpleList2() //Для использования конструктора по умолчанию
	{
		f_step=10;
		List=new T[f_step];
		f_size=f_step;
		f_count=0;
	};

	TSimpleList2(unsigned int step)
	{
		if(step==0)step=1;
		f_step=step;
		List=new T[f_step];
		f_size=f_step;
		f_count=0;
	};

	~TSimpleList2()
	{
		delete[] List;
	};
	unsigned int count() 
	{
		return f_count;
	};
	void add(T item)
	{
		if(f_count<f_size)
		{
			List[f_count]=item; 
			f_count++;
		}
		else
		{
			T* buf=new T[f_size+=f_step];
			for(unsigned int i=0;i<=f_count;i++) buf[i]=List[i];
			T* buf0=List;
			List=buf;
			delete[] buf0;
			List[f_count]=item;
			f_count++;
		}
	};
	void del(T item) //удаляем элемент и сдвигаем все элементы на 1 в лево
	{
		unsigned int cnt=0;
		bool b=false;
		for(unsigned int i=0;i<f_count;i++)
		{
			//if(List[i]==item){cnt--; b=true;}
			if(List[i]==item){b=true; continue;}
			List[cnt]=List[i];
			cnt++;
		}
		if(b)
		{
			f_count--;
		}
	};
	bool del(unsigned int pos) //удаляем элемент и сдвигаем все элементы на 1 в лево
	{
		if(pos>=f_count)return false;
		f_count--;
		for(unsigned int i=pos;i<f_count;i++) List[i]=List[i+1];
		return true;
	};
	T& get(unsigned int i){return List[i];};
	T& operator[](unsigned int i){return List[i];};
	bool Position(T item, unsigned int &pos) //Найти позицию элемента в списке перебором
	{
		for(unsigned int i=0;i<f_count;i++)
			if(List[i]==item) { pos=i; return true; }
		return false;
	};
	void clear()
	{
		unsigned int cnt=f_count;
		f_count=0;
		T* tmp=List;
		f_size=f_step;
		List=new T[f_step];
		delete[] tmp;
	};
};
//------------------------------------------------------------------------------

#endif
