/*
 * Name:
 * mtjs_loader.js
 *
 * Legal:
 * Copyright (c) 2008 Micah Tischler
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * Description:
 * Provides loading of external JS files and hook code for use such that 
 * availability is guaranteed by invocation-time
 *
 * Distribution site:
 * http://micahtischler.com/
 *
 * Versioning: 
 * "1.0"
 * $Id: mtjs_loader.js 614 2008-08-01 23:04:32Z junior $
 *
 */
 
var mtjs_loader=null;

function mtjs_loader_class(){
  if (mtjs_loader==null){
    mtjs_loader=this;
    this.targets=new Array();
    this.load_count=0;
    this.head=document.getElementsByTagName('head')[0];
    this.fault=false;
    this.reason='';
    this.onload=null;
    this.timer=null;
    this.base_url=location.protocol+'//'+location.host;
    this.lib_path='/jslib/';
    this.include((location.pathname.replace(/\/$/,'/index')).replace(/([.][^\/]*)*$/,'_includer.js'));
  } else {
    alert("There should be only one mtjs_loader.  Please stop trying to make more.");
  }
}
mtjs_loader_class.prototype.set_lib_path = function (path){
  this.lib_path=path;
} 
mtjs_loader_class.prototype.lib_include = function (src){
  src=this.lib_path+src;
  this.inner_include(src);
}
mtjs_loader_class.prototype.include = function (src){
  if (src.search("^/")==-1){
    src=location.pathname.replace(/\/[^\/]*$/,'/')+src;
  }
  this.inner_include(src);
}
mtjs_loader_class.prototype.inner_include = function (src){
  var http_request=false,
      target_num=0;
  if (!this.fault){
    target_num=this.find_target(src);
    if (target_num>=0){
      return;
    }
    this.targets.push({'src':src, 'value':false});
    if (window.XMLHttpRequest){
      http_request=new XMLHttpRequest();
      if (http_request.overrideMimeType){
        http_request.overrideMimeType('text/xml');
      }
    } else {
      if (window.ActiveXObject){
        try {
          http_request=new ActiveXObject('Msxml2.XMLHTTP');
        }
        catch(e) {
          try {
            http_request=new ActiveXObject('Microsoft.XMLHTTP');
          }
          catch(e) {
          }
        }
      }
    }
    if (!http_request){
      this.fault=true;
      this.reason="will not be able to include any external javascript";
      return;
    }
    http_request.onreadystatechange=function(){mtjs_loader.ajax_tap(http_request,src);};
    http_request.open('GET', this.base_url+src, true);
    http_request.send(null); 
  }
}
mtjs_loader_class.prototype.injector = function (buffer,id){
  var newjs=document.createElement('script'); 
  newjs.setAttribute('type', 'text/javascript');
  newjs.setAttribute('id','mtjs_loader_script_'+id);
  this.head.appendChild(newjs);
  try {
    newjs.appendChild(document.createTextNode(buffer));
  } 
  catch(e) {
    newjs.text=buffer;
  }
}
mtjs_loader_class.prototype.set_onload = function (func){
  this.onload=func;
}
mtjs_loader_class.prototype.ready = function (){
  var iter;
  if ((this.load_count!=this.targets.length)||(this.load_count==1)){
    return false;
  }
  if (this.onload==null){
    this.fault=true;
    this.reason="need an onload function to be specified and none were supplied";  
    return false;
  }
  return true;
}
mtjs_loader_class.prototype.ajax_tap = function(http_request,src){
  try {
    if (http_request.readyState==4){
      if (http_request.status==200) {
        this.targets[this.find_target(src)].value=http_request.responseText;
      } else {
        this.fault=true;
        this.reason="couldn't include "+src+" due to a bad return status";
      }
    }
  }
  catch(e) {
    this.fault=true;
    this.reason="couldn't include "+src+" due to server issues: "+e.description;
  }
}
mtjs_loader_class.prototype.find_target=function(src){
  var iter;
  for (iter=0;iter<this.targets.length;iter++){
    if (this.targets[iter].src==src){
      return iter;
    }
  }
  return -1;
}
mtjs_loader_class.prototype.onloader=function(){
  for (;(this.load_count<this.targets.length)&&(this.targets[this.load_count].value);this.load_count++){
    this.injector(this.targets[this.load_count].value,this.load_count);
    this.targets[this.load_count].value=false;
  }
  if (this.ready()){
    this.onload();
  } else {
    if (!this.fault){
      this.timer=setTimeout("mtjs_loader.onloader();",50);
    } else {
      if (this.reason!=''){
        alert("mtjs_loader: "+this.reason);
        this.reason='';
      }
    }
  }
}

new mtjs_loader_class();
