#include "String.h"

#include <string.h>

String::String()
{
	this->data = new char[1];
	this->data[0] = '\0';
	this->length = 0;
}

String::String(const char *text)
{
	this->length = strlen(text);
	this->data = new char[this->length + 1];
	strncpy(this->data, text, this->length + 1);
}

String::String(const String &string)
{
	this->length = string.length;
	this->data = new char[this->length + 1];
	strncpy(this->data, string.data, this->length + 1);
}

String::String(const char c)
{

	this->data = new char[2];
	this->data[0] = c;
	this->data[1] = '\0';
	this->length = 1;
}

String::String(const SizeType length)
{
	this->length = length;
	this->data = new char[length + 1];
	this->data[length] = '\0';
}

bool String::operator == (const String string) const
{
	return !strcmp(data, string.data);
}

bool String::operator != (const String string) const
{
	return !(*this == string);
}

bool String::operator > (const String string) const
{
	return strcmp(data, string.data) > 0;
}

bool String::operator < (const String string) const
{
	return strcmp(data, string.data) < 0;
}

bool String::operator >= (const String string) const
{
	return *this > string || *this == string;
}

bool String::operator <= (const String string) const
{
	return *this < string || *this == string;
}

String& String::operator = (const String string)
{
	delete [] this->data;
	length = string.GetLength();
	data = new char[length + 1];
	strncpy(data, string.data, length + 1);

	return *this;
}

String& String::operator += (const String string)
{
	*this = *this + string;
	return *this;
}

char& String::operator [] (const SizeType index)
{
	if (index >= GetLength()) throw OutOfRange();
	return data[index];
}

const char& String::operator [] (const SizeType index) const
{
	if (index >= GetLength()) throw OutOfRange();
	return data[index];
}

String::~ String()
{
	delete [] this->data;
}

String String::SubString(const SizeType from, const SizeType to) const
{
	if (from > to) return "";

	String tmp(to - from + 1);
	for (SizeType i = from; i <= to; i++)
		tmp[i - from] = data[i];

	return tmp;
}

String::SizeType String::Find(const char c, const SizeType from) const
{
	for (SizeType i = from; i < GetLength(); i++)
		if ((*this)[i] == c) return i;

	return GetLength();
}

void String::Cut(const SizeType from, const SizeType to)
{
	if (from == 0)
		*this = SubString(to + 1, GetLength() - 1);
	else
		*this = SubString(0, from - 1) + SubString(to + 1, GetLength() - 1);
}

String operator + (const String s1, const String s2)
{
	String result(s1.GetLength() + s2.GetLength());
	strncpy(result.data, s1.data, s1.GetLength());
	strncpy(result.data + s1.GetLength(), s2.data, s2.GetLength());
	return result;
}
