if (!this.FAST) {
  this.FAST = {};
  /******************************************************************************
  *******                           CONFIG                                *******
  ******************************************************************************/
  //FAST.var = value;
  
  // START CODE  
  FAST.createObject = function (type, parent, id, styleName, content) {
    var obj = document.createElement(type);
    
    if (id && !document.getElementById(id)) {
      obj.id = id;
    } else {
      alert("Cannot create element.  The ID '" + id + "' already exists.");
      
      return null;
    }
    
    if (styleName) obj.className = styleName;
    if (content) obj.innerHTML = content;
    
    parent.appendChild(obj);
    return obj;
  }
  
  FAST.styleObject = function (obj, style) {
    var obj = FAST.getObject(obj);
    var style = style || {}; 
    if (obj)
      for(var i in style)
        obj.style[i] = style[i];
        
    return obj;
  }
  
  FAST.getObject = function (obj) {
    return obj.id ? obj : document.getElementById(obj);
  }
  
  FAST.removeObject = function (obj) {
    var obj = FAST.getObject(obj);
    
    if (obj) {
      var parent = obj.parentNode;
      parent.removeChild(obj); 
      
      return parent;
    }
  }
  
  FAST.toggleObject = function (obj, style, on, off) {
    var obj = FAST.getObject(obj);
    return obj.style[style] = obj.style[style] != off ? off : on;
  }
  
  FAST.popupObject = function(id, style, content, height, width) {
  // Toggles Popup if the object exists
    if (!(obj = FAST.getObject(id))) {
      var popup = FAST.createObject("div", document.body, "darkenScreenObject", "", "");  
      var content = FAST.createObject("div", document.body, id, style, content);

      var scrollPosition = FAST.getScrollPosition();
      var windowSize = FAST.getWindowSize();
      var height = height || content.offsetHeight;
      var width = width || content.offsetWidth;
      var top = scrollPosition[1] + ((windowSize[1] - height) / 2);
      var left = (windowSize[0] - width) / 2;
  
      // Check to make sure values are greater than zero...
      top = top > 0 ? top : 0;
      left = left > 0 ? left : 0;
      
      FAST.styleObject(content, {
        "position": "absolute",
        "height": height + "px",
        "width": width + "px",
        "left": left + "px",
        "top": top + "px"
      });
      
      var pageSize = FAST.getPageSize();
      pageSize[0] = pageSize[0] > 0 ? pageSize[0] + "px" : "100%"
      pageSize[1] = pageSize[1] > 0 ? pageSize[1] + "px" : "100%"
      
      FAST.styleObject(popup, {
        "position": "absolute",
        "zIndex": "50",
        "opacity": ".70",
        "MozOpacity": ".70",
        "filter": "alpha(opacity=70)",
        "backgroundColor": "#000",
        "height": pageSize[1],
        "width": pageSize[0],
        "overflow": "hidden",
        "top": "0px",
        "left": "0px",
        "display": "block"
      });
    } else {      
      do {
        var parent = FAST.removeObject(obj);
      } while ((obj = parent) && (parent != document.body));
      
      FAST.removeObject("darkenScreenObject");
    }
      
    return false;
  }
  
  FAST.popupWindow = function (url, name, options) {
    var url = url.href || url.action || url.src || url;
    var name = name || "popup";
    var params = "";
      
    if (options)
      for(var i in options)
        params =  params + i + "=" + options[i] + ",";
  
    var newWindow = window.open(url,name,params);
    if (window.focus) newWindow.focus()
    
    if (!newWindow.closed)
      return false;
  }

  // TODO Create AJAX calls
  FAST.Ajax = function (url, func) {
      try {
        var scripts = true; // run scripts by default
        var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
        
        xmlhttp.onreadystatechange = function() {
          if (xmlhttp.readyState == 4)
          if (xmlhttp.status==200) {
            var response = FAST.parseScript(xmlhttp.responseText);
            eval(func(response[0]));
            if (scripts)
              for(var i=0; i<response[1].length; i++)
                try {
                  eval(response[1][i]);
                } catch(ex) {
                  alert("An error has occured while trying to run the AJAX scripts.");
                }
          } else {
            // TODO program for error handling
            alert(xmlhttp.status + ": An error has occured.");
            document.location = url;
          }
        }
        xmlhttp.open("GET",url,true);
        xmlhttp.send(null);
      } catch(e) {
        alert("An error has occure while trying to process the AJAX call.");
        return true;
      }
      
      return false;
  }
  
  // TODO Cookie Stuff
  FAST.createCookie = function (name,value,days) {
    if (days) {
      var date = new Date();
      date.setTime(date.getTime()+(days*24*60*60*1000));
      var expires = "; expires="+date.toGMTString();
    } else
      var expires = "";
      
    document.cookie = name+"="+value+expires+"; path=/";
  }

  FAST.readCookie = function (name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
      var c = ca[i];
      while (c.charAt(0)==' ') c = c.substring(1,c.length);
      if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
  }

  FAST.eraseCookie = function (name) {
    createCookie(name,"",-1);
  }
  
  // TODO Form Controls -- enable/disable fields, check/uncheck all  
  FAST.selectAll = function (obj) {
    var obj = FAST.getObject(obj);
    var form = obj.form;
    
    var test = new Array();
    var collection = form.getElementsByTagName(obj.nodeName);
    for ( i=0; i<collection.length; i++ )
      if (collection[i].type == obj.type && collection[i].name == obj.name)
        collection[i].checked = obj.checked;
  }
  
  FAST.disableObject = function (obj) {
    var obj = FAST.getObject(obj);

    obj.disabled = true;
    
    return obj.disabled;
  }

  // TODO DEFAULT MESSAGES FOR "ARE YOU SURE..."

  // TODO START ERROR HANDLING FUNCTIONS
  
  // START RANDOM FUNCTIONS
  FAST.addEvent = function ( obj, type, fn ) {
    if (obj.addEventListener)
      obj.addEventListener( type, fn, false );
    else if (obj.attachEvent){
      obj["e"+type+fn] = fn;
      obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
      obj.attachEvent( "on"+type, obj[type+fn] );
    }
  }

  FAST.removeEvent = function ( obj, type, fn ){
    if (obj.removeEventListener)
      obj.removeEventListener( type, fn, false );
    else if (obj.detachEvent){
      obj.detachEvent( "on"+type, obj[type+fn] );
      obj[type+fn] = null;
      obj["e"+type+fn] = null;
    }
  }

  FAST.getWindowSize = function () {
    var myWidth = 0, myHeight = 0;
    if( typeof( window.innerWidth ) == 'number' ) {
      myWidth = window.innerWidth;
      myHeight = window.innerHeight;
    } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
      myWidth = document.documentElement.clientWidth;
      myHeight = document.documentElement.clientHeight;
    } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
      myWidth = document.body.clientWidth;
      myHeight = document.body.clientHeight;
    }
    
    return [ myWidth, myHeight ];
  }

  FAST.getScrollPosition = function () {
    var scrOfX = 0, scrOfY = 0;
    if( typeof( window.pageYOffset ) == 'number' ) {
      scrOfY = window.pageYOffset;
      scrOfX = window.pageXOffset;
    } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
      scrOfY = document.body.scrollTop;
      scrOfX = document.body.scrollLeft;
    } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
      scrOfY = document.documentElement.scrollTop;
      scrOfX = document.documentElement.scrollLeft;
    }
    return [ scrOfX, scrOfY ];
  }
  
  FAST.getPageSize = function (){
    // TODO - fix width bug in Firefox
    if (window.innerHeight && window.scrollMaxY) {// Firefox
      yWithScroll = window.innerHeight + window.scrollMaxY;
      xWithScroll = window.innerWidth + window.scrollMaxX;
    } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
      yWithScroll = document.body.scrollHeight;
      xWithScroll = document.body.scrollWidth;
    } else { // works in Explorer 6 Strict, Mozilla (not FF) and Safari
      yWithScroll = document.body.offsetHeight;
      xWithScroll = document.body.offsetWidth;
    }
    return [ xWithScroll , yWithScroll ];
  }
  
  FAST.parseScript = function (source) {
    // TODO - understand/optomize this code
    var source = source;
    var scripts = new Array();
    
    // Strip out tags
    while(source.indexOf("<script") > -1 || source.indexOf("</script") > -1) {
      var s = source.indexOf("<script");
      var s_e = source.indexOf(">", s);
      var e = source.indexOf("</script", s);
      var e_e = source.indexOf(">", e);
    
      // Add to scripts array
      scripts.push(source.substring(s_e+1, e));
      // Strip from source
      source = source.substring(0, s) + source.substring(e_e+1);
    }

    return [ source, scripts ];
  }
} else {
  alert("The framework is already loaded");
}

//
function $(id){
  return FAST.getObject(id);
}

/* TODO - method example... 
var method = {
  sampleVariable : 'variable',
  sampleMethod : function () {
    // do something
  }
}

// TODO - prototyping example
String.prototype.trim= function(){   
  return this.replace(/(^\s*)|(\s*$)/g, "");  
} */

// Proof of Concept Stuff
function framework_popin(url, height, width) {
  try {
    FAST.Ajax(url, function(response) {
      FAST.popupObject("newPopupWindow","framework_popup", response, height, width);
    });
  } catch(e) {
    return true;
  }
    
  return false;
}

function framework_popout(element) {
  FAST.popupObject("newPopupWindow");
  
  return false;
}