/**
 * STRING Object Extensions
 */
if( !String.upperCaseFirst )
String.prototype.upperCaseFirst = function() {
  t = this.toLowerCase();
  
  alphas = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  
  start = 0;
  while( alphas.indexOf(t.substr(start,1).toUpperCase()) == -1 )
    start++;
  
  fletter = t.substr(start,1).toUpperCase();
  last = t.substr(start+1, t.length-start);
  
  ret = t.substr(0, start) + fletter + last;

  return ret;
};

if( !String.upperCaseWords )
String.prototype.upperCaseWords = function() {
  ret = new String("");
  aret = new Array();
  
  a = new Array();
  re = /\s\s+/gi;
  
  //Replace Back-to-Back Spaces with a single space
  strPhrase = this.replace( re, " " );

  a = strPhrase.split(" ");
  for(index = 0; index < a.length; index++) {
    aret[index] = a[index].upperCaseFirst();
  };
  
  ret = aret.join(" ");

  return ret;
};

if( !String.trim )
String.prototype.trim = function() {
  re = /(^[\s\t\r\n]+|[\s\t\r\n]+$)+/gi;
  
  ret = this.replace( re, "" );
  
  return ret;
};

if( !Number.trim )
Number.prototype.trim = function() {
  strValue = '' + this;
  
  return parseFloat(strValue.trim());
};

if( !Array.pop )
Array.prototype.pop = function() {
  var b = this[this.length-1];
  this.length--;
  return b;
};

if( !Array.push )
Array.prototype.push = function() {
  for( var i = 0, b = this.length, a = arguments, l = a.length; i<l; i++ ) {
    this[b+i] = a[i];
  }
  
  return this.length;
};

if( !Array.empty )
Array.prototype.empty = function() {
  this.length = 0;
};


if( !window.getObject )
function getObject( obj ) {
  var type = typeof(obj);
  obj = ( type.toLowerCase() == "string" )? document.getElementById(obj) : obj;
  
  return obj;
};

/**
 * FormValidator Object
 */
 
function FormValidator() {
  this.errors = new Array();

};

FormValidator.prototype.STRING_MIN_LENGTH = 3;

FormValidator.prototype.parseErrors = function() {
  ret = this.errors.join("\n");

  return ret;
};

FormValidator.prototype.isValid = function(validatorName, value, bIsRequired) {
  try {
  
    functionName = "isValid" + this._normalizeValidator(validatorName);
  
    if( !this[functionName] ) {
      throw 'Validation Rule Parser Not Found ('+functionName+')';
    };

	isValidValue = this[functionName](value, bIsRequired);
	
	return isValidValue;
	
  } catch(e) {
    alert(e);
  };
};


FormValidator.prototype._normalizeValidator = function(validatorName) { 
  ret = validatorName.upperCaseFirst(); return ret;
};

//Validation Rules

FormValidator.prototype.isValidRequired = function(value, bIsRequired) {
  test = value.trim();
  
  bReturn = true;

  if( bIsRequired == true || bIsRequired == 'true' ) {
    if( test=='' || test.length < 1 ) {
      this.errors.push("is a required field.");
      bReturn = false;
	};
  };

  return bReturn;
};

FormValidator.prototype.isValidNumeric = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  ret = ( isNaN(value) )? false : true;
  
  if( !ret ) {
    this.errors.push("must contain only numeric values.");
	return false;
  };

  return ret;    
};

FormValidator.prototype.isValidString = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  if( value.trim().length > 0 && value.trim().length < this.STRING_MIN_LENGTH ) {
    this.errors.push("must be at least "+this.STRING_MIN_LENGTH+" characters long.");
  
    return false;
  };
  
  return true;
};

FormValidator.prototype.isValidStateprovince = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  SP_MIN_LENGTH = 2;

  if( value.trim().length > 0 && value.trim().length < SP_MIN_LENGTH ) {
    this.errors.push("must be at least "+SP_MIN_LENGTH+" characters long.");
  
    return false;
  };
  
  return true;
};

FormValidator.prototype.isValidPostalcode = function(value, bIsRequired) {

  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  POSTALCODE_MIN_LENGTH = 5;
  POSTALCODE_MAX_LENGTH = 14;
  
  re = /[\s\t\r\n\-\_]+/gi;
  test = value.replace( re, '' );

  if( test.length > 0 && test.length < POSTALCODE_MIN_LENGTH ) {
    this.errors.push("must be at least "+POSTALCODE_MIN_LENGTH+" characters.");
    return false;
  };
  
  if( test.length > POSTALCODE_MAX_LENGTH ) {
    this.errors.push("cannot exceed "+POSTALCODE_MAX_LENGTH+" characters.");
    return false;
  };
  
  return true;
};

FormValidator.prototype.isValidCountry = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  COUNTRY_MIN_LENGTH = 2;

  if( value.trim().length > 0 && value.trim().length < COUNTRY_MIN_LENGTH ) {
    this.errors.push("must be at least "+COUNTRY_MIN_LENGTH+" characters long.");
  
    return false;
  };
  
  return true;
};

FormValidator.prototype.isValidPhone = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  PHONE_MIN_LENGTH = 10;
  PHONE_MAX_LENGTH = 20;

  re = /\D+/gi;
  test = value.replace( re, "");
  
  if( bIsRequired == true && test.trim().length == 0 ) {
    this.errors.push("contains no Numbers");
	return false;
  };
  
  if( test.length > 0 && test.trim().length < PHONE_MIN_LENGTH ) {
    this.errors.push("must contain at least "+PHONE_MIN_LENGTH+" digits.");
	return false;
  };
  
  if( test.trim().length > PHONE_MAX_LENGTH ) {
    this.errors.push("cannot exceed "+PHONE_MIN_LENGTH+" digits.");
	return false;
  };
  
  return true;  
};

FormValidator.prototype.isValidEmail = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  re = /^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)+$/gi;
  results = value.match( re );

  if( !results && value.length > 0 ) {
    this.errors.push("is formatted invalidly.  please re-enter.");
	return false;
  };

  return true;
};

//Datatype Validation Rules

FormValidator.prototype.isValidInteger = function(value, bIsRequired) {
  INT_MAX = 65535;

  if( !this.isValidNumeric(value, bIsRequired) ) {    
	return false;
  };
  
  tempInt = (value < 0)? value * (-1) : value;
  testInt = INT_MAX - Math.ceil(tempInt);
  
  if( testInt < 0 ) {
    this.errors.push("invalid integer value (passed as 'Double').");
	return false;
  };
  
  return true;
};

FormValidator.prototype.isValidLong = function(value, bIsRequired) {
  if( !this.isValidRequired(value, bIsRequired) )
    return false;

  LNG_MAX = 16777215;
  
  if( !this.isValidNumeric(value, bIsRequired) ) {    
	return false;
  };
  
  tempLng = (value < 0)? value * (-1) : value;
  testLng = LNG_MAX - Math.ceil(tempLng);
  
  if( testLng < 0 ) {
    this.errors.push("invalid integer value (passed as 'Double').");
	return false;
  };
  
  return true;
};

FormValidator.prototype.isValidFloat = function(value, bIsRequired) {
  FLT_MAX = 4294967295;
  
  if( !this.isValidNumeric(value, bIsRequired) ) {    
	return false;
  };
  
  tempFlt = (value < 0)? value * (-1) : value;
  testFlt = FLT_MAX - Math.ceil(tempFlt);
  
  if( testFlt < 0 ) {
    this.errors.push("invalid float value (passed as 'Double').");
	return false;
  };
  
  return true;
};

FormValidator.prototype.isValidDouble = function(value, bIsRequired) {
  DBL_MAX = 18446744073709551615;

  if( !this.isValidNumeric(value, bIsRequired) ) {    
	return false;
  };
  
  tempDbl = (value < 0)? value * (-1) : value;
  testDbl = DBL_MAX - Math.ceil(tempDbl);
  
  if( testDbl < 0 ) {
    this.errors.push("invalid double value (passed as 'Double').");
	return false;
  };
  
  return true;
};

FormValidator.prototype.isValidCurrency = function(value, bIsRequired) {
  if( !this.isValidNumeric( Math.ceil(value) , bIsRequired) ) {    
	return false;
  };
  
  re = /(\.[\d]{3})$/gi;

  str = '' + value;

  if( str.match(re) ) {
    this.errors.push("has too many significant digits (decimal places).");
	return false;
  };
  
  return true;
};

FormValidator.prototype.isValidCreditcard = function(value, bIsRequired) {
  CC_MIN_LENGTH = CC_MAX_LENGTH = 16;

  if( !this.isValidNumeric( value , bIsRequired) ) {    
	return false;
  };
  
  temp = ""+value;
  
  if( temp.length < CC_MIN_LENGTH ) {
    this.errors.push("less than "+CC_MIN_LENGTH+" digits.");
	return false;
  };
  
  if( temp.length > CC_MAX_LENGTH ) {
    this.errors.push("cannot exceed "+CC_MAX_LENGTH+" digits.");
	return false;
  };

  checkCC = new Function('s', 'var i, n, c, r, t; r = ""; for (i = 0; i < s.length; i++) {c = parseInt(s.charAt(i), 10); if (c >= 0 && c <= 9) r = c + r;}; if (r.length <= 1) return false; t = ""; for (i = 0; i < r.length; i++) { c = parseInt(r.charAt(i), 10); if (i % 2 != 0) c *= 2; t = t + c; }; n = 0; for (i = 0; i < t.length; i++) {c = parseInt(t.charAt(i), 10); n = n + c; }; if (n != 0 && n % 10 == 0) return true; else return false;');
  test = checkCC(value);
  
  if( !test ) {
    this.errors.push("is Invalid (Bad Checksum).  Please Re-Enter.");
	return false;
  };
  
  return true;
};
/**
 * Courtesy of http://www.codingforums.com/showthread.php?t=10531
 */

/**
 * The constructor should be called with
 * the parent object (optional, defaults to window).
 */

function Timer(){
    this.obj = (arguments.length)?arguments[0]:window;
    return this;
};

/** 
 * The set functions should be called with:
 * - The name of the object method (as a string) (required)
 * - The millisecond delay (required)
 * - Any number of extra arguments, which will all be
 *   passed to the method when it is evaluated.
 */

Timer.prototype.setInterval = function(func, msec){
    var i = Timer.getNew();
    var t = Timer.buildCall(this.obj, i, arguments);
    Timer.set[i].timer = window.setInterval(t,msec);
    return i;
};
Timer.prototype.setTimeout = function(func, msec){
    var i = Timer.getNew();
    Timer.buildCall(this.obj, i, arguments);
    Timer.set[i].timer = window.setTimeout("Timer.callOnce("+i+");",msec);
    return i;
};

/**
 * The clear functions should be called with
 * the return value from the equivalent set function.
 */

Timer.prototype.clearInterval = function(i){
    if(!Timer.set[i]) return;
    window.clearInterval(Timer.set[i].timer);
    Timer.set[i] = null;
};
Timer.prototype.clearTimeout = function(i){
    if(!Timer.set[i]) return;
    window.clearTimeout(Timer.set[i].timer);
    Timer.set[i] = null;
};

/**
 * Private data
 */
Timer.set = new Array();
Timer.buildCall = function(obj, i, args){
    var t = "";
    Timer.set[i] = new Array();
    if(obj != window){
        Timer.set[i].obj = obj;
        t = "Timer.set["+i+"].obj.";
    }
    t += args[0]+"(";
    if(args.length > 2){
        Timer.set[i][0] = args[2];
        t += "Timer.set["+i+"][0]";
        for(var j=1; (j+2)<args.length; j++){
            Timer.set[i][j] = args[j+2];
            t += ", Timer.set["+i+"]["+j+"]";
    }}
    t += ");";
    Timer.set[i].call = t;
    return t;
};
Timer.callOnce = function(i){
    if(!Timer.set[i]) return;
    eval(Timer.set[i].call);
    Timer.set[i] = null;
};
Timer.getNew = function(){
    var i = 0;
    while(Timer.set[i]) i++;
    return i;
};
/**********************************************************
 * BODY Element FocusMask Object
 *
 * Created by: Cornel Boudria
 *             Partner/CTO
 *             3Prime, LLC.
 *
 * Copyright Cornel Boudria, 2006, All Rights Reserved
 * Please Read the Policy Page,
 * located @ http://www.3-prime.com,
 * for Terms or Use
 **********************************************************/

/**
 * General Utility Functions
 */
/* Return VIEWPORT WIDTH */
if( !window.getViewportWidth ) {
  function getViewportWidth() {

    /* supported in Mozilla, Opera, and Safari */
     if(window.innerWidth)
         return window.innerWidth;
	
    /* supported in standards mode of IE, but not in any other mode */
     if(window.document.documentElement.clientWidth)
         return document.documentElement.clientWidth;
	
    /* supported in quirks mode, older versions of IE, and mac IE (anything else). */
    return window.document.body.clientWidth;
  };
};

/* Return VIEWPORT HEIGHT */
if( !window.getViewportHeight ) {
  function getViewportHeight() {

    /* supported in Mozilla, Opera, and Safari */
     if(window.innerHeight)
         return window.innerHeight;
	
    /* supported in standards mode of IE, but not in any other mode */
     if(window.document.documentElement.clientHeight)
         return document.documentElement.clientHeight;
	
    /* supported in quirks mode, older versions of IE, and mac IE (anything else). */
    return window.document.body.clientHeight;
  };
};

/**
 * FocusMask Constructor
 */
function FocusMask() {

  this.container = document.createElement("DIV");
  this.isAttached = false;

  this.setOpacity(this.defaultOpacity);

  this.container.style.position = "absolute";
  this.container.style.top = "0px";
  this.container.style.left = "0px";
  this.container.style.width = "100%";
  this.container.style.height = "100%";
  this.container.style.zIndex = "200";
  this.container.style.backgroundColor = "#ffffff";
  this.container.style.display = "none";
  this.container.style.visibility = "hidden";

  /**
   * Timer Control (http://www.codingforums.com/showthread.php?t=10531)
   * Allows for Establishing Succesful BODY Element Attachment
   */
  if( !Timer )
    return false;

  this.timer = new Timer(this);
  this.timer.setTimeout( "attachToBody", 1);
};

/**
 * Default OPACITY Value
 * Values Are whole Number Percentages (50 = 50%, 60=60%, etc...)
 */
FocusMask.prototype.defaultOpacity = 50; /* 50% */

/**
 * Afixes the Mask Container to the BODY Element.
 */
FocusMask.prototype.attachToBody = function() {
  try {
    /* Get BODY Collection */
    body = document.getElementsByTagName("BODY");

    /* Check for BODY Collection */
    if( !body ) throw "setTimeout";

    /* Check for BODY Element */
    if( !body[0] ) throw "setTimeout";
    
    body = body[0];

    /* Check for BODY Element's insertBefore Method */
    if( !body.insertBefore ) throw "setTimeout";


    /* Get Very First BODY Element ChildNode */
    first = body.childNodes[0];

    /* Insert FocusMask's HTML Element Container Before First Element */
    body.insertBefore( this.container, first );

    /* Change isAttached to true to Highlight Successful Attachment */
    this.isAttached = true;

  } catch(e) {
    if( e == "setTimeout" ) this.timer.setTimeout( "attachToBody", 1);
  }
};

/**
 * Sets the Dimensional Level of the Mask (zIndex)
 */
FocusMask.prototype.setLevel = function( intNewLevel ) {
  if( isNaN(intNewLevel) )
    return false;

  this.container.style.zIndex = intNewLevel;

  return true;
};

/**
 * Sets the Mask Color
 */
FocusMask.prototype.setMaskColor = function( color ) {
  this.container.style.backgroundColor = color;
};

/**
 * Sets the Mask Color
 */
FocusMask.prototype.setOpacity = function( intOpacity ) {
  try {
    /* Check if intOpacity is a Number.  Return FALSE if NOT */
    if( isNaN(intOpacity) ) throw "VOID";

    /* Check the Value of intOpacity to be sure it is a value between 1 and 100 */
    var localOpacity = ( intOpacity >= 1 && intOpacity <= 100 )? intOpacity : this.defaultOpacity;
    var ieOpacity = localOpacity;
    var commonOpacity = localOpacity / 100;

    /* IE/Win */
    this.container.style.filter = "alpha(opacity:" + ieOpacity + ")";
  
    /* Safari<1.2, Konqueror */
    this.container.style.KHTMLOpacity = commonOpacity;
  
    /* Older Mozilla and Firefox */
    this.container.style.MozOpacity = commonOpacity;
  
    /* Safari 1.2, newer Firefox and Mozilla, CSS3 */
    this.container.style.opacity = commonOpacity;
  } catch(e) {
    return false;
  }
  finally { return true; }
};

/**
 * Sets the Height of the Mask
 */
FocusMask.prototype.setHeight = function() {
  /* Constrain the Height of the Container Object to the Window Height */
  this.container.style.height = getViewportHeight() + "px";

  var vph = getViewportHeight();  
  var osh = document.body.offsetHeight;
  var sch = document.body.scrollHeight;
  var dosh = document.documentElement.offsetHeight;
  var dsch = document.documentElement.scrollHeight;
  
  /**
   * Note: scrollHeights should use Max settings,
   *       to ensure that no content gets clipped off from the mask
   */  
  var max_sh = Math.max( sch, dsch );
  var max_oh = Math.max( osh, dosh );

  var height = max_sh;

  debug = "document.body.offsetHeight: " + osh + "\n";
  debug += "document.body.scrollHeight: " + sch + "\n";
  debug += "document.documentElement.offsetHeight: " + dosh + "\n";
  debug += "document.documentElement.scrollHeight: " + dsch + "\n";
  
  this.container.style.height = height + "px";
};

/**
 * Sets the Width of the Mask
 */
FocusMask.prototype.setWidth = function() {
  /* Constrain the Width of the Container Object to the Window Width */
  this.container.style.width = getViewportWidth() + "px";

  var vpw = getViewportWidth();
  var osw = document.body.offsetWidth;
  var scw = document.body.scrollWidth;
  var dosw = document.documentElement.offsetWidth;
  var dscw = document.documentElement.scrollWidth;
  
  /**
   * Note: scrollWidths should use Min settings,
   *       to avoid injecting a Horizontal Scroll.
   */
  var min_sw = Math.min( scw, dscw );
  var min_ow = Math.min( osw, dosw );
  
  var width = min_sw;
  
  debug = "document.body.offsetWidth: " + osw + "\n";
  debug += "document.body.scrollWidth: " + scw + "\n";
  debug += "document.documentElement.offsetWidth: " + dosw + "\n";
  debug += "document.documentElement.scrollWidth: " + dscw + "\n";

  this.container.style.width = width + "px";
};

/**
 * Acivates the Mask
 */
FocusMask.prototype.mask = function() {
  if( !this.isAttached ) return false;

  body = document.getElementsByTagName("BODY")[0];
  
  this.container.style.overflow = "hidden";

/*
  this.container.style.height = body.scrollHeight + "px";
  this.container.style.width = body.scrollWidth + "px";
*/
  this.setHeight();
  this.setWidth();
  
  this.bRezised = false;
  __this = this;
  
  window.onresize = function() {
      __this.setHeight();
      __this.setWidth();
  }

//  this.container.style.display = "inline";
  this.container.style.display = "block";
  this.container.style.visibility = "visible";

  return true;
};

/**
 * Deacivates the Mask
 */
FocusMask.prototype.unmask = function() {
  if( !this.isAttached ) return false;

  this.container.style.display = "none";
  this.container.style.visibility = "hidden";

  return true;
};

/**********************************************************
 * HttpRequest Implementation and Ajax Encapsulation Class
 *
 * Created by: Cornel Boudria
 *             Partner/CTO
 *             3Prime, LLC.
 *
 * Copyright Cornel Boudria, 2006, All Rights Reserved
 * Please Read the Policy Page,
 * located @ http://www.3-prime.com,
 * for Terms of Use
 **********************************************************/



/**
 * HTTP Status Code/Name Handling
 */
var gHttpStatusCodes = {
/* Informational */
"Continue": 100,
"Switching Protocols": 101,

/* Successful */
"Ok": 200,
"Created": 201,
"Accepted": 202,
"Non-Authoritative Information": 203,
"No Content": 204,
"Reset Content": 205,
"Partial Content": 206,

/* Redirection */
"Multiple Choices": 300,
"Moved Permanently": 301,
"Found": 302,
"See Other": 303,
"Not Modified": 304,
"Use Proxy": 305,
"Temporary Redirect": 307,

/* Client Errors */
"Bad Request": 400,
"Unauthorized": 401,
"Payment Required": 402,
"Forbidden": 403,
"Not Found": 404,
"Method Not Allowed": 405,
"Not Acceptable": 406,
"Proxy Authentication Required": 407,
"Request Timeout": 408,
"Conflict": 409,
"Gone": 410,
"Length Required": 411,
"Precondition Failed": 412,
"Request Entity Too Large": 413,
"Request-URI Too Long": 414,
"Unsupported Media Type": 415,
"Requested Range Not Satisfiable": 416,
"Expectation Failed": 417,

/* Server Errors */
"Internal Server Error": 500,
"Not implemented": 501,
"Bad Gateway": 502,
"Service Unavailable": 503,
"Gateway Timeout": 504,
"HTTP Version Not Supported": 505
};


function getHttpStatusCode( strStatus ) {
  try {
    for( status in gHttpStatusCodes ) {
      code = gHttpStatusCodes[status];
      if( status.toLowerCase() == strStatus.toLowerCase() )
	    return code;
    }
	
	return getHttpStatus(-1);

  } catch(e) {
    alert( "[getHttpStatusCode]\n\n" + e.message );
  }
}

function getHttpStatus( intStatusCode ) {
  try {
    for( status in gHttpStatusCodes ) {
      code = gHttpStatusCodes[status];
      if( code == intStatusCode )
        return status;
    }
  
    return "Http Status Code Not Found";  
  } catch(e) {
    alert( "[getHttpStatus]\n\n" + e.message );
  }
}


/**
 * XmlHttpRequest State Code/Name Handling
 */
var gXmlHttpStateCodes = {
"Uninitialized": 0,
"Loading": 1,
"Loaded": 2,
"Interactive": 3,
"Complete": 4
};

function getXmlHttpStateCode( strStateName ) {
  try {
    for( stateName in gXmlHttpStateCodes ) {
      code = gXmlHttpStateCodes[stateName];
      if( stateName.toLowerCase() == strStateName.toLowerCase() )
	    return code;
    }
	
	return getHttpStatus(-1);

  } catch(e) {
    alert( "[getXmlHttpStateCode]\n\n" + e.message );
  }
}

function getXmlHttpState( intStateCode ) {
  try {
    for( stateName in gXmlHttpStateCodes ) {
      code = gXmlHttpStateCodes[stateName];
      if( code == intStateCode )
        return stateName;
    }
  
    return "XmlHttpRequest State Code not Found";  
  } catch(e) {
    alert( "[getXmlHttpState]\n\n" + e.message );
  }
}
/**
 * The Following is Generally Bad b/c
 * of Object Method Pollution but for 
 * the purposes of proper scoping, it 
 * shall be used.
 */
if ( !Function.prototype.bind ) {
  Function.prototype.bind = function( object ) {
    var __method = this;
    return function() {
      __method.apply( object, arguments );
    };
  };
}

/***********************************/
/* HTTPREQUEST IMPLEMENTATIONS */
/***********************************/

/**
 * Virtual Method for HttpRequest Object Implementations
 */
function createHttpRequest() { /* VIRTUAL */ }


/**
 * IE Implementation
 */
function createHttpRequest_IE() {
  try {
    xmlhttp = false; /* Initialize */
    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
	catch (E) { xmlhttp = false; }
  } finally {
    return xmlhttp;
  }
}

/**
 * Mozilla/Netscape Implementation
 */
function createHttpRequest_Moz() {
  try { xmlhttp = false; /* Initialize */ xmlhttp = new XMLHttpRequest(); }
  catch (e) { xmlhttp=false; }
  finally { return xmlhttp; }
}

/**
 * window.createRequest Implementation
 */
function createHttpRequest_Req() {
  try { xmlhttp = false; /* Initialize */ xmlhttp = window.createRequest(); }
  catch (e) { xmlhttp=false; }
  finally {
    return xmlhttp;
  }
}

/**
 * Unavailable Implementation
 */
function createHttpRequest_Void() {
  try { xmlhttp = false; /* Initialize */ throw "VOID"; }
  catch(e) { xmlhttp = false; }
  finally { return xmlhttp; }
}

/**
 * Assign Implementation Method
 */
/* Test for VIRTUAL Implementation Function */
if( window.createHttpRequest ) {  
  /* Test Netscape/Mozilla */
  if( window.XMLHttpRequest ) {
    window.createHttpRequest = createHttpRequest_Moz;
  }
  /* Test IE */
  else if ( window.ActiveXObject ) {
    window.createHttpRequest = createHttpRequest_IE;
  }
  /* Test Other GECKO createRequest Capability */
  else if ( window.createRequest ) {
    window.createHttpRequest = createHttpRequest_Req;
  }
  /* No Compatible Implementations Available, Assign VOID */
  else
    window.createHttpRequest = createHttpRequest_Void;  

  /* Assign WINDOW Implementation to DOCUMENT Object */
  document.createHttpRequest = createHttpRequest;
};
/***********************************/
/* END HTTPREQUEST IMPLEMENTATIONS */
/***********************************/


/**
 * Ajax Wrapper Class
 */
/**
 * Constructor
 */
function IAjax() {
try {
    /**
     * Create HttpRequest Instance
     */

    /* Check if Implementation has been assigned to the document */
    /* "Void" the Instantiation if NOT */
    if( !document.createHttpRequest ) throw "VOID";

    /* Create an Instance of an HttpRequest */
    this.requestObject = document.createHttpRequest();

    /* Check if Implementation is Valid */
    /* Throw Error if NOT */
    if( !this.requestObject ) throw "document.createHttpRequest NOT implemented in this Browser";

  } catch(e) {
    this.error = e.message;
    return false;
  }
  finally {

  }

};

/**
 * Request Authentication Properties
 */
IAjax.prototype.authenticateRequest = false;


/**
 * Method Encapsulations
 */

/**
 * Method: Open
 */
IAjax.prototype.open = function( strMethod, strUrl ) {
  try {

    /* Rewrite to Avoid Caching Issues */
    var strOriginalUrl = strUrl;
    strUrl = this.rewriteUrl(strUrl);

    /* Get (Optional) Parameters */
    bAsynchronous = arguments[2]; /* 3rd Parameter */
    username = arguments[3];      /* 4th Parameter */
    password = arguments[4];      /* 5th Parameter */

    /* Check to Make Sure bAsynchronous is Explicilty BOOLEAN */
    if( bAsynchronous !== true && bAsynchronous !== false )
      throw "Invalid Data Type for Variable 'bAsynchronous'";    

    /* Check if Implementation has been assigned to the document */
    /* "Void" the Instantiation if NOT */
    if( !document.createHttpRequest || !this.requestObject ) throw "VOID";

    this.requestObject.onreadystatechange = this.onReadyStateChange.bind(this);

    /* Check to see if Request Must be Authenticated */
    if( this.authenticateRequest )
      this.requestObject.open( strMethod.toUpperCase(), strUrl, bAsynchronous, username, password );
    else
      this.requestObject.open( strMethod.toUpperCase(), strUrl, bAsynchronous);

  } catch(e) {
    return false;
  }
  finally {

  }
}

/**
 * Method: setRequestHeader
 */
IAjax.prototype.setRequestHeader = function( strName, strValue ) {
  this.requestObject.setRequestHeader( strName, strValue );
}

/**
 * Method: send
 */
IAjax.prototype.send = function() {

  data = ( arguments.length == 1 )? arguments[0] : null;
  this.requestObject.send(data);

}

/**
 * Method: abort
 */
IAjax.prototype.abort = function() {
  this.requestObject.abort();
}

/**
 * Method: getResponseHeader
 */
IAjax.prototype.getResponseHeader = function( strName ) {
  if( !this.requestObject.getResponseHeader ) return false;

  return this.requestObject.getResponseHeader(strName);
}

/**
 * Method: getAllResponseHeaders
 */
IAjax.prototype.getAllResponseHeaders = function() {
  if( !this.requestObject.getAllResponseHeaders ) return false;

  return this.requestObject.getAllResponseHeaders();
}

/**
 * Xml Http ReadyState CallBack Assignment Method
 */
IAjax.prototype.assignCallback = function( fnc, stateEvent ) {
  this[stateEvent] = fnc.bind(this.requestObject); /* Passes HttpRequest Instance to Callback */
}

/**
 * IAjax Event: ReadyStateChange
 */
IAjax.prototype.onReadyStateChange = function() {
  try {
    switch( this.requestObject.readyState ) {
      case getXmlHttpStateCode("uninitialized"): this.onUnitialized(); break;
      case getXmlHttpStateCode("loading"): this.onLoading(); break;
      case getXmlHttpStateCode("loaded"): this.onLoaded(); break;
      case getXmlHttpStateCode("interactive"): this.onInteractive(); break;
      case getXmlHttpStateCode("complete"):
        switch( this.requestObject.status ) {
          case 200: this.onComplete(); break;
          default: this.onResponseUnsuccessful(); break;
        };

      break;
      default: break;
    };
  } catch(e) {

  }
  finally {

  }
}

/**
 * IAjax Event: Uninitialized
 */
IAjax.prototype.onUnitialized = function() { /* VIRTUAL */ }

/**
 * IAjax Event: Interactive
 */
IAjax.prototype.onInteractive = function() { /* VIRTUAL */ }

/**
 * IAjax Event: Loading
 */
IAjax.prototype.onLoading = function() { /* VIRTUAL */ }

/**
 * IAjax Event: Loaded
 */
IAjax.prototype.onLoaded = function() { /* VIRTUAL */ }

/**
 * IAjax Event: Complete
 */
IAjax.prototype.onComplete = function() { /* VIRTUAL */ }

/**
 * IAjax Event: Non-Successful Response Code
 */
IAjax.prototype.onResponseUnsuccessful = function() { /* VIRTUAL */ }

/**
 * IAjax Utility Methods
 */
IAjax.prototype.rewriteUrl = function( oURL ) {
  /**
   * Great Url Rewriter Hack to Prevent Caching of Url Resource
   * by Mark Wilton-Jones, http://www.howtocreate.co.uk/tutorials/jsexamples/importingXML.html
   */   
   
  oURL += ( ( oURL.indexOf('?') + 1 ) ? '&' : '?' ) + ( new Date() ).getTime();

  return oURL;
}

if( gwinPleaseWait == null || !gwinPleaseWait )
  var gwinPleaseWait = null;

function bindPleaseWait() {
  gwinPleaseWait = document.getElementById('winPleaseWait');

  if( gwinPleaseWait ) {
    gwinPleaseWait.style.zIndex = "150";
    clearInterval( pleaseWaitBinder );
  }
}


var pleaseWaitBinder = setInterval( "bindPleaseWait()", 1 );

function closePleaseWait() {
  gwinPleaseWait.style.visibility = "hidden";
  gwinPleaseWait.style.block = "none";
}

function openPleaseWait() {
  bindPleaseWait();
  gwinPleaseWait.style.display = "block";
  setPleaseWaitPosition();
  gwinPleaseWait.style.visibility = "visible";
}

function setPleaseWaitPosition() {
  setPleaseWaitTop();
  setPleaseWaitLeft();
}

function setPleaseWaitTop() {
  if( window.getViewportHeight && window.topScrolled ) {
    y = Math.round(( getViewportHeight() - gwinPleaseWait.offsetHeight ) / 2) + topScrolled() + "px";
  }
  else
    y= '';
  gwinPleaseWait.style.top = y;
}

function setPleaseWaitLeft() {
  if( window.getViewportWidth && window.widthScrolled )
    x = Math.round(( window.getViewportWidth() - gwinPleaseWait.offsetWidth ) / 2) + widthScrolled() + "px";
  else
    x= '';
  gwinPleaseWait.style.left = x;
}
