#ifndef Array_H
#define Array_H

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

namespace Framework
{
	class IntArray
	{
	private:
		int This;
		IntArray *next;

	public:
		// Konstruktor 
		IntArray();
		// Destruktor 
		~IntArray();
		// nicht constant 
		void addInt( int i, int index, int null ); // fügt i bei endex ein
		void addInt( int i ); // fügt i hinzu
		void setInt( int i, int index, int null ); // setzt das index - te int zu i
		void löscheInt( int index, int null ); // löscht das index - te int
		void tauschInt( int vindex, int nindex ); // löscht das index - te int
		void setNext( IntArray *n ); // setzt den next Zeiger auf n
		int getInt( int index, int null ); // gibt das index - te int zurück
		void deleteAll(); // gibt den Speicher frei
		IntArray *release(); // gibt den Speicher frei
		// constant 
		int zThis() const; // gibt This zurück
		IntArray *zNext() const; // gibt den next Zeiger zurück
	};
	
	class Int64Array
	{
	private:
		__int64 This;
		Int64Array *next;

	public:
		// Konstruktor 
		Int64Array();
		// Destruktor 
		~Int64Array();
		// nicht constant 
		void addInt( __int64 i, int index, int null ); // fügt i bei endex ein
		void setInt( __int64 i, int index, int null ); // setzt das index - te int zu i
		void löscheInt( int index, int null ); // löscht das index - te int
		void tauschInt( int vindex, int nindex ); // löscht das index - te int
		void setNext( Int64Array *n ); // setzt den next Zeiger auf n
		__int64 getInt( int index, int null ); // gibt das index - te int zurück
		void deleteAll(); // gibt den Speicher frei
		Int64Array *release(); // gibt den Speicher frei
		// constant 
		__int64 zThis() const; // gibt This zurück
		Int64Array *zNext() const; // gibt den next Zeiger zurück
	};

	class DoubleArray
	{
	private:
		double This;
		DoubleArray *next;

	public:
		// Konstruktor 
		DoubleArray();
		// Destruktor 
		~DoubleArray();
		// nicht constant 
		void addDouble( double i, int index, int null ); // fügt i bei endex ein
		void setDouble( double i, int index, int null ); // setzt das index - te int zu i
		void löscheDouble( int index, int null ); // löscht das index - te int
		void tauschDouble( int vindex, int nindex ); // löscht das index - te int
		void setNext( DoubleArray *n ); // setzt den next Zeiger auf n
		double getDouble( int index, int null ); // gibt das index - te int zurück
		void deleteAll(); // gibt den Speicher frei
		DoubleArray *release();
		// constant 
		double zThis() const; // gibt This zurück
		DoubleArray *zNext() const; // gibt den next Zeiger zurück
	};

	template< class TYPE >
	class Array
	{
	private:
		TYPE This;
		Array<TYPE> *next;

	public:
		// Konstruktor 
		Array()
		{
			next = 0;
		}

		// Destruktor 
		~Array()
		{
			if( next )
				delete next;
		}

		// nicht constant 
		void add( TYPE t, int index, int null ) // fügt t bei endex ein
		{
			if( index == null )
			{
				Array<TYPE> *tmp = next;
				next = new Array<TYPE>();
				next->setNext( tmp );
				next->set( This, 0, 0 );
				This = t;
				return;
			}
			if( !next )
				next = new Array<TYPE>();
			next->add( t, index, null + 1 );
		}

		void set( TYPE t, int index, int null ) // setzt den index - ten T zu t
		{
			if( index == null )
			{
				This = t;
				return;
			}
			if( !next )
				next = new Array<TYPE>();
			next->set( t, index, null + 1 );
		}

		void lösche( int index, int null ) // löscht den index - ten T
		{
			if( index == null )
			{
				if( next )
				{
					This = next->getThis();
					Array<TYPE> *tmp = next->zNext();
					next->setNext( 0 );
					delete next;
					next = tmp;
				}
				return;
			}
			if( !next )
				next = new Array<TYPE>();
			next->lösche( index, null + 1 );
		}

		void tausch( int vindex, int nindex ) // vertauscht den vindex - ten T und den nindex - ten T
		{
			TYPE tmp = get( nindex, 0 );
			set( get( vindex, 0 ), nindex, 0 );
			set( tmp, vindex, 0 );
		}

		void setNext( Array<TYPE> *n ) // setzt den next Zeiger auf n
		{
			next = n;
		}

		TYPE get( int index, int null ) // gibt den index - ten T zurück
		{
			if( index == null )
			{
				return This;
			}
			if( !next )
				next = new Array<TYPE>();
			return next->get( index, null + 1 );
		}

		void deleteAll() // gibt den Speicher frei
		{
			if( next )
				next->deleteAll();
			delete next;
			next = 0;
		}

		Array<TYPE> *release()
		{
			if( next )
				next = next->release();
			delete this;
			return 0;
		}

		// constant 
		TYPE getThis() const // gibt This zurück
		{
			return This;
		}

		Array<TYPE> *zNext() const // gibt den next Zeiger zurück
		{
			return next;
		}
	};

	template< class TYPE >
	class TArray
	{
	private:
		TYPE *This;
		TArray<TYPE> *next;

	public:
		// Konstruktor 
		TArray()
		{
			This = 0;
			next = 0;
		}

		// Destruktor 
		~TArray()
		{
			if( next )
				delete next;
		}

		// nicht constant 
		void add( TYPE *t, int index, int null ) // fügt t bei endex ein
		{
			if( index == null )
			{
				TArray<TYPE> *tmp = next;
				next = new TArray<TYPE>();
				next->setNext( tmp );
				next->set( This, 0, 0 );
				This = t;
				return;
			}
			if( !next )
				next = new TArray<TYPE>();
			next->add( t, index, null + 1 );
		}

		void set( TYPE *t, int index, int null ) // setzt den index - ten T zu t
		{
			if( index == null )
			{
				if( This )
					This->release();
				This = t;
				return;
			}
			if( !next )
				next = new TArray<TYPE>();
			next->set( t, index, null + 1 );
		}

		void lösche( int index, int null ) // löscht den index - ten T
		{
			if( index == null )
			{
				if( This )
					This = This->release();
				if( next )
				{
					This = next->zThis();
					TArray<TYPE> *tmp = next->zNext();
					next->setNext( 0 );
					delete next;
					next = tmp;
				}
				return;
			}
			if( !next )
				next = new TArray<TYPE>();
			next->lösche( index, null + 1 );
		}

		void tausch( int vindex, int nindex ) // vertauscht den vindex - ten T und den nindex - ten T
		{
			TYPE *tmp = get( nindex, 0 );
			set( get( vindex, 0 ), nindex, 0 );
			set( tmp, vindex, 0 );
		}

		void setNext( TArray<TYPE> *n ) // setzt den next Zeiger auf n
		{
			next = n;
		}

		TYPE *get( int index, int null ) // gibt den index - ten T zurück
		{
			if( index == null )
			{
				if( !This )
					return 0;
				return This->getThis();
			}
			if( !next )
				next = new TArray<TYPE>();
			return next->get( index, null + 1 );
		}

		TYPE *z( int index, int null )
		{
			if( index == null )
				return This;
			if( !next )
				next = new TArray<TYPE>();
			return next->z( index, null + 1 );
		}

		void deleteAll() // gibt den Speicher frei
		{
			if( This )
				This = This->release();
			if( next )
				next->deleteAll();
			delete next;
			next = 0;
		}

		TArray<TYPE> *release()
		{
			if( This )
				This = This->release();
			if( next )
				next = next->release();
			delete this;
			return 0;
		}

		// constant 
		TYPE *zThis() const // gibt This zurück
		{
			return This;
		}

		TArray<TYPE> *zNext() const // gibt den next Zeiger zurück
		{
			return next;
		}
	};

	template< class TYPE >
	class ZTArray
	{
	private:
		TYPE *This;
		ZTArray<TYPE> *next;

	public:
		// Konstruktor 
		ZTArray()
		{
			This = 0;
			next = 0;
		}

		// Destruktor 
		~ZTArray()
		{
			if( next )
				delete next;
		}

		// nicht constant 
		void add( TYPE *zT, int index, int null ) // fügt zT bei endex ein
		{
			if( index == null )
			{
				ZTArray<TYPE> *tmp = next;
				next = new ZTArray<TYPE>();
				next->setNext( tmp );
				next->set( This, 0, 0 );
				This = zT;
				return;
			}
			if( !next )
				next = new ZTArray<TYPE>();
			next->add( zT, index, null + 1 );
		}

		void set( TYPE *zT, int index, int null ) // setzt den index - ten Zeiger zu zT
		{
			if( index == null )
			{
				This = zT;
				return;
			}
			if( !next )
				next = new ZTArray<TYPE>();
			next->set( zT, index, null + 1 );
		}

		void lösche( int index, int null ) // löscht den index - ten Zeiger
		{
			if( index == null )
			{
				This = 0;
				if( next )
				{
					This = next->zThis();
					ZTArray<TYPE> *tmp = next->zNext();
					next->setNext( 0 );
					delete next;
					next = tmp;
				}
				return;
			}
			if( !next )
				next = new ZTArray<TYPE>();
			next->lösche( index, null + 1 );
		}

		void tausch( int vindex, int nindex ) // vertauscht den vindex - ten Zeiger und den nindex - ten Zeiger
		{
			TYPE *tmp = z( nindex, 0 );
			set( z( vindex, 0 ), nindex, 0 );
			set( tmp, vindex, 0 );
		}

		void setNext( ZTArray<TYPE> *n ) // setzt den next Zeiger auf n
		{
			next = n;
		}

		TYPE *z( int index, int null ) // gibt den index - ten Zeiger zurück
		{
			if( index == null )
				return This;
			if( !next )
				next = new ZTArray<TYPE>();
			return next->z( index, null + 1 );
		}

		void deleteAll() // gibt den Speicher frei
		{
			This = 0;
			if( next )
				next->deleteAll();
			delete next;
			next = 0;
		}

		ZTArray<TYPE> *release()
		{
			This = 0;
			if( next )
				next = next->release();
			delete this;
			return 0;
		}

		// constant 
		TYPE *zThis() const // gibt This zurück
		{
			return This;
		}

		ZTArray<TYPE> *zNext() const // gibt den next Zeiger zurück
		{
			return next;
		}
	};
}

#endif