#include "XML_Document.h"


//----------------------<Builds a tree for a given filename>---------------------------------------
Node * XML_Document::Load(string filename, bool isFile)
{
	try
	{
		Toker toker(filename.c_str(), isFile);
		toker.setMode(Toker::xml);
		XML_Parts parts(&toker);
		Document = new Node("Document", " ");
		ScopeStack.push(Document);
		// parts.verbose();                 // uncomment to show token details
		while (parts.get())
		{
			XML_Document::CreateNode(ScopeStack.top(), parts);
		}
	}

	catch (exception ex)
	{
		cout << "\n  " << ex.what() << "\n\n";
		exit(1);
	}

	return Document;
}

Node * XML_Document::ParseString(string filename)
{
	try
	{
		Toker toker(filename.c_str(), false);
		toker.setMode(Toker::xml);
		XML_Parts parts(&toker);
		Document = new Node("Document", " ");
		ScopeStack.push(Document);
		// parts.verbose();                 // uncomment to show token details
		while (parts.get())
		{
			XML_Document::CreateNode(ScopeStack.top(), parts);
		}
	}

	catch (exception ex)
	{
		cout << "\n  " << ex.what() << "\n\n";
		exit(1);
	}

	return Document;
}

//----<This function is used to FORMAT comments and banners so as to be processed by web browsers>----------

string XML_Document::ShowComment(XML_Parts &parts)
{
	string result;
	for (int i = 0; i<parts.length() - 1; i++)
	{
		if (parts[i] == "<")
			result = result + parts[i] + parts[i + 1];
		else if (parts[i] == "!" || parts[i] == "?" || parts[i] == "--")
			result += parts[i + 1];
		else
			result = result + " " + parts[i + 1];
	}
	return result;
}

//-----------------------------<Recursive function, create nodes using XML_Parts>--------------------

void XML_Document::CreateNode(Node * pParent, XML_Parts parts)
{
	try
	{
		if (parts[0] == "<")
		{
			int i = 1;
			if (parts[i] == "!")
			{
				Node * CommentNode = new Node("XmlComment", XML_Document::ShowComment(parts));
				pParent->AddChild(CommentNode);
			}
			else if (parts[i] == "?")
			{
				Node * PreProcessingInstruction = new Node("PreProcessingInstruction", XML_Document::ShowComment(parts));
				pParent->AddChild(PreProcessingInstruction);
			}
			else if (parts[i] == "/")
				ScopeStack.pop();
			else
			{
				Node * Element = new Node;
				Element->setNodetype("Element");
				Element->setNodeName(parts[i]);
				if (parts[parts.length() - 2] != "/")
					ScopeStack.push(Element);
				i++;
				//if(parts[i]!=">")
				while (i<parts.length() && parts[i] != ">")
				{
					Element->AddAttributes(parts[i], parts[i + 2]);
					i += 3;
					if (i >= parts.length() || parts[i] == ">" || parts[i] == "/")
						break;
				}
				pParent->AddChild(Element);
			}
		}
		else
		{
			Node * textNode = new Node("TextNode", parts.show());
			pParent->AddChild(textNode);
		}
	}
	catch (exception e)
	{
		cout << e.what() << endl;
		exit(1);
	}
}

