
#ifndef ArrayHPP
#define ArrayHPP

template<class genType>
class TArray
{
	private:
		genType *Array; // allocated on heap
		static const long kArrInitSize = 5;
		long ArrDefaultSize;
		long ArrSize; // no longer const
		long LastAdded;
	public:
		TArray( long default_size = kArrInitSize);
		virtual ~TArray();
		
		void	set( long idx, genType item );
		void	add( genType item );
		long	getSize();
		genType getNthElement( long elementToFind );
		void	clear();
		long	binarySearch( genType whatToFind );
		/*
		genType*	find( genType* );
		short			isEmpty();
		short			isInArray( genType* );
		genType*	getFirst();
		genType*	getLast();
		*/
};

template<class genType>
TArray<genType>::TArray( long default_size )
{
	ArrDefaultSize = default_size;  // no longer const
	ArrSize = ArrDefaultSize;
	Array = new genType[ArrSize];			// allocated on heap
	LastAdded = 0;
}

template<class genType>
TArray<genType>::~TArray()
{
	this->clear();
}

template<class genType>
void TArray<genType>::clear()
{
	delete [] Array; // does not delete elements!
	ArrSize = 0;
	LastAdded = 0;
}

template<class genType>
void TArray<genType>::set( long idx, genType item )
{
	if( idx < 1 ) {
		return;
	}
	if ( idx - 1 > LastAdded ) {
		return;
	}
	Array[ idx - 1 ] = item;
}

template<class genType>
void TArray<genType>::add( genType item )
{
  if ( LastAdded >= ArrSize ) {
		ArrSize += ArrDefaultSize; // add default size ( =first time double the size )
		genType *temp = new genType[ArrSize]; // create new bigger array.
		for ( long i = 0; i < LastAdded ; i++ ) {
			temp[i] = Array[i]; // copy values to new array.
		}
		delete [] Array; // free old array memory.
		Array = temp; // now a points to new array.
  }
	Array[LastAdded++] = item;
}

template<class genType>
long TArray<genType>::getSize()
{
	return LastAdded;
}

template<class genType>
genType TArray<genType>::getNthElement( long elementToFind )
{ // elementToFind = 1 -based index
	if( elementToFind < 1 ) {
		return NULL;
	}
	if( elementToFind > getSize() ) {
		return NULL;
	}
	return Array[elementToFind - 1];
}


template<class genType>
long TArray<genType>::binarySearch( genType whatToFind ) // returns equal or previous smaller
{
	/*
	Puolitus- eli bin‰‰rihaussa tutkittava alue (alussa koko taulukko) 
	jaetaan kahtia ja katsotaan kummassa puoliskossa haettava avain on. 
	Hakua jatketaan n‰in valitussa puoliskossa rekursiivisesti kunnes 
	j‰ljell‰ on haettu alkio tai ei mit‰‰n.
	Puolitushaun tehokkuus on O(logN). 
	*/
  int low = 0;
  //int high = this.getSize() - 1; //xcode 4.2 fix, remove this
  int high = getSize() - 1;
  int mid;

  while( low <= high )
  {
      mid = (low + high) / 2; // Integer division result is rounded
															// down towards nearest integer
      if( Array[mid] < whatToFind ) 
          low = mid + 1;
      else if( Array[mid] > whatToFind ) 
          high = mid - 1;
      else
          return mid;
  }
	
  return mid; // return -1;     // Not found
}

#endif


