/**
 * Beskrivelse
 *
 * @author	Thomas Sømoen <thomas at apt.no>
 * @version	20061005
 * @package	net
 */
var net = new Object();
net.READY_STATE_UNINITIALIZED=0;
net.READY_STATE_LOADING=1;
net.READY_STATE_LOADED=2;
net.READY_STATE_INTERACTIVE=3;
net.READY_STATE_COMPLETE=4;

/**
 * Klasse om håndterer forespørsler mellom klient og tjener.
 *
 * @access	public
 * @author	Tommy Gildseth  <tommy at gildseth.com>
 * @author	Thomas Sømoen <thomas at apt.no>
 * @version	20061005
 * @package	net
 */
net.XmlHttp = function(url, observer) {
  //member variables
  this.request		= null;
  this.isIE			= false;
  this.response		= null;
  this.observer		= new Array();
  this.method			= 'GET';
  this.params			= new Array();
  this.load(url);
}

/**
 * Definerer objektets metoder.
 *
 * @since	20061005
 */
net.XmlHttp.prototype = {
  /**
   * Legger til parameter som skal sendes til tjener.
   *
   * @access	public
   * @since	20061005
   * @param	string	name	Parameternavn
   * @param	string	value	Parameterverdi
   */
  reqParam:function(name, value){
    this.params.push(escape(name) + "=" + escape(value));
  },

  /**
   * Setter forespørselsmetoden.
   *
   * @access	public
   * @since	20061005
   * @param	string	method	Typen forespørsel som skal gjøres. kan være GET eller POST
   */
  requestMethod:function( method ) {
    if (method == 'GET' || method == 'POST') {
      this.method = method;
    } else {
      throw('Invalid request method');
    }
  },

  /**
   * Setter objektet som overvåker forespørselen.
   *
   * @access	public
   * @since	20061005
   * @param	Object	observer	Objektet som overvåker forespørslen.
   */
  attach:function( observer ) {
    this.observer.push(observer);
  },

  /**
   * Funksjonen laster filen fra tjeneren.
   *
   * @access	public
   * @since	20061005
   * @param	string	url	Filen som skal lastes fra tjeneren.
   */
  load:function( url ) {
    try {
      if (url) {
          this.loadXMLDoc(url);
      }
    } catch(e) {
      var msg = (typeof e == "string") ? e : ((e.message) ? e.message : "Unkown error");
      alert("Feil i AJAX kall til tjener:\n" + msg);
      return;
    }
  },

  /**
   * Funksjonen oppretter XmlHttp objektet og gjøre forespørselen til tjeneren.
   *
   * Det tas hensyn til metodeulikhetene på kryss av nettleserne.
   *
   * @access	public
   * @since	20061005
   * @param	string	url	Filen som skal lastes fra tjeneren.
   */
  loadXMLDoc:function(url) {
    objXmlHttp 	= this;
      reqParams 	= this.params.join('&');
      if( this.method == 'GET') {
        url = url + "?" + reqParams;
      }

      // branch for native XMLHttpRequest object
      if( window.XMLHttpRequest ){
          this.req = new XMLHttpRequest();
      // branch for IE/Windows ActiveX version
      } else if ( window.ActiveXObject ) {
          this.isIE 	= true;
          this.req 	= new ActiveXObject("Microsoft.XMLHTTP");
      }

      if( this.req ){
        this.req.onreadystatechange = function ( ) { objXmlHttp.processChange(); }
        this.req.open(this.method, url, true);
        if (this.method == 'POST') {
          this.req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        }
        this.req.send(reqParams);
      }
  },

  /**
   * Funksjon som overvåker svaret fra tjeneren.
   *
   * Funsksjonen svarer når tjeneren har sendt ferdig. Den sjekker så svarets innholdtype og oppretter et javascript-objekt dersom innholdtypen er json, rent tekst dersom det er tekst eller html, og et DOM-tre dersom det er XML.
   * Dersom det skjer en feil kalles feilhåndterrer eller standard feilfunksjon.
   *
   * @access	public
   * @since	20061005
   */
  processChange:function() {
      // only if req shows "loaded"
      if (this.req.readyState == net.READY_STATE_COMPLETE) {
          // only if "OK"
          if (this.req.status == 200) {
        var response = null;

        switch(this.req.getResponseHeader("Content-type")){
          case 'text/json':
            this.response = eval("("+ this.req.responseText+")");
            break;
          case 'text/xml':
            this.response = this.req.responseXML;
            break;
          default:
            this.response = this.req.responseText;
        }

        for(i = 0; i < this.observer.length; ++i) {
          this.observer[i].notify(this.response);
        }
           } else {
              alert("There was a problem communicating with the server:\n" + this.req.statusText);
           }
      }
  }
}

/**
 * Klasse som håndterer objektet som skal varsles når tjeneren har sendt svaret sitt.
 *
 * @access	public
 * @author	Tommy Gildseth  <tommy at apt.no>
 * @author	Thomas Sømoen <thomas at apt.no>
 * @version	20061005
 * @package	net
 */
net.Observer = function() {
  this.target = null;
}

/**
 * Funksjon som kalles når tjeneren har send ferdig. Funksjonen er her satt til en defaultfunksjon som viser en alert-boks med svaret.
 *
 * @access	public
 * @since	20061005
 * @param	var	response	Svaret fra tjeneren
 */
net.Observer.prototype.onLoad = function(response){
  alert(response);
}

/**
 * Funksjon som kalles når det oppstår en feil. Funksjonen er her satt til en defaultfunksjon som viser en alert-boks med feilmelding.
 *
 * @access	public
 * @since	20061005
 * @param	var	response	Svaret fra tjeneren
 */
net.Observer.prototype.onError = function(message){
  alert(message);
}

/**
 * Kort
 *
 * @access	public/private/protected
 * @since	### (versjonsnummer eller dato(YYYYMMDD))
 * @param	type	variabel	Beskrivelse
 * @return	type	Beskrivelse
 * @see	classname::function()
 */
net.getElementTextNS = function(prefix, local, parentElem, index) {
    var result = "";
    if (prefix && isIE) {
        // IE/Windows way of handling namespaces
        result = parentElem.getElementsByTagName(prefix + ":" + local)[index];
    } else {
        // the namespace versions of this method
        // (getElementsByTagNameNS()) operate
        // differently in Safari and Mozilla, but both
        // return value with just local name, provided
        // there aren't conflicts with non-namespace element
        // names
        result = parentElem.getElementsByTagName(local)[index];
    }
    if (result) {
        // get text, accounting for possible
        // whitespace (carriage return) text nodes
        if (result.childNodes.length > 1) {
            return result.childNodes[1].nodeValue;
        } else if (result.firstChild) {
            return result.firstChild.nodeValue;
        } else {
      return '';
    }
    } else {
        return "n/a";
    }
}
