/*
opendot_xml.js.php

Loading and saving opendots documents.
Conversion of dom objcects (document and dots) to xml and xml to dom.

Copyright (c) Gareth Hadfield 2008
*/


// Dot -> xml conversioin

function dot_xml(aDot){
  // return a string of xml representing the given dot
  return(xml_tag("\n" + attributes_xml(aDot), "dot"));
}

function dots_xml(aDots){
  // return a string of xml representing all the non-template dots in the given array
  var aXML = "";

  for(var iDot=0; iDot<aDots.length; iDot++){
    var aTemplateDot = aDots[iDot].getAttributeText("template_dot");
    if(aTemplateDot == undefined){
      aTemplateDot = "false";
    }
    if(aTemplateDot=="false"){
      aXML += dot_xml(aDots[iDot]) + "\n";
    }
  }
  return(aXML);
}

function all_dots_xml(aParentNode){
  // return a string of xml representing all the dots in the document
  return(dots_xml(all_dots(aParentNode)));
}

function document_xml(){
  return(xml_tag("\n" + attributes_xml(document.body), "document") + "\n");
}

/* Loading */

function do_on_after_load(aParentDot){
  // call aDot.doOnAfterLoad for all dots
  var aDots = all_dots(aParentDot);
  for(iDot=0; iDot < aDots.length; iDot++){
    aDots[iDot].doOnAfterLoad();
  }
  
  var aFunction = document.body.onload;

  if(aFunction != undefined){
    aFunction();
  }
  
  if(OPENDOTS_MODE==OPENDOTS_EDIT_MODE){
    refresh_properties();
    refresh_opendots_list();
  }

/*
  var aOnload = document.body.getAttributeText("onload");
  if(aOnload != undefined){
    eval(aOnload);
  }
*/
}

function do_on_after_load_template(aParentDot){
  // call aDot.doOnAfterLoad for all template dots
  var aDots = all_dots(aParentDot);
  for(iDot=0; iDot < aDots.length; iDot++){
  	if(aDots[iDot].isTemplateDot()){
	    aDots[iDot].doOnAfterLoad();
  	}
  }
  
  // todo template document onload?

  if(OPENDOTS_MODE==OPENDOTS_EDIT_MODE){
    refresh_properties();
    refresh_opendots_list();
  }
}

function loading_distractor(){
  // clobbers document.body contents with loading distractor
  var aDistractorHTML = "<table class='loading_distractor_table'><tr><td><center><img src='"+THEME_DIR+"loading.gif'></center></td></tr></table>";
  setAttributeText(document.body, "content", aDistractorHTML);
}

function load_page(aPageName){
  if(aPageName != null){
    if(aPageName != ""){
      // load the given page

      document.currentPage = aPageName;

      // delete_all_dots is done before init_document otherwise dots can get
      // orphaned and a popup message occurs
      delete_all_dots();

      init_document();

      if(close_all_floats != undefined){
        close_all_floats(false);
      }

      var aFileName = aPageName + ".xml";

//      loading_distractor();

      doc_load(aFileName, do_on_after_load);
    }
    else{
      // new page
      do_new_document(false);
      check_select_template();
    }
  }
}

function doc_load(aFileName, aOnAfterLoad){
  // load an xml opendots document
  // generally - don't call this - call load_page

  if((aFileName != null) && (aFileName != "")){
    var aPathName = HTTP_FMD;
    var aHTTPLoader = new THTTPLoader();
    aHTTPLoader.onLoad = XMLDocOnLoad;
    aHTTPLoader.onAfterLoad = aOnAfterLoad;
    aHTTPLoader.loadXML(aPathName + "documents/" + aFileName); // todo use const
  }
}

function template_load(aPageName){
  // load an xml opendots document template
  if((aPageName != null) && (aPageName != "")){
    var aPathName = HTTP_FMD;
    var aXML = load_xml(aPathName + "documents/" + aPageName + ".xml"); // todo use const
    XMLDocOnLoadTemplate(aXML);
  }
}

function child_nodes_value(aNode){
  var result = "";
  for(var iChildNodes=0; iChildNodes<aNode.childNodes.length; iChildNodes++){
    result += aNode.childNodes[iChildNodes].nodeValue;
  }
  return(result);
}

function process_document(aDocument, aTemplateDocument){
  // Process the <document> element
  if(aTemplateDocument == undefined){
    aTemplateDocument = false;
  }
  
  for(var i=0; i<aDocument.childNodes.length; i++){
    var aNode = aDocument.childNodes[i];
    var aName = aNode.nodeName;
    var aValue = "";
    
    if(aName != "#text"){
      
      if(aNode.childNodes.length != 0){
        aValue = xml_decode(child_nodes_value(aNode));
      }

      if(aTemplateDocument){
        // append value to current template value
        var aCurrentValue;
        aCurrentValue = document.body.gat(OPENDOTS_TEMPLATE_PREFIX+aName);

        if(aCurrentValue == undefined){
          aCurrentValue = "";
        }
        document.body.sat(OPENDOTS_TEMPLATE_PREFIX+aName, aValue+aCurrentValue);
      }
      else{
        document.body.sat(aName, aValue);
      }
    }
  }
  
}

function process_dots(aDots, aTemplateDots){
  // Process the <dot> elements
  if(aTemplateDots == undefined){
    aTemplateDots = false;
  }

  var aDot;
  var aNewDot;
  var result = new Array();

  var aContentValue;

  for(var iDot=0; iDot<aDots.length; iDot++){
    aDot = aDots[iDot]; // the xml dot

    aNewDot = new_dot(undefined,undefined,undefined,undefined,undefined,undefined,false); // the dom dot
    result[iDot] = aNewDot;

    if(aTemplateDots){
      aNewDot.setAttributeText("template_dot", "true");
    }
    else{
      aNewDot.setAttributeText("template_dot", "false");
    }

    var aAttribute;
    var aName;
    var aValue;
    aContentValue = undefined;

    for(var iAttribute=0; iAttribute<aDot.childNodes.length; iAttribute++){
      aAttribute = aDot.childNodes[iAttribute];

      aName = aAttribute.nodeName;
      aValue = "";

      if(aName != "#text"){

        if(aAttribute.childNodes.length!=0){
          aValue = xml_decode(child_nodes_value(aAttribute));
        }

        if(aName=="content"){
          aContentValue = aValue; // save content and assign it last
        }
        else if(aName == "id"){
          aNewDot.id = ""; // so it doesnt find aNewDot (could be coincidentally auto-named as aValue)
          var aExistingElement = document.getElementById(aValue);
          if(aExistingElement != undefined){
            // this id already exists
            aNewDot.renamedID = true;
            aNewDot.previousID = aValue;
            // find a unique id
            aValue = find_unique_id(aValue);
          }

          aNewDot.setAttributeText(aName, aValue);
        }
        else{
          aNewDot.setAttributeText(aName, aValue);
        }

      }

    }

    if(aContentValue != undefined){
      aNewDot.setAttributeText("content", aContentValue);
    }
  }

  // loop all new dots and if a dot has been renamed then loop all dots and rename parent_id for children
  for(var iDot=0; iDot<result.length; iDot++){
    var aDot = result[iDot];
    if(aDot.renamedID != undefined){
      for(var iChild=0; iChild<result.length; iChild++){
        var aChild = result[iChild];
        if(aChild.getAttributeText("parent_id")==aDot.previousID){
          aChild.setAttributeText("parent_id", aDot.id);
        }
      }
    }
  }

  return(result);
}

function find_unique_id(aBaseId){
  var aNewValue = aBaseId;
  var aCounter = 0;
  while(document.getElementById(aNewValue)!=undefined){
    aNewValue = aBaseId + "_" + aCounter;
    aCounter++;
  }
  return(aNewValue);
}

function XMLDocOnLoadTemplate(aXMLDoc){
  assert(aXMLDoc != undefined, "XMLDocOnLoadTemplate(aXMLDoc) aXMLDoc cannot be undefined");

  document.loading++;

  var aDocument = aXMLDoc.getElementsByTagName("document")[0];
  process_document(aDocument, true);

  var aDots = aXMLDoc.getElementsByTagName("dot");
  process_dots(aDots, true);

  assign_z_index(); // needed because z_index may get assigned prior to parent_id

  document.loading--;
  refresh_sub_classes();
}

function XMLDocOnLoad(aXMLDoc){
  document.loading++;
  var aDocument = aXMLDoc.getElementsByTagName("document")[0];
  process_document(aDocument);

  var aDots = aXMLDoc.getElementsByTagName("dot");
  process_dots(aDots);

  assign_z_index(); // needed because z_index may get assigned prior to parent_id

  document.loading--;
  refresh_sub_classes();
}

function assign_z_index(){
  var aDots = all_dots();
  for(var iDot=0; iDot<aDots.length; iDot++){
    var aDot = aDots[iDot];
    set_z_index(aDot, aDot.getAttribute("z_index"));
  }
}
