/*
WARNING: This header should never be directly included. Include XML.h instead.

Author:		Chris Kaynor (chris@kaynor.net)
Edited By:		

Description:		Provides element information from an XML file.
			
Usage:		Access the attributes found by the getAttributes()
			function or the getFirstAttribute() function.
			Access the child elements with the getChildren()
			function or the getFirstChild() function.
			The contents of the element (including child elements)
			can be accessed by the valBuff c-style string, or
			the value stream.
			
Requirements:	string as defined in the standard template library.
			strstream as defined in the standard template library.
			XMLDocument as defined in kLibrary's XML section.
			Element as defined in kLibrary's XML section.
			Attribute as defined in kLibrary's XML section.
			Typedefs as defined in kLibrary's XML section (XML.h)
			
Last Edited:	June 24th, 2008
*/
/*
Copyright 2008 Chris Kaynor

This file is part of kLibrary.

kLibrary is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or(at your option) any later version.

kLibrary is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License.
*/

#ifndef KLIBRARY_XML_ELEMENT_H
#define KLIBRARY_XML_ELEMENT_H

#include "XML.h"
#include "attribute.h"

namespace kLibrary
{
	namespace XML
	{
		class Element
		{
		public:
			/*
			Handle creation and copying of elements.
			*/
			Element(void);
			Element& operator=(const Element& other);
			Element(const Element& other);
			
			/*
			Handle clean-up of data.
			*/
			~Element(void);
			
			/*
			Retrieve the tree of children.
			These three functions are the same as the get*Element?*()
			functions of the XMLDocument class, and should be used to
			traverse the tree.
			GetFirstChild() and getEndChild() can be combined to iterator
			though the entire array (though not recursively) with the simple
			loop:

			const elementIterator end = getEndChild();
			for (elementIterator cur = getFirstChild(); cur != end; cur++)
			{
				...
			}
			*/
			const elements& getChildren(void) const;
			const elementIterator getFirstChild(void) const;
			const elementIterator getEndChild(void) const;

			/*
			Finds the first occurrence of the element with the name elementName.
			Does not search recursively...the element must be contained directly
			within this element.
			*/
			const elementIterator findFirstChildElement(const std::string& elementName) const;

			/*
			Finds the next child element with the same element name as the
			specified element.
			Combined with findFirstChildElement, this can be used to create a
			loop though all elements with the specified name, as follows:

			const elementIterator end = getEndChild();
			for (elementIterator cur = findFirstChildElement("MyElement"); cur != end; findNextChildElement(cur))
			{
				...
			}

			Note that the return value is the same as the input. The value passed into
			current WILL change when this funtion is called.
			*/
			elementIterator& findNextChildElement(elementIterator& current) const;

			/*
			Returns true if the element name specified exists within this element.
			Does not search recursively. If an iterator is specified, the search
			begins there and true is only returned if the element is found later
			in the tree.
			*/
			const bool elementExists(const std::string& elementName) const;
			const bool elementExists(const std::string& elementName, const elementIterator& begin) const;
			
			/*
			Retrieve the list of attributes.
			Usage is the same as the get*Child*() functions, however the data
			type is different.
			*/
			const attributes& getAttributes(void) const;
			const attributeIterator getFirstAttribute(void) const;
			const attributeIterator getEndAttribute(void) const;

			/*
			Retrieves the iterator to the attribute with the specified name.
			In well-formed XML, this will be the only instance.
			*/
			const attributeIterator findAttribute(const std::string& attributeName) const;
			
			/*
			Retrieve the element's value in various ways.
			*/
			operator std::string(void) const;
			operator float(void) const;
			operator int(void) const;

			/*
			The name of the element. For the "<?xml...?>" element, this
			is "?xml".
			*/
			std::string element;
			
			/*
			The list of attributes. This the the same as the return of
			getAttributes() function.
			
			Changing this value has no effect on the input XML.
			*/
			attributes attributes;
			
			/*
			The list of child elements. This the the same as the return of
			getChildren() function.
			
			Changing this value has no effect on the input XML.
			*/
			elements children;
			
			/*
			The value stream. This will contain the XML of any child
			elements.
			*/
			std::strstream* value;
			
			/*
			The value as a c-style string. This will contain the XML of any child
			elements.
			*/
			char* valBuff;
			
			/*
			The length of the value buffer, including the null character.
			*/
			size_t buffLength;
		};
	}
}

#endif //KLIBRARY_XML_ELEMENT_H