// -*-Mode: Java;-*- 
/*
JourneySat, a library to georeference a travel journal using Google Maps.
Copyright (C) 2005  Paolo Montrasio, paolo AT paolomontrasio.com

This file is part of JourneySat (the Program).

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

/**
 * @author Paolo Montrasio paolo AT paolomontrasio.com
 */

// This is a kind of package JourneySat declaration in Java
if (JourneySat == undefined) var JourneySat = {};

/**
 * @class JourneySat.ResourceBundle
 * Manages a set of name/value pairs organized in a XML file in the format
 * <pre>
 * &lt;?xml version="1.0" ?&gt;
 * &lt;bundle name="it"&gt;
 * &lt;resource&gt;
 *   &lt;name&gt;resource_name&lt;/name&gt;
 *   &lt;value&gt;resource_value&lt;/value&gt;&lt;/resource&gt;
 * &lt;/resource&gt;
 * ...
 * &lt;/bundle&gt;
 * </pre>
 * The pairs are loaded asynchronously from the file.
 * @param {String} file The URL of the XML file 
 * @param {function} onload A function to call when the file has been loaded
 * @constructor
 */
JourneySat.ResourceBundle = function (file, onload) {
  this.onload = onload;
  this.request = GXmlHttp.create();
  this.request.open("GET", file, true);
  
  // Sets the trigger to parse the XML file
  this.parser = new JourneySat.ResourceParser();
  this.request.onreadystatechange = this.parser.parse(this);
  
  // Sends the request
  this.request.send(null);
}

/**
 * @private
 */
JourneySat.ResourceBundle.onload = null;

/**
 * @private
 */
JourneySat.ResourceBundle.request = null;

/**
 * Returns the request object for the URL of the XML file
 * @returns {GXmlHTTPRequest} the request object
 */
JourneySat.ResourceBundle.prototype.getRequest = function () {
  return this.request;
};

/**
 * The parser object for the XML file
 * @private
 * @type JourneySat.ResourceParser
 * @see JourneySat.ResourceParser
 */

JourneySat.ResourceBundle.prototype.parser = null;


/**
 * @class JourneySat.ResourceParser
 * Parses a resource XML file
 * @constructor
 */
JourneySat.ResourceParser = function () {};

/**
 * Returns a function that parses a resource file
 * @param {JourneySat.ResourceBundle} obj The resource bundle
 * @returns a parser function
 * @type function
 * @see JourneySat.ResourceBundle
 */
JourneySat.ResourceParser.prototype.parse = function (obj) {
  
  return function () {
    
    var request = obj.getRequest();
    
    if (request.readyState != 4) {
      return;
    }
    var xmlDoc = request.responseXML;
    var root = xmlDoc.documentElement;
    
    // Defines some functions that will be used only
    // inside this method
    function getNode(tag, parent) {
      var name = parent.nodeName;
      if (parent.hasChildNodes()) {
	var node = parent.firstChild;
	while (1) {
	  if (node.nodeName == tag) {
	    return node;
	  }
	  if (node == parent.lastChild) {
	    return null;
	  }
	  node = node.nextSibling;
	}
      } else {
	return null;
      }
    }
    
    function getValueOfNode(tag, parent) {
      var n = getNode(tag, parent);
      if (n == null) return null;
      return n.firstChild.nodeValue;
    }
    
    function getName(node) {
      return getValueOfNode("name", node);
    }
    
    function getValue(node) {
      return getValueOfNode("value", node);
    }
    
    // Reads properties from the XML file and create attributes in
    // obj.prototype with the name of the property and its value
    for (i = 0; i < root.childNodes.length; i++) {
      var node = root.childNodes[i];
      if (node.nodeName == "resource") {
	var name = getName(node);
	var value = getValue(node);
	
	// Adds to prototype
	obj[name] = value;
      }
    }
    // Calls the callback
    obj.onload();
  };
};

