/*TITLE vector definition */

/****keyword-flag*** "%v %f %n" */
/* "9 6-May-98,10:32:34 VECTOR.H" */

#include "common.h"

#if VDEBUG
#define vectorassert(p) ((p) ? (void)0 : (void) QFAssertFail( \
  "Assertion failed: %s, file %s, line %d\n", \
   #p, __FILE__, __LINE__ ) )
#else
#define vectorassert(p)
#endif

template <class T> class AccessVector;

template <class T>
class SVector
{
protected:
	T *m_Data;
	ArrayIndex m_Count;
public:
	SVector();
	SVector(ArrayIndex p_Count);
	SVector(ArrayIndex p_Count, T *p_Data);
	SVector(char *p_Data);
	SVector(const SVector& p_Vector);
	SVector(AccessVector<T>& p_AccessVector);
operator const char *() const {return (char *)m_Data;};
int operator==(char *p_Data);
int	operator==(const SVector& p_Vector);
void *GetDataAddress(){return (void *)m_Data;}
SVector& operator =( const SVector& p_Vector);
T& operator[](ArrayIndex p_ArrayIndex)
{
vectorassert (this && (p_ArrayIndex < m_Count));
return m_Data[p_ArrayIndex];
}
T& operator[](int p_ArrayIndex)
{
return operator[]((ArrayIndex)p_ArrayIndex);
}
ArrayIndex GetSize() {return m_Count;}
void SetSize(ArrayIndex p_NewCount);
void InsertBefore(ArrayIndex p_ArrayIndex);
void InsertAfter(ArrayIndex p_ArrayIndex);
void Delete(ArrayIndex p_ArrayIndex);
     ~SVector() {delete [] m_Data;}
};

template <class T>
SVector<T>::SVector()
{
	m_Data = new T[0];
	m_Count = 0;
}

template <class T>
SVector<T>::SVector(ArrayIndex p_Count)
{
	m_Data = new T[p_Count];
	m_Count = p_Count;
}

template <class T>
SVector<T>::SVector(ArrayIndex p_Count, T *p_Data)
{
	m_Data = new T[p_Count];
	m_Count = p_Count;
	for (ArrayIndex i = 0; i < m_Count; i ++)
		m_Data[i] = p_Data[i];
}

template <class T>
SVector<T>::SVector(char *p_Data)
{
	m_Count = strlen(p_Data);
	m_Data = new T[m_Count];
	memcpy((void *)m_Data,p_Data,m_Count);
}

template <class T>
SVector<T>::SVector(const SVector<T>& p_Vector)
{
	if (this == &p_Vector)
		return;

	m_Count = p_Vector.m_Count;
	m_Data = new T[m_Count];
	for (ArrayIndex i = 0; i < m_Count; i ++)
		m_Data[i] = p_Vector.m_Data[i];
}


template <class T>
SVector<T>::SVector(AccessVector<T>& p_AccessVector)
{
	m_Count = p_AccessVector.GetSize();
	m_Data = new T[m_Count];
	for (ArrayIndex i = 0; i < m_Count; i ++)
		m_Data[i] = p_AccessVector[i];
}


template <class T>
SVector<T>& SVector<T>::operator=(const SVector<T>& p_Vector)
{
	if (this == &p_Vector)
		return *this;

	delete [] m_Data;
	m_Count = p_Vector.m_Count;
	m_Data = new T[m_Count];
	for (ArrayIndex i = 0; i < m_Count; i ++)
		m_Data[i] = p_Vector.m_Data[i];
	return *this;
}


template <class T>
int SVector<T>::operator==(const SVector<T>& p_Vector)
{
	if (this == &p_Vector)
		return 1;
	if (m_Count != p_Vector.m_Count)
		return 0;
	if (m_Count == 0)
		return 1;
	if (memcmp(m_Data,p_Vector.m_Data,m_Count*sizeof(T)) == 0)
		return 1;
	return 0;
}


template <class T>
int SVector<T>::operator==(char *p_Data)
{
	int CompareLength = strlen(p_Data);

	if (CompareLength != m_Count)
		return 0;

	if (memcmp((void *)m_Data,(void *)p_Data, strlen(p_Data)) == 0)
		return 1;

	return 0;
}


template <class T>
void SVector<T>::SetSize(ArrayIndex p_NewCount)
{
	T *TempPtr;
	ArrayIndex i;
	ArrayIndex Smaller;

	Smaller = min(p_NewCount, m_Count);

	TempPtr = new T[p_NewCount];
	for (i = 0; i < Smaller; i ++)
		TempPtr[i] = m_Data[i];
		
	delete [] m_Data;
	m_Count = p_NewCount;
	m_Data = TempPtr;
}


template <class T>
class AccessVector
{
protected:
	T *m_Data;
	ArrayIndex m_Count;
public:
	AccessVector();
	AccessVector(ArrayIndex p_Count, T *p_Data);
	AccessVector(char *p_Data);
void *GetDataAddress(){return (void *)m_Data;}
int	operator==(const AccessVector& p_AccessVector);
T& operator[](ArrayIndex p_ArrayIndex)
{
vectorassert (p_ArrayIndex < m_Count);
return m_Data[p_ArrayIndex];
}
ArrayIndex GetSize() {return m_Count;}
};

template <class T>
AccessVector<T>::AccessVector()
{
	m_Data = 0;
	m_Count = 0;
}

template <class T>
AccessVector<T>::AccessVector(ArrayIndex p_Count, T *p_Data)
{
	m_Data = p_Data;
	m_Count = p_Count;
}

template <class T>
AccessVector<T>::AccessVector(char *p_Data)
{
	m_Data = (T *)p_Data;
	m_Count = strlen(p_Data);
}

template <class T>
int AccessVector<T>::operator==(const AccessVector<T>& p_AccessVector)
{
	if (this == &p_AccessVector)
		return 1;
	if (m_Count != p_AccessVector.m_Count)
		return 0;
	if (memcmp(m_Data,p_AccessVector.m_Data,m_Count*sizeof(T)) == 0)
		return 1;
	return 0;
}


class VectorCharRep;

// obsolete nomenclature for template specialization
// class SVector<char>

template<> class SVector<char>
{
friend ostream& operator<<(ostream& os, const SVector<char>& Str);
friend istream& operator>>(istream& os, SVector<char>& Str);
protected:
	VectorCharRep *m_Rep;
public:
	SVector<char>();
	SVector<char>(ArrayIndex p_Count);
	SVector<char>(ArrayIndex p_Count, char *p_Data);
	SVector<char>(char *p_Data);
	SVector<char>(const SVector<char>& p_Vector);
operator const char *() const;
int operator==(char *p_Data);
int	operator==(const SVector<char>& p_Vector);
int operator!=(char *p_Data);
int	operator!=(const SVector<char>& p_Vector);
void *GetDataAddress();
SVector<char>& operator =( const SVector<char>& p_Vector);
SVector<char>operator +(const SVector<char>& p_Vector);
char& operator[](ArrayIndex p_ArrayIndex);
ArrayIndex GetSize();
void	SetSize(ArrayIndex p_NewCount);
~SVector();
SVector<char> Mid(ArrayIndex p_Start, ArrayIndex p_Length);
int Instr(char* p_Search, ArrayIndex p_Start = 0);
};

class VectorCharRep
{
friend SVector<char>;
protected:
	char *m_Data;
	ArrayIndex m_Count;
	int m_RefCount;
};


typedef SVector<char> String;

template <class T>
void SVector<T>::InsertBefore(ArrayIndex p_ArrayIndex)
{
	ArrayIndex i;
	ArrayIndex OldSize = GetSize();
	ArrayIndex NewSize = OldSize + 1;
	T* TempPtr = new T[NewSize];

	for (i = 0; i < p_ArrayIndex; i ++)
		TempPtr[i] = m_Data[i];

	for (i = p_ArrayIndex + 1; i < NewSize; i ++)
		TempPtr[i] = m_Data[i-1];

	delete [] m_Data;
	m_Data = TempPtr;
	m_Count = NewSize;
}

template <class T>
void SVector<T>::InsertAfter(ArrayIndex p_ArrayIndex)
{
	ArrayIndex i;
	ArrayIndex OldSize = GetSize();
	ArrayIndex NewSize = OldSize + 1;
	T* TempPtr = new T[NewSize];

	for (i = 0; i <= p_ArrayIndex; i ++)
		TempPtr[i] = m_Data[i];

	for (i = p_ArrayIndex + 2; i < NewSize; i ++)
		TempPtr[i] = m_Data[i-1];

	delete [] m_Data;
	m_Data = TempPtr;
	m_Count = NewSize;
}

template <class T>
void SVector<T>::Delete(ArrayIndex p_ArrayIndex)
{
	ArrayIndex i;
	ArrayIndex OldSize = GetSize();
	ArrayIndex NewSize = OldSize - 1;

	for (i = p_ArrayIndex; i < OldSize-1; i ++)
		m_Data[i] = m_Data[i+1];

	SetSize(NewSize);
}


