
function XmlElement(s,t)
{
   this.name = s;
   this.text = (t&&t!=null ? iman.xmlEncode(t) : "");
   this.children = new Array();
   this.attributes = new Array();
   
   function add(element)
   {
      this.children[this.children.length] = element;
   }
   
   function clearChildren()
   {
      this.children = new Array();
   }
   
   function toString()
   {
      var str = "<" + this.name;
      var a = this.attributes;
      for (var i in a) str += " " + i + "=\"" + a[i] + "\"";
      str += ">";
   
      var c=this.children;
      if (c && c.length>0)
         for (var i in c) str += c[i].toString();
      else
         str += this.text;
   
      str += "</" + this.name + ">";
      return str;
   }
   
   function getName()
   {
      return this.name;
   }
   
   function getText()
   {
      return iman.xmlDecode(this.text);
   }
   
   function getChildrenTextTrim(s)
   {
      var c=this.getChildren(s);
      var ret = new Array();
      for (var i=0; i<c.length; i++)
      {
         ret[ret.length] = iman.trim(c[i].text);
      }
      return ret;
   }
   
   function getChildTextTrim(s)
   {
      var c=this.children;
      for (var i in c) if(c[i].name==s) return iman.trim(c[i].text);
      return null;
   }
   
   //return child element
   function getChild(s)
   {
      var c=this.children;
      if (!s) return c[0];
      for(var i in c) if(c[i].name==s) return c[i];
      return null;
   }
   
   //return child element as a string
   function getChildString(s)
   {
      var c=this.getChild(s);
      if (c==null) return "";
      else return c.toString();
   }
   
   //return array of children elements
   function getChildren(s)
   {
      var c=this.children;
      if (!s) return c;
      var ret = new Array();
      for(var i in c) if(c[i].name==s) ret[ret.length] = c[i];
      return ret;
   }
   
   //return array of children elements as strings
   function getChildrenStrings(s)
   {
      var c=this.getChildren(s);
      var ret = new Array();
      for (var i=0; i<c.length; i++)
      {
         ret[ret.length] = c[i].toString();
      }
      return ret;
   }
   
   function getAttributeValue(k)
   {
      return this.attributes[k];
   }
   
   function setAttribute(k,v)
   {
      this.attributes[k] = v;
   }
   
   this.add = add;
   this.toString = toString;
   this.getName = getName;
   this.getText = getText;
   this.getChildTextTrim = getChildTextTrim;
   this.getChildrenTextTrim = getChildrenTextTrim;
   this.getChildren = getChildren;
   this.getChildrenStrings = getChildrenStrings;
   this.getChild = getChild;
   this.getChildString = getChildString;
   this.setAttribute = setAttribute;
   this.addAttribute = setAttribute;
   this.getAttributeValue = getAttributeValue;
   this.clearChildren = clearChildren;
}

// requres XmlParser.js
function parseXml(s)
{
   var xmlDoc = iman.parseXmlString(s);
   return buildChild(xmlDoc.documentElement)
}

function buildChild(child)
{
   if(!child)
   {
      return null;
   }
   else if(child.childNodes.length>0 && child.childNodes[0].nodeType==1)
   {
      var c = new XmlElement(child.nodeName);
      var attrs=child.attributes;
      for(var i=0; i<attrs.length; i++)
      {
         c.attributes[attrs.item(i).name] = attrs.item(i).value;
      }

      var children = child.childNodes;
      for(var i=0; i<children.length; i++)
      {
         c.children[c.children.length] = buildChild(children[i]);
      }
      return c;
   }
   else
   {
      var c = new XmlElement(child.nodeName, (child.childNodes[0]?child.childNodes[0].nodeValue:""));
      var attrs=child.attributes;
      for(var i=0; i<attrs.length; i++)
      {
      	c.attributes[attrs.item(i).name] = attrs.item(i).value;
      }
      return c;
   }
}



// ================ Widget Helper Methods =====================

function getValueFromXml(str)
{
   s = str.indexOf("<value>");
   e = str.indexOf("</value>");
   if((s!=-1) && (e!=-1))
   {
      return iman.xmlDecode(str.substring(s+7, e));
   }
   return "";
}

function toXmlString(value, mode)
{
   var modeStr = (mode? " mode='" + mode + "' " : "");
   var valStr  = (value && value.length>0 ? "<value>" + iman.xmlEncode(value) + "</value>" : "");
   return "<attribute"+modeStr+">"+valStr+"</attribute>";
}

function getWidgetValueAsXml(t)
{
   var mode = eval("document.forms[0]." + t.name + "_mode");

   if(mode)
      return toXmlString(t.value, mode[mode.selectedIndex].value);
   else
      return toXmlString(t.value);
}

function initWidgetFromXml(t, x)
{
   t.value = getValueFromXml(x);
   initMooMode(t.name,x);
}

function initMooMode(controlName, x)
{
   if(x==null || x.length<1)
      return;

   // set mode
   var modeControl = eval("document.forms[0]." + controlName + "_mode");
   var s = x.indexOf("mode='");
   if(modeControl && s!=-1)
   {
      s+=6;
      var e = x.indexOf("'", s);
      var mode = x.substring(s,e);

      var i=0;
      if(mode=="set") i=1;
      else if(mode=="add") i=2;
      else if(mode=="remove") i=3;
      modeControl.selectedIndex = i;
   }
}
