/*
$Id: MiniXmlParser.cc 2319 2011-12-16 12:40:03Z yinamura $
 */
#include "MiniXmlParser.hh"
///////////////////////////////////////
MiniXmlParser::
MiniXmlParser(){
  xml_tree = NULL;
  st = "";
}
///////////////////////////////////////
MiniXmlParser::
~MiniXmlParser(){
  // Added by Ito, T. 20101029.
  if (xml_tree != NULL){
    mxmlDelete(xml_tree);
  }
}
///////////////////////////////////////
mxml_node_t * MiniXmlParser::
CreateNewTree(){
  xml_tree = mxmlNewXML( "1.0" );
  return xml_tree;
}
///////////////////////////////////////
void MiniXmlParser::
SaveXmlTree( string FileName ){
  FILE *fp;
  fp = fopen( FileName.c_str(), "w");
  mxmlSaveFile( xml_tree , fp, MXML_NO_CALLBACK );
  fclose( fp );
}
///////////////////////////////////////
mxml_node_t * MiniXmlParser::
ReadXmlTree( string FileName ){
  // Change a return value from a pointer of tree to one of xml_tree. 20101029
  FILE *fp;
  //mxml_node_t *tree;
  fp = fopen( FileName.c_str(), "r" );
  //tree = mxmlLoadFile(NULL, fp,
  // [inamura 111116]-->.
  if (xml_tree != NULL){
    mxmlDelete(xml_tree);
  } //<--[inamura 111116]
  xml_tree = mxmlLoadFile(NULL, fp,
			  MXML_OPAQUE_CALLBACK); //[inamura 130302]
			  //MXML_TEXT_CALLBACK);
  fclose(fp);
  //return tree;
  return xml_tree;
}
///////////////////////////////////////
mxml_node_t *MiniXmlParser::
NewElement( mxml_node_t *node, string name ){
  return mxmlNewElement( node, name.c_str() );
}
///////////////////////////////////////
void MiniXmlParser::
NewText( mxml_node_t *node, string text ){
  mxmlNewText( node, 0, text.c_str() );
}
///////////////////////////////////////
void MiniXmlParser::
NewText( mxml_node_t *node, vector<string> text ){
  StringTools *st = new StringTools();
  string s = st -> VecStringToString( text );
  NewText( node, s );
  delete st;
}
///////////////////////////////////////
void MiniXmlParser::
NewText( mxml_node_t *node, vector<UInt4> text ){
  StringTools *st = new StringTools();
  string s = st -> VecUInt4ToString( text );
  NewText( node, s );
  delete st;
}
///////////////////////////////////////
void MiniXmlParser::
NewText( mxml_node_t *node, vector<Int4> text ){
  StringTools *st = new StringTools();
  string s = st -> VecInt4ToString( text );
  NewText( node, s );
  delete st;
}
///////////////////////////////////////
void MiniXmlParser::
NewText( mxml_node_t *node, vector<Double> text ){
  StringTools *st = new StringTools();
  string s = st -> VecDoubleToString( text );
  NewText( node, s );
  delete st;
}
//////////////////////////////////////
Int4 MiniXmlParser::
SaveString( mxml_node_t *node, Int4 MaxLength,
	    mxml_save_cb_t cb ){
  Int4 r;
  Char *b = new Char [MaxLength];
  r = mxmlSaveString( node, b, MaxLength, cb );
  
  string *temp = new string( b );
  st.clear();
  st = *temp;
  delete [] b;
  delete temp;
  return r;
}
///////////////////////////////////////
string MiniXmlParser::
PutString(){
  string r = st.substr( 0, st.size()-1 );
  return r;
}
///////////////////////////////////////
vector<string> MiniXmlParser::
PutStringVector( mxml_node_t *node, Int4 MaxLength ){
  string t = PutString( node, MaxLength );
  StringTools *st = new StringTools();
  vector<string> r = st -> SplitString( t );
  delete st;
  return r;
}
///////////////////////////////////////
vector<Int4> MiniXmlParser::
PutInt4Vector( mxml_node_t *node, Int4 MaxLength ){
  string t = PutString( node, MaxLength );
  StringTools *st = new StringTools();
  vector<string> r = st -> SplitString( t );
  vector<Int4> vi;
  for( UInt4 i=0; i<r.size(); i++ ){
    vi.push_back( st->StringToInt4( r[i] ) );
  }
  delete st;
  return vi;
}
///////////////////////////////////////
vector<UInt4> MiniXmlParser::
PutUInt4Vector( mxml_node_t *node, Int4 MaxLength ){
  string t = PutString( node, MaxLength );
  StringTools *st = new StringTools();
  vector<string> r = st -> SplitString( t );
  vector<UInt4> vi;
  for( UInt4 i=0; i<r.size(); i++ ){
    vi.push_back( st->StringToUInt4( r[i] ) );
  }
  delete st;
  return vi;
}
///////////////////////////////////////
vector<Double> MiniXmlParser::
PutDoubleVector( mxml_node_t *node, Int4 MaxLength ){
  string t = PutString( node, MaxLength );
  StringTools *st = new StringTools();
  vector<string> r = st -> SplitString( t );
  vector<Double> vi;
  for( UInt4 i=0; i<r.size(); i++ ){
    vi.push_back( st->StringToDouble( r[i] ) );
  }
  delete st;
  return vi;
}
///////////////////////////////////////
string MiniXmlParser::
PutString( mxml_node_t *node, Int4 MaxLength ){
  SaveString( node, MaxLength );
  return PutString();
}
///////////////////////////////////////
mxml_node_t * MiniXmlParser::
WalkPrevious( mxml_node_t *node, mxml_node_t *top,
	      int descend ){
  return mxmlWalkPrev( node, top,
		       descend );
}
///////////////////////////////////////
mxml_node_t * MiniXmlParser::
WalkNext( mxml_node_t *current, mxml_node_t *tree,
	  int descend ){
  return mxmlWalkNext( current,tree,
		      descend );
}
///////////////////////////////////////
mxml_node_t * MiniXmlParser::
FindElement(  mxml_node_t *node,
	      mxml_node_t *top,
	      string name,
	      string attr,
	      string value,
	      int descend ){

  Char *Name  = new Char [ name.size() + 1 ];
  Char *Attr  = new Char [ attr.size() + 1 ];
  Char *Value = new Char [ value.size() + 1 ];

  strcpy( Name,   name.c_str() );
  strcpy( Attr,   attr.c_str() );
  strcpy( Value, value.c_str() );

  if( name == "NULL" ){
    delete [] Name;
    Name = NULL;
  }
  
  if( attr == "NULL" ){
    delete [] Attr;
    Attr = NULL;
  }

  if( value == "NULL" ){
    delete [] Value;
    Value = NULL;
  }

  mxml_node_t *r;
  r = mxmlFindElement( node, top, 
		       Name,
		       Attr, 
		       Value,
		       descend );
  delete [] Name;
  delete [] Attr;
  delete [] Value;
  return r;

}
///////////////////////////////////////
string MiniXmlParser::
PutAttr( mxml_node_t *node, string name, UInt4 MaxLen ){
  Char *buf = new Char [MaxLen+1];
  /*
  strcpy( buf, mxmlElementGetAttr( node, name.c_str() ) );
  string r( buf );
  delete [] buf;
  return r;
  */
  const char *buf2 = mxmlElementGetAttr( node, name.c_str() );
  string r="";
  if (buf2!=NULL){
      strcpy( buf, buf2 );
      r.append( buf );
  }
  delete [] buf;
  
  return r;

}
///////////////////////////////////////
void MiniXmlParser::
SetAttr( mxml_node_t *node, string name, string value ){
  mxmlElementSetAttr( node,
		      name.c_str(),
		      value.c_str() );
}
///////////////////////////////////////
