#include "ofXML.h"


ofXML::ofXML(){

	mainTagSet = false;

}

//---------------------------------------------------------

void ofXML::init(char * mainTag){

	xMainNode=XMLNode::createXMLTopNode(_T(mainTag));
	mainTagSet = true;
}

//---------------------------------------------------------

void ofXML::initFromFile(char * xmlFile, char * mainTag){

	printf("ofXML:  opening file %s \n", xmlFile);

    // this open and parse the XML file:
	xMainNode=XMLNode::openFileHelper(_T(xmlFile),_T(mainTag));
	mainTagSet = true;
}

//---------------------------------------------------------

void ofXML::saveFile(char * xmlFile)
{
	if(!mainTagSet){
		printf("ofXML:  mainTag not set, please set with init() or initFromFile()\n");
		return;
	}
	printf("ofXML:  saving file %s \n", xmlFile);
	xMainNode.writeToFile(xmlFile);
}

//---------------------------------------------------------
void ofXML::getValue(char * tag, int * valueAsInt)
{
	if(!mainTagSet){
		printf("ofXML:  mainTag not set, please set with init() or initFromFile()\n");
		return;
	}
	
	XMLNode myNode = this->parseTag(tag); 

	//Added this to the XML Parser class
	//Returns true if the tag contains any text
	if( myNode.isText() )
	{
		//This only modifies the int if there is a value
		//So you can pass in a default value and it will
		//be not affected if no value can be found.
		*valueAsInt = atoi( myNode.getText() );
	}
	else{
		//printf("ofXML:  tag %s not found value set to %i\n", tag, *valueAsInt);
	}
}

//---------------------------------------------------------

void ofXML::getValue(char * tag, float * valueAsFloat)
{
	if(!mainTagSet){
		printf("ofXML:  mainTag not set, please set with init() or initFromFile()\n");
		return;
	}

	XMLNode myNode = this->parseTag(tag); 
	
	//Added this to the XML Parser class
	//Returns true if the tag contains any text
	if( myNode.isText() )
	{
		//This only modifies the float if there is a value
		//So you can pass in a default value and it will
		//be not affected if no value can be found.
		*valueAsFloat = atof( myNode.getText() );
	}else{
		//printf("ofXML:  tag %s not found value set to %f\n", tag,  *valueAsFloat);
	}
}

//---------------------------------------------------------

void ofXML::getValue(char * tag, char * valueAsString)
{
	if(!mainTagSet){
		printf("ofXML:  mainTag not set, please set with init() or initFromFile()\n");
		return;
	}

	XMLNode myNode = this->parseTag(tag); 
	
	//Added this to the XML Parser class
	//Returns true if the tag contains any text
	if( myNode.isText() )
	{
		//Warning you better pass in buffer large enough!!!
		//You need size of string you are getting +1
		//otherwise boom explosion!
		int sizeOfString = strlen(myNode.getText());
		
		memset(valueAsString, 0, sizeOfString+1); //So the string is terminated
		memcpy(valueAsString, myNode.getText(), sizeOfString);
		
	}else{
		//printf("ofXML:  tag %s not found value set to %f\n", tag,  *valueAsString);
	}
}



//---------------------------------------------------------

void ofXML::setValue(char * tag, int value)
{
	char tmpStr[512];
	memset(tmpStr, 0, 512);
	
	sprintf(tmpStr,"%i",value); 
	setValue(tag, tmpStr);
}

//---------------------------------------------------------

void ofXML::setValue(char * tag, float value)
{
	char tmpStr[512];
	memset(tmpStr, 0, 512);
	
	sprintf(tmpStr,"%f",value); 
	setValue(tag, tmpStr);
}


//---------------------------------------------------------

void ofXML::setValue(char * tag, char * value)
{

	if(!mainTagSet){
		printf("ofXML:  mainTag not set, please set with init() or initFromFile()\n");
		return;
	}

	XMLNode xNode;
	
	int pos		= 0;
	int index	= 0;
	bool first	= true;
	char * ptr  = tag;

	//Parse through the text one
	//char at a time
	while(tag[index] != 0){
		
		//look for the seperator
		if(tag[index] == ':'){
			//create a tmp string to store the tag name
			char * str = new char[pos+1];
			memset(str, 0, pos+1); //This is to make sure the str is terminated
			memcpy(str, ptr, pos);
			//printf("tag is %s ptr is %s pos is  %i\n", str, ptr, pos);
			
			//If this is the first tag
			//we need to reference the 
			//main node 
			if(first){
				xNode = xMainNode.getChildNode(str);	
				first = false;
				
				//If we are empty and have no text
				//then we don't exist.
				//if( xNode.isEmpty() && !xNode.isText() )	
				
				if( xNode.getName() == NULL )
				{
					xMainNode.addChild(str);
				}
				
				xNode = xMainNode.getChildNode(str);	
			}
			else{
				
				//If we are empty and have no text
				//then we don't exist.
				//So let us create a new node
				//Might have to check for nodes with
				//no text.
				
				if( xNode.getChildNode(str).getName() == NULL )	
				{
					xNode.addChild(str);
				}
		
				xNode = xNode.getChildNode(str);
			}
			//destroy the tmp string
			delete str;	
						
			//Make sure our tag ptr is now pointing
			//at the begining of the next tag
			ptr+=pos+1;
			pos = 0;	
		}
		else pos++;
		index++;
	}
	
	//Finally grab the last tag in the structure
	//which is the one we actually want to write
	//to
			
	//it could be the first tag ie "Red"
	//or it could be a child tag ie "Color:Red"
	//so we check
	if(first)
	{
		xNode = xMainNode.getChildNode(ptr);
		if( xNode.getName() == NULL )
		{
			xMainNode.addChild(ptr);
		}
				
		xNode = xMainNode.getChildNode(ptr);
	}
	else
	{
		if( xNode.getChildNode(ptr).getName() == NULL )	
		{
			xNode.addChild(ptr);
		}
		xNode = xNode.getChildNode(ptr);
	}
	
    xNode.updateText(value);  
	  
}

//---------------------------------------------------------

XMLNode ofXML::parseTag(char * tag)
{
	
	//This is where we parse the tag.
	//We make sure that non-
	//existant tags don't crash the 
	//system. 
	
	//Tags can be in the format TAG
	//Representing <TAG>some text</TAG>
	
	//Or they can be in the format 
	//MainTag:InnerTag:Color:RED
	//Representing 
	/*
		<MainTag>
				<InnerTag>
					<Color>
						<RED>
							Some Value here
						</RED>
					</Color>
				</InnerTag>
		</MainTag>
	*/			
						
	XMLNode xNode;
	
	int pos		= 0;
	int index	= 0;
	bool first	= true;
	char * ptr  = tag;

	//Parse through the text one
	//char at a time
	while(tag[index] != 0){
		
		//look for the seperator
		if(tag[index] == ':')
		{
			//create a tmp string to store the tag name
			char * str = new char[pos+1];
			memset(str, 0, pos+1); //This is to make sure the str is terminated
			memcpy(str, ptr, pos);
			//printf("tag is %s ptr is %s pos is  %i\n", str, ptr, pos);
			
			//If this is the first tag
			//we need to reference the 
			//main node 
			if(first){
				xNode = xMainNode.getChildNode(str);
				first = false;
			}
			else{
				//Otherwise we get the child node
				xNode = xNode.getChildNode(str);
			}
			//destroy the tmp string
			delete str;				
			
			//Make sure our tag ptr is now pointing
			//at the begining of the next tag
			ptr+=pos+1;
			pos = 0;	
			
			//If the tag is empty then 
			//we should stop
			if( xNode.isEmpty() ) break;
		}
		else pos++;
		index++;
	}
	
	//Finally grab the last tag in the structure
	//which is the one we actually want to get the
	//contents of.
	
	//it could be the first tag ie "Red"
	//or it could be a child tag ie "Color:Red"
	//so we check
	if(first)xNode = xMainNode.getChildNode(ptr);
	else xNode = xNode.getChildNode(ptr);
	
	//finally we return the node
	//it might not contain anything or even exist
	//we do checking outside of this function
	//before using it
	return xNode;	
}


