var Net = {
  UNINITIALIZED : 0,
  LOADING       : 1,
  LOADED        : 2,
  INTERACTIVE   : 3,
  COMPLETE      : 4,
  /* Constructor for the Net object
  Parameters:
    url: The URL to the server file
    onLoad: Handler function when the data has loaded, can access data like so, this.req.status etc.
    onError: Handler for errors, if this isn't passed default error will be used.
    method: The HTTP request type, such as GET or POST.
    params: This will post parameters back to the server.
    contentType: If passed will add a content type. If the metohd is POST, it'll automatically be assigned a content type "application/x-www-form-urlencoded".        
    pass: An object to pass along to the handle function
  */
  Loader : function( obj ) {
    if ( !obj['url'] || 
         !obj['onLoad'] ) { return false };
    this.req 	       = null;
    this.url 	       = obj['url'];
    this.onLoad      = obj['onLoad'];
    this.onLoading   = ( !obj['onLoading']   ) ? function() {}     : obj['onLoading'];
    this.onError     = ( !obj['onError']     ) ? this.defaultError : obj['onError'];          
    this.method      = ( !obj['method']      ) ? "GET"             : obj['method'].toUppercase();
    this.contentType = ( !obj['contentType'] ) ? null              : obj['contentType'];
    this.params      = ( !obj['params']      ) ? null              : obj['params'];  
    this.pass        = ( !obj['pass']        ) ? null              : obj['pass'];     
    this.loadDoc();
  }        
};
Net.getXmlHttp = function() {
  var req;
  if ( window.XMLHttpRequest ) { req = new XMLHttpRequest(); }  
  else {
    try {
      req = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        req = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) {
        req = null;
      }
    }
  }
  return req;
}
Net.Loader.prototype = {
  loadDoc : function() {
    if ( !this.contentType && this.method == "POST" ) {
      this.contentType = "application/x-www-form-urlencoded";
    }
    this.req = Net.getXmlHttp();    
    if ( this.req ) {
      try {
        var loader = this; //make sure we get the right scope.
        this.req.onreadystatechange = function() {
          loader.onReadyState.call( loader );          
        }
        this.req.open( this.method, this.url, true );
        if ( this.contentType ) {
          this.req.setRequestHeader( "Content-Type", this.contentType );
        }
        this.req.send( this.params );
      }
      catch ( err ) {
        this.onError.call( this );
      }
    } else {
      //do nothing, let the default html happen as normal
      return null;
    }
  },
  onReadyState : function() {
    var req 	= this.req;
    if ( req.readyState == Net.COMPLETE ) {
      var httpStatus = req.status;
      if ( httpStatus == 200 || httpStatus == 0 ) {
        this.onLoad.call( this );
      }
      else {
        this.onError.call( this );
      }
    }
    else {
      this.onLoading.call( this );
    }
  },
  defaultError : function() {
    alert( "error fetching data!" +
    "\n\nreadyState: " + this.req.readyState +
    "\nstatus: " + this.req.status +
    "\nheaders: " + this.req.getAllResponseHeaders() );
  }
}

/* 
Api, simplifies the call to network requests for music genres.
*/      
var Api = {
  GENRE_PROMO : "/music/includes/api_genre_promo.sssi",
  ALBUM_PROMO : "/music/includes/api_album_promo.sssi",
  MUSIC_NEWS  : ""
}
Api.Query = function( obj ) {
  if ( !obj['api']  ||
       !obj['pass'] ||
       !obj['onLoad'] ) { return false };
  this.onLoad    = obj['onLoad'];
  this.api       = obj['api'];
  this.pass      = obj['pass'];
  //alert( this.params );
  this.onLoading = ( !obj['onLoading'] ) ? function() {} : obj['onLoading'];
  this.onError   = ( !obj['onError']   ) ? null          : obj['onError'];
  this.buildQuery();
}      
Api.Query.prototype = {
  buildQuery : function() {
    this.query = "?return=" + this.pass.genres.join('&');
  },
  send : function() {
    new Net.Loader({
      url       : this.api + this.query,
      onLoad    : this.onLoad,
      onLoading : this.onLoading,
      onError   : this.onError,
      pass      : this.pass
    }); 
  }
}