#include "c4d_string.h"
#include "c4d_memory.h"

void* String::operator new(size_t,int line,const CHAR *file)
{
	return C4DOS.St->Alloc();
}

void String::operator delete(void* del)
{
	C4DOS.St->Free((String*)del);
}

String::String(void)
{
	C4DOS.St->Init(this);
}

String::String(const String &cs)
{
	C4DOS.St->Init(this);
	C4DOS.St->CopyTo(&cs,this);
}

String::String(const CHAR *cstr)
{
	C4DOS.St->Init(this);
	C4DOS.St->InitCString(this,cstr,-1,StXbit);
}

String::String(LONG count,UWORD fillch)
{
	C4DOS.St->Init(this);
	C4DOS.St->InitArray(this,count,fillch);
}

String::~String(void)
{
	C4DOS.St->Flush(this);
}

void String::CopyTo(String *str) const
{
	C4DOS.St->CopyTo(this,str);
}

String *String::GetClone(void) const
{
 	return C4DOS.St->GetClone(this);
}

const String& String::operator = (const String &cs)
{
	C4DOS.St->CopyTo(&cs,this);
	return *this;
}

void FreeString(String *&str)
{
	if (str) C4DOS.St->Free(str);
	str=NULL;
}

LONG String::GetLength(void) const
{
	return C4DOS.St->GetLength(this);
}

const String operator + (const String &Str1,const String &Str2)
{
	return String(Str1)+=Str2;
}

const String& String::operator += (const String &Str)
{
	Insert(GetLength(),Str);
	return *this;
}

Bool String::operator < (const String &Str) const
{
	return (Compare(Str) < 0);
}

Bool String::operator > (const String &Str) const
{
	return (Compare(Str) > 0);
}

Bool String::operator <= (const String &Str) const
{
	return (Compare(Str) <= 0);
}

Bool String::operator >= (const String &Str) const
{
	return (Compare(Str) >= 0);
}

Bool String::operator == (const String &Str) const
{
	return (Compare(Str) == 0);
}

Bool String::operator != (const String &Str) const
{
	return (Compare(Str) != 0);
}

LONG String::Compare(const String &cs) const
{
	return C4DOS.St->Compare(this,&cs,0);
}

LONG String::LexCompare(const String &cs) const
{
	return C4DOS.St->Compare(this,&cs,1);
}

LONG String::RelCompare(const String &cs) const
{
	return C4DOS.St->Compare(this,&cs,2);
}

Bool String::FindFirst(const String &cs,LONG *pos,LONG start) const
{
	return C4DOS.St->FindFirst(this,&cs,pos,start);
}

Bool String::FindLast(const String &cs,LONG *pos,LONG start) const
{
	return C4DOS.St->FindLast(this,&cs,pos,start);
}

Bool String::FindFirst(UWORD ch,LONG *pos,LONG start) const
{
	String tmp = String(1,ch);
	return C4DOS.St->FindFirst(this,&tmp,pos,start);
}

Bool String::FindLast(UWORD ch,LONG *pos,LONG start) const
{
	String tmp = String(1,ch);
	return C4DOS.St->FindLast(this,&tmp,pos,start);
}

void String::Delete(LONG pos,LONG count)
{
	C4DOS.St->Delete(this,pos,count);
}

void String::Insert(LONG pos,UWORD ch)
{
	String tmp = String(1,ch);
	C4DOS.St->Insert(this,pos,&tmp);
}

void String::Insert(LONG pos,const String &cs)
{
	C4DOS.St->Insert(this,pos,&cs);
}

const String String::SubStr(LONG start,LONG count) const
{
	String str,*s=C4DOS.St->SubStr(this,start,count);
	if (s) str=*s;
	FreeString(s);
	return str;
}

Real String::StringToReal(LONG *error, LONG unit, LONG angletype, LONG base) const
{
	return C4DOS.St->ToReal(this,error,unit,angletype,base);
}

LONG String::StringToLong(LONG *error) const
{
	return C4DOS.St->ToLong(this,error);
}

const String String::ToUpper() const
{
	String str,*s=C4DOS.St->ToUpper(this);
	if (s) str=*s;
	FreeString(s);
	return str;
}

const String String::ToLower() const
{
	String str,*s=C4DOS.St->ToLower(this);
	if (s) str=*s;
	FreeString(s);
	return str;
}

LONG String::GetCStringLen(StringEncoding type) const
{
	return C4DOS.St->GetCStringLen(this,type);
}

LONG String::GetCString(CHAR *scstr, LONG max, StringEncoding type) const
{
	return C4DOS.St->GetCString(this,scstr,max,type);
}

LONG String::SetCString(const CHAR *cstr, LONG count, StringEncoding type)
{
	String *s=C4DOS.St->AllocCString((CHAR*)cstr,count,type);
	if (s) *this=*s;
	FreeString(s);
	return GetLength();
}

const String LongToString(LONG l)
{
	String str,*s=C4DOS.St->LongToString(l);
	if (s) str=*s;
	FreeString(s);
	return str;
}

const String RealToString(Real v, LONG vvk, LONG nnk, Bool e, UWORD xchar)
{
	String str,*s=C4DOS.St->RealToString(v,vvk,nnk,e,xchar);
	if (s) str=*s;
	FreeString(s);
	return str;
}

const String::PChar String::operator[] (LONG Pos) const
{
	if (Pos >= GetLength() || Pos < 0) Pos = -1;
	return PChar((String *)(this),Pos);
}

String::PChar String::operator[] (LONG Pos)
{
	if (Pos >= GetLength() || Pos < 0) Pos = -1;
	return PChar(this,Pos);
}

String::PChar::PChar(String *str,LONG pos)
{
	Str = str;
	Pos = pos;
}

String::PChar& String::PChar::operator = (const PChar& rhs)
{
	if (!Str) return *this;
	if (Pos < 0 || Pos >= Str->GetLength()) return *this;
	
	C4DOS.St->SetChr(Str,Pos,C4DOS.St->GetChr(rhs.Str,rhs.Pos));
	return *this;
}

String::PChar& String::PChar::operator = (UWORD c)
{
	if (!Str) return *this;
	if (Pos < 0 || Pos >= Str->GetLength()) return *this;
	C4DOS.St->SetChr(Str,Pos,c);
	return *this;
}

String::PChar::operator UWORD(void) const
{
	if (!Str) return 0;
	if (Pos < 0 || Pos >= Str->GetLength()) return 0;
	else return C4DOS.St->GetChr(Str,Pos);
}

#if (defined _DEBUG) && (defined WIN32)
static CHAR array[1000];

CHAR *cstr(String &str)
{
	str.GetCString(array,1000);
	return array;
}

#include "c4d_file.h"
CHAR *cstr(Filename &fn)
{
	fn.GetString().GetCString(array,1000);
	return array;
}
#endif
