/*
xml.js.php

Copyright (c) Gareth Hadfield 2008
*/

/* xml */


function load_message_html(aMessage){
  return(OPENDOTS_LOADING_MESSAGE_START + aMessage + OPENDOTS_LOADING_MESSAGE_END);
}

function load_fail_message(aErrorText, aDocumentName){
  var aMessage = "<span style='font-size:10pt;'>Failed to load file: " + aDocumentName + " \n Error: " +  aErrorText + "</span>";
  show_global_message(aMessage, ["Ok"]);
}

function save_fail_message(aErrorText, aDocumentName){
  var aMessage = "<span style='font-size:10pt;'>Failed to save file: " + aDocumentName + " \n Error: " +  aErrorText + "</span>";
  show_global_message(aMessage, ["Ok"]);
}

function load_fail_message_http(aHttp, aDocumentName){
  load_fail_message(aHttp.statusText, aDocumentName);
}

function IEXMLHttpRequest(){
  this.http = new ActiveXObject('Microsoft.XMLHTTP');

  this.open = bind(this, function(aMethod, aUrl, aAsync, aUser, aPassword){
    return(this.http.open(aMethod, aUrl, aAsync, aUser, aPassword));
  });

  this.setRequestHeader = bind(this, function(aHeader, aValue){
    return(this.http.setRequestHeader(aHeader, aValue));
  });

  this.send = bind(this, function(aData){
    return(this.http.send(aData));
  });

  this.abort = bind(this, function(){
    return(this.http.abort());
  });

  this.getAllResponseHeaders = bind(this, function(){
    return(this.http.getAllResponseHeaders());
  });

  this.http.onreadystatechange = bind(this, function(){
    var result;
    try{
      this.responseText = this.http.responseText;
      this.responseXML = this.http.responseXML;
      this.status = this.http.status;
      this.statusText = this.http.statusText;

      this.readyState = this.http.readyState;

      if(this.onreadystatechange != undefined){
        result = this.onreadystatechange(arguments);
      }
    }
    catch(aError){
      // do nothing
    }

    return(result);
  });
}

function createXMLHttpRequest(){
  var aHttp;
  if((window.XMLHttpRequest == undefined) && (window.ActiveXObject != undefined)){
    aHttp = new IEXMLHttpRequest();
  }
  else{
    aHttp = new XMLHttpRequest();
  }
  return(aHttp);
}

/* Loading */


/* todo - in process of building class wrapper for these functions */

function THTTPLoader(aOnLoad, aOnAfterLoad, aGetRemoteFile, aAllowCache,
    aUseAsynch, aOnLoadFail, aUseFailMessage){

  if(aGetRemoteFile == undefined){
    aGetRemoteFile = false;
  }

  if(aAllowCache == undefined){
    aAllowCache = false;
  }

  if(aUseFailMessage == undefined){
    aUseFailMessage = true;
  }

  this.onLoad = aOnLoad;
  this.onAfterLoad = aOnAfterLoad;
  this.onLoadFail = aOnLoadFail;
  this.getRemoteFile = aGetRemoteFile;
  this.allowCache = aAllowCache;
  this.useAsynch = aUseAsynch;
  this.useFailMessage = aUseFailMessage;

  this.doOnLoad = bind(this, function(aXMLDoc){
    if(this.onLoad != undefined){
      this.onLoad(aXMLDoc);
    }

    if(this.onAfterLoad != undefined){
      this.onAfterLoad();//aXMLDoc); // :(
    }
  });

  this.loadXML = bind(this, function(aDocumentName){
    return load_xml(aDocumentName, this.doOnLoad, this.getRemoteFile,
      this.allowCache, this.useAsynch, this.onLoadFail, this.useFailMessage);
  });

  this.loadText = bind(this, function(aDocumentName){
    return load_text(aDocumentName, this.doOnLoad, this.getRemoteFile,
      this.allowCache, this.useAsynch, this.onLoadFail, this.useFailMessage);
  });
}

function do_load_xml(aDocumentName, aXMLDocOnLoad, aGetRemoteFile, aAllowCache,
    aUseAsynch, aOnLoadFail, aUseFailMessage){
  var url;

  if(aGetRemoteFile==undefined){
    aGetRemoteFile = false;
  }

  if(aAllowCache==undefined){
    aAllowCache = false;
  }

  if(aUseAsynch==undefined){
    aUseAsynch = (aXMLDocOnLoad != undefined);
  }

  if(aUseFailMessage==undefined){
    aUseFailMessage = true;
  }

  var aHttp = createXMLHttpRequest();

  if(aAllowCache){
    url = aDocumentName;
  }
  else{
    // add query string to avoid caching
    url = add_query_string(aDocumentName, random_query_string());
  }

  var aAsynch = aUseAsynch;//(aXMLDocOnLoad != undefined);

  url = add_http(url);
/*
  if(url.substr(0, 4)!="http"){
    // assume current server
    var aPathName = location.protocol + "//" + location.host + location.pathname;
    url = aPathName + url;
  }
*/
  aHttp.documentName = aDocumentName;
  aHttp.useFailMessage = aUseFailMessage;
  aHttp.XMLDocOnLoad = aXMLDocOnLoad;

  aHttp.onreadystatechange = bind(aHttp, function(){
    if(this.readyState == 4) {
      if(this.status == 200){
        // 200 - Ok
        if(this.responseText != undefined){
   	      if(aAsynch){
            this.XMLDocOnLoad(this);
          }
        }
        else{
          if(!this.failed){
            this.failed = true;
            if(this.useFailMessage){
              load_fail_message_http(this, this.documentName);
            }
            if(aOnLoadFail != undefined){
              aOnLoadFail(this);
            }
          }
        }
      }
      else{
     	  // not 200 - not ok
        if(!this.failed){
          this.failed = true;
          if(this.useFailMessage){
            load_fail_message_http(this, this.documentName);
          }
          if(aOnLoadFail != undefined){
            aOnLoadFail(this);
          }
        }
      }
  	}
  });

  if(aGetRemoteFile){
    set_cookie("opendots_getremotefile_validate", cookie_value("PHPSESSID"));
    aHttp.open("GET", HTTP_FMD+"getremotefile.php?url="+escape(url), aAsynch);
  }
  else{
    aHttp.open("GET", url, aAsynch);
  }

  if(IS_FF){
    try{
      aHttp.send(null);
    }
    catch(aError){
      // for naughty ff errors
      load_fail_message_http(aHttp, aHttp.documentName);
      aHttp = undefined;
    }
  }
  else{
    aHttp.send(null);
  }

  if(!aAsynch){
    return(aHttp);
  }
}

function load_xml(aDocumentName, aXMLDocOnLoad, aGetRemoteFile, aAllowCache,
    aUseAsynch, aOnLoadFail, aUseFailMessage){
  // loads the given xml file

  if(aGetRemoteFile == undefined){
    aGetRemoteFile = false;
  }

  if(aAllowCache == undefined){
    aAllowCache = false;
  }

  var aOnLoad = undefined;

  if(aXMLDocOnLoad != undefined){
    aOnLoad = function(aHttp){
      aXMLDocOnLoad(aHttp.responseXML);
    }
  }
  var aResult = do_load_xml(aDocumentName, aOnLoad, aGetRemoteFile, aAllowCache,
    aUseAsynch, aOnLoadFail, aUseFailMessage);

  if(aResult != undefined){
    return(aResult.responseXML);
  }
}

function load_text(aDocumentName, aDocOnLoad, aGetRemoteFile, aAllowCache,
    aUseAsynch, aOnLoadFail, aUseFailMessage){
  var aOnLoad = undefined;

  if(aGetRemoteFile==undefined){
    aGetRemoteFile = true; // nb
  }

  if(aAllowCache==undefined){
    aAllowCache = false;
  }

  if(aDocOnLoad!=undefined){
    aOnLoad = function(aHttp){
      aDocOnLoad(aHttp.responseText);
    }
  }

  var aResult = do_load_xml(aDocumentName, aOnLoad, aGetRemoteFile, aAllowCache,
    aUseAsynch, aOnLoadFail, aUseFailMessage);

  if((aResult!=undefined) && (aResult.status==200)){
    return(aResult.responseText);
  }
}

function load_local_text(aDocumentName, aDocOnLoad, aAllowCache,
    aUseAsynch, aOnLoadFail, aUseFailMessage){
  // Load the raw text of a file - (eg dont run the .php just return the php code)
  var aUrl = HTTP_FMD + "get_local_file.php?filename="+encodeURIComponent(aDocumentName);
  return(load_text(aUrl, aDocOnLoad, false, aAllowCache,
    aUseAsynch, aOnLoadFail, aUseFailMessage));
}


// xml generation

function xml_tag(aString, aTagType, aPrefix, aPostfix){
  // return aString wrapped within an xml tag eg. <aTagType>aString</aTagType>
  if(aPrefix==undefined){
    aPrefix="";
  }
  if(aPostfix==undefined){
    aPostfix="";
  }
  return(aPrefix+"<"+aTagType+">" + aString + "</"+aTagType+">"+aPostfix);
}

//aText = "%2B";
//aText = aText.replace(/\%2B/g, escape("%2B"));
//alert(aText + " " + );

function urlencode(aText){
  aText = aText.replace(/\+/g, '%2B');
	return(escape(aText));
}

function urldecode(aText){
	aText = aText.replace(/\%2B/g, '+');
  return(aText);
}

function xml_encode(aString){
  return(urlencode(encodehtmlspecialchars(aString)));
}

function xml_decode(aString){
  return(decodehtmlspecialchars(urldecode(aString)));
}

function in_string(aNeedle, aString){
  var re = new RegExp(aNeedle);
  return( aString.search(re) != -1 );
}

function validate_file_name(aFileName){
  var result = true;

  if(aFileName.search(/[^a-zA-Z0-9/\-\_\.]/) != -1){
    result = false;
  }

  return(result);
}

/* save xml */

function save_xml(aDocumentName, aXML, aSaverScript){
  // save the given aXML text as the given aDocumentName
  
  if(aSaverScript == undefined){
    // defaults to save opendots page
    aSaverScript = HTTP_FMD+"save_opendots_page.php";
  }

  if(validate_file_name(aDocumentName)){
    var http = createXMLHttpRequest();
    var url = aSaverScript;
    var params = "xml=" + aXML + "&document=" + aDocumentName;

    http.open("POST", url, true);

    //http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
    http.setRequestHeader("Content-length", params.length);
    http.setRequestHeader("Connection", "close");

    http.onreadystatechange = function(){
    	if(http.readyState == 4 && http.status == 200) {
    		if(http.responseText != ""){
          show_global_message("<span style='font-size:12pt;'>" + http.responseText + "</span>", ["Ok"]);
        }
    	}
    };

    http.send(params);
  }
  else{
    save_fail_message("Invalid filename", aDocumentName);
  }
}

function attributes_xml(aElement){
  // return a string of xml representing the attributes of the given element
  var aXML = "";

  for(var iAttribute=0; iAttribute<aElement.attributes.length; iAttribute++){

    var aAttribute = aElement.attributes[iAttribute];

    if(allowed_attribute(aAttribute.name)){
      aXML += xml_tag(xml_encode(aElement.getAttributeText(aAttribute.name)), aAttribute.name, "", "\n");
    }
  }

  return(aXML);
}

function open_test_xml_window(){
  var aWindow = window.open(HTTP_FMD+"show_test_xml.php");
}

function popup_xml_source(aXML){
  var aXmlView = popup_text_editor(aXML, undefined, "XML Source");
  var aMainGroup = aXmlView.getToolbarGroup("main");
  var aOpenButton = aMainGroup.addToolbarButton("Open in new browser window " +
    "(NB content will be publicly accessible as " +
    "http://gtdesktop.com/test_xml.xml)");
  aOpenButton.doOnClick = bind(aXmlView, function(){
    //debug(xml_encode(this.text_editor.value));
    if(IS_SAFARI){
      // safari rocks!
      var aWindow = window.open();
      aWindow.document.write(this.text_editor.value);
      aWindow.document.close();
    }
    else{
      save_xml("", xml_encode(this.text_editor.value), HTTP_FMD+"save_test_xml.php");
      open_test_xml_window();
    }
  });

}


