#include "element.h"

namespace kLibrary
{
	namespace XML
	{
		Element::Element(void)
		{
			//Initialize the value buffer values to a null string.
			buffLength = 1;
			valBuff = new char[1];
			valBuff[0] = '\0';
			value = new std::strstream(valBuff, std::streamsize(buffLength));
		}

		Element& Element::operator=(const Element& other)
		{
			//Delete our existing buffer, if any
			if (valBuff != 0)
				delete [] valBuff;
			if (value != 0)
				delete value;
		
			//Check to make sure the other has a value buffer
			if (other.valBuff != 0)
			{
				//If so, copy it into our own memory
				buffLength = other.buffLength;
				valBuff = new char[buffLength + 1];
				strcpy_s(valBuff, buffLength, other.valBuff);
				value = new std::strstream(valBuff, std::streamsize(buffLength));
			}
			else
			{
				//Otherwise, initialize the value buffer values to a null string.
				buffLength = 1;
				valBuff = new char[1];
				valBuff[0] = '\0';
				value = new std::strstream(valBuff, std::streamsize(buffLength));
			}
			
			//Copy the other items over
			element = other.element;
			attributes = other.attributes;
			children = other.children;

			return *this;
		}

		Element::Element(const Element& other)
		{
			//Check to make sure the other has a value buffer
			if (other.valBuff != 0)
			{
				//If so, copy it into our own memory
				buffLength = other.buffLength;
				valBuff = new char[buffLength + 1];
				strcpy_s(valBuff, buffLength, other.valBuff);
				value = new std::strstream(valBuff, std::streamsize(buffLength));
			}
			else
			{
				//Otherwise, initialize the value buffer values to a null string.
				buffLength = 1;
				valBuff = new char[1];
				valBuff[0] = '\0';
				value = new std::strstream(valBuff, std::streamsize(buffLength));
			}
			
			//Copy the other items over
			element = other.element;
			attributes = other.attributes;
			children = other.children;
		}

		Element::~Element(void)
		{
			//Delete our buffer, if any
			if (valBuff != 0)
				delete [] valBuff;
			if (value != 0)
				delete value;
		}

		const elements& Element::getChildren(void) const
		{
			return children;
		}

		const elementIterator Element::getFirstChild(void) const
		{
			return children.begin();
		}

		const elementIterator Element::getEndChild(void) const
		{
			return children.end();
		}
		
		const elementIterator Element::findFirstChildElement(const std::string& elementName) const
		{
			elementIterator cur = children.begin();
			const elementIterator& end = children.end();

			for(; cur != end; cur++)
				if (strcmp(cur->element.c_str(), elementName.c_str()) == 0)
					return cur;

			return cur;
		}

		elementIterator& Element::findNextChildElement(elementIterator& current) const
		{
			const std::string& elementName = current->element;
			const elementIterator& end = children.end();

			for(; current != end; current++)
				if (strcmp(current->element.c_str(), elementName.c_str()) == 0)
					return current;

			return current;
		}

		const bool Element::elementExists(const std::string& elementName) const
		{
			elementIterator cur = children.begin();
			const elementIterator& end = children.end();

			for(; cur != end; cur++)
				if (strcmp(cur->element.c_str(), elementName.c_str()) == 0)
					return true;

			return false;
		}

		const bool Element::elementExists(const std::string& elementName, const elementIterator& begin) const
		{
			elementIterator cur = begin;
			const elementIterator& end = children.end();

			for(; cur != end; cur++)
				if (strcmp(cur->element.c_str(), elementName.c_str()) == 0)
					return true;

			return false;
		}

		const attributes& Element::getAttributes(void) const
		{
			return attributes;
		}
		
		const attributeIterator Element::getFirstAttribute(void) const
		{
			return attributes.begin();
		}
		
		const attributeIterator Element::getEndAttribute(void) const
		{
			return attributes.end();
		}

		const attributeIterator Element::findAttribute(const std::string& attributeName) const
		{
			attributeIterator cur = attributes.begin();
			const attributeIterator& end = attributes.end();

			for(; cur != end; cur++)
				if (strcmp(cur->name.c_str(), attributeName.c_str()) == 0)
					return cur;

			return cur;
		}

		Element::operator std::string(void) const
		{
			if (valBuff == 0) return "";

			return std::string(valBuff);
		}

		Element::operator float(void) const
		{
			if (value == 0) return 0.0f;

			value->seekg(0);
			float out;
			*value >> out;
			return out;
		}

		Element::operator int(void) const
		{
			if (value == 0) return 0;

			value->seekg(0);
			int out;
			*value >> out;
			return out;
		}
	}
}