/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 <;
 <;	Databasik Javabasik Javascript Framework 1.0
 <;	Core Function File
 <;	this is the Primary function library and js subsystem
 <;
 <;
 <;	Auth: Russ Stratfull
 <;	WebSite: http://databasik.com
 <;
 <;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
*/

// Open by defining the browser environment and doing some default behavior that should be universal.

MSIE = navigator.userAgent.indexOf('MSIE')>=0?true:false;
Opera = navigator.userAgent.indexOf('Opera')>=0?true:false;
navigatorVersion = navigator.appVersion.replace(/.*?MSIE (\d\.\d).*/g,'$1')/1;


// Absolute Home path details
nohashurlhomeI = location.href.indexOf('#');
if (nohashurlhomeI != -1) {
   nohashurlhome = location.href.substring(0, nohashurlhomeI);
}
else {
   nohashurlhome = location.href.replace('#', '');
}
nohashurlhome = nohashurlhome.replace(/\?.*$/, '');
// Define the actual url without #anchors
// **need to eventually add logic to remove ?'s and just plane other oddness like ::, etc...
urlhome = nohashurlhome.replace(self.location.search, '');

function databasik_jxurl() {
var dpath = location.pathname.replace(/\?.*$/, '');
var fpath = location.protocol + "//" + location.host + dpath;
return fpath;
}
// * * *
//   Begin Subsystem Function and Class Library
// * * *

/*
	$(): Replaces getElementById(), getElementsByClassName() (this one's not a native function to the dom),
		 and getElementsByTagName
		 Thank you: http://www.thewatchmakerproject.com/journal/292/a-better-dollar-function-getelementsbyanything
	Usage: $("divID", "tag <p>, <div> etc...", "className")
Summary:
var inputs = document.getElementsByTagName('input');
var selects = document.getElementsByTagName('select');
var ta = document.getElementsByTagName('textarea');
var elements = inputs.concat(selects.concat(ta));

How much easier would it be to do it like this:

var elements = $('input','select','textarea');
*/
function $() {
	var elements = [];
	for (var i=0,len=arguments.length;i<len;i++) {
		var element = arguments[i];
		if (typeof element == 'string') {
			var matched = document.getElementById(element);
			if (matched) {
				elements.push(matched);
			} else {
				var allels = (document.all) ? document.all : document.getElementsByTagName('*');
				var regexp = new RegExp('(^| )'+element+'( |$)');
				for (var i=0,len=allels.length;i<len;i++) { if (regexp.test(allels[i].className)) { elements.push(allels[i]); } }
			}
			if (!elements.length) { elements = document.getElementsByTagName(element); }
			if (!elements.length) {
				elements = [];
				var allels = (document.all) ? document.all : document.getElementsByTagName('*');
				for (var i=0,len=allels.length;i<len;i++) { if (allels[i].getAttribute(element)) { elements.push(allels[i]); } }
			}
			if (!elements.length) {
				var allels = (document.all) ? document.all : document.getElementsByTagName('*');
				for (var i=0,len=allels.length;i<len;i++) {
					if (allels[i].attributes) {
						for (var j=0,lenn=allels[i].attributes.length;j<lenn;j++) {
							if (allels[i].attributes[j].specified) {
								if (allels[i].attributes[j].nodeValue == element) { elements.push(allels[i]); }
							}
						}
					}
				}
			}
		} else {
			elements.push(element);
		}
	}
	if (elements.length == 1) {
		return elements[0];
	} else {
		return elements;
	}
}

// dv0.149 - javabasik home
javabasik_home_dir = $('Databasik_jspath').getAttribute('src').replace(/\?.*$/, '');
var databasik_covr = 'off'; //make sure there is a value for databasik_covr - works with function below
/*
	MagicBox(): Magic div which appends to the body object and overlays the current displaying page
	Usage:	    MagicBox('Message to display in div', 'Message <h1> title text...etc', 'typeofmessage (alert, notice, mbox, etc)');
	Note:	    This is a flashy, reusable method to send prompts and messages and content into a div which is appended
		    to the dom in the center of the page.
	Optional Globals:
			MagicOpacity

*/
MagicOpacity = "95";
function MagicBox(msg, title, type, func) {
   clearMagic();
   // shorten the document obj to make the code smaller + run faster =)
   d = document;

   // register the covr div
   databasik_covr = 'on';

   // Hide selects which poke through the cover div ;(
   if (document.all) {
      var selectObjs = document.getElementsByTagName('select');
      for (var i=0; i<selectObjs.length; ++i) {
         if (!selectObjs[i].md_nohide) { selectObjs[i].md_vis = selectObjs[i].style.visibility; selectObjs[i].style.visibility = 'hidden'; }
      }
   }

   // if the pagecover object already exists in the DOM, don't proceed.
   // In the future this will involve queuing. <---- important!
   if (d.getElementById("MagicCover")) { return; }

   // Make sure the basic required attributes exist, if no type is specified, then
   if (!msg) { return; }
   if (!type) { type = 'mbox'; }

   // construct the "Covr"
   covr = d.getElementsByTagName("body")[0].appendChild(d.createElement("div"));

   // These attributes are part of the .style... dom object for the covr div
   covr.id = "MagicCover";//id
   covr.style.position = "absolute";//absolute position
   covr.style.width = "100%";//100% width
   covr.style.left = '0px';//left 0px
   covr.style.top = '0px';//top 0px
   covr.style.zIndex = '10000';//give it a big z-index
   covr.style.textAlign = 'center';//position everything in it to the center =)

   // make sure its as tall as it needs to be to overlay all the content on the page
   covr.style.height = Math.round(document.documentElement.scrollHeight + 200) + "px";

   // create MagicBox Div
   mdoc = d.getElementsByTagName("body")[0].appendChild(d.createElement("div"));

   // assign it the id "MagicDoc"
   mdoc.id = "MagicDoc";

   // Set the MagicDoc paramters
   // Top
   mdoc.style.top = Math.round(document.documentElement.scrollHeight + 200) + "px";
   //if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) setTimeout("mdoc.style.paddingTop = Math.round(document.documentElement.scrollHeight + 500) + 'px'", 200);
   // Z-Index
   mdoc.style.zIndex = '10001';
   // width
   mdoc.style.width = '400px'; //this can be changed by our calling script, but the default is 400px
   // absolutely position it
   mdoc.style.position = 'absolute';
   // make sure the overflow is visible
   mdoc.style.overflow = 'visible';
   // default font?
   mdoc.style.fontFamily = 'verdana';
   // default font size?
   mdoc.style.fontSize = '12px';
   // dv0.150 center MagicBox content
   mdoc.style.textAlign = 'center';

   // Using some styling tricks we can directly center the div
   mdoc.style.top = Math.round(document.body.scrollTop + 200) + "px";

   // Find the left location
   mdoc.style.left = (d.documentElement.scrollWidth - mdoc.offsetWidth)/2 + "px";

   // the following fixes a bug in Google Chrome.
   //if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) setTimeout("window.scrollBy(1,0)", 600);

   // This is the displayed dialog div with background colors etc...
   // all the settings can be customized by the function
   // call param at the end of the MagicBox() function.
   mbox = mdoc.appendChild(d.createElement("div"));
   mbox.style.float = 'left';
   mbox.style.width = '100%';
   mbox.style.border = 'solid 1px #000';
   mbox.style.backgroundColor = "#fff";
   mbox.style.paddingBottom = '10px';

   // Top dialog bar (with close x)
   mbar = mbox.appendChild(d.createElement("div"));
   mbar.style.display = 'block';
   mbar.id = "magicBar";
   mbar.style.float = 'left';
   mbar.style.width = '100%';
   mbar.style.textAlign = 'right';
   mbar.style.paddingTop = '4px';
   mbar.style.marginRight = '4px';
   mbar.style.margin = '0';
   mbar.style.height = '18px';
   mbar.style.paddingBottom = '0';
   mbar.style.borderBottom = 'solid 1px #666';
   mbar.style.backgroundColor = '#d4d0c8';
   // The innerHTML was easier to just code inline
   mbar.innerHTML = '<p style="text-align: left; font-family: verdana; float: left; width: 95%; display: block; text-indent: 15px; font-weight: bold; font-size: 11px; margin: 0; padding: 0px 0px 0px 0px;">' + title + '</p><a id="clearMagicX" href="#" onclick="clearMagic(); return false;" style="width: 4%; text-align: right; padding-right: 1px;"><img src="' + Databasik_data + 'icons/close-x.gif" alt="Close" style="text-align: right; border: 0; text-decoration: none;" /></a>';

   // Extended function attribute:
   // (this is the magic right here! Be careful, because whatever you send this will be evaluated)
   // This is where you can customize the box
   if (func) {
      eval(func);
   }
   // Now let's be specific to the type of box we need
   // There are currently 3 types supported:
   // 1.)alerts 2.)confirms 3.)mbox
   if (type != 'mbox' && type != 'confirm') {
      //Create Message object
      theMsg = mbox.appendChild(d.createElement("p"));

      theMsg.id = "theMsg";

      /* Bring in the data from our target */

      theMsg.innerHTML = msg;


      theMsg.style.margin = '0';
      theMsg.style.paddingTop = '10px';
      theMsg.style.paddingBottom = '20px';
      theMsg.style.textAlign = 'left';
      theMsg.style.textIndent = '0';
      theMsg.style.width = '70%';
      theMsg.style.position = 'relative';
      theMsg.style.marginLeft = 'auto';
      theMsg.style.marginRight = 'auto';

      //Pick icon based on message type:
      mbox.style.backgroundRepeat = 'no-repeat';
      mbox.style.backgroundPosition = '15px 35px';
      if (type == 'alert') { mbox.style.backgroundImage = 'url(' + Databasik_data + 'icons/alert.gif)'; }
      else if (type == 'info') { mbox.style.backgroundImage = 'url(' + Databasik_data + 'icons/info.gif)'; }
      else if (type == 'question') { mbox.style.backgroundImage = 'url(' + Databasik_data + 'icons/question.gif)'; }
      else if (type == 'warning') { mbox.style.backgroundImage = 'url(' + Databasik_data + 'icons/alert.gif)'; }
      else if (type == 'error') { mbox.style.backgroundImage = 'url(' + Databasik_data + 'icons/error.gif)'; }
      else if (type == 'complete') { mbox.style.backgroundImage = 'url(' + Databasik_data + 'icons/complete.png)'; }

      // create an anchor element to use as the confirmation button.
      btn = mbox.appendChild(d.createElement("a"));
      btn.appendChild(d.createTextNode('Continue'));
      btn.style.borderTop = 'solid 1px #999';
      btn.style.borderBottom = 'solid 2px #000';
      btn.style.borderLeft = 'solid 1px #999';
      btn.style.borderRight = 'solid 2px #999';
      btn.href = '#';
      btn.id = 'MagicOk';
      btn.onclick = function() { return false; };
      btn.style.paddingTop = '2px';
      btn.style.paddingBottom = '2px';
      btn.style.paddingLeft = '5px';
      btn.style.paddingRight = '5px';
      btn.style.fontFamily = 'verdana';
      btn.style.fontSize = '12px';
      btn.style.textDecoration = 'none';
      btn.style.fontWeight = 'bold';
      btn.style.backgroundColor = '#d4d0c8';
      btn.onclick = function() { clearMagic(); return false; };
   }
   else if (type == 'confirm') {
	  // Create <p> element and add message
      theMsg = mbox.appendChild(d.createElement("p"));
      theMsg.innerHTML = msg;
      theMsg.style.margin = '0';
      theMsg.style.paddingTop = '10px';
      theMsg.style.paddingBottom = '20px';
      theMsg.style.textAlign = 'left';
      theMsg.style.textIndent = '0';
      theMsg.style.width = '70%';
      theMsg.style.position = 'relative';
      theMsg.style.marginLeft = 'auto';
      theMsg.style.marginRight = 'auto';
      // Multiple Buttons:
      //yes
      ybtnc = mbox.appendChild(d.createElement("span"));
      ybtnc.style.padding = '10px';

      ybtn = ybtnc.appendChild(d.createElement("a"));
      ybtn.appendChild(d.createTextNode('Yes'));
      ybtn.style.borderTop = 'solid 1px #999';
      ybtn.style.borderBottom = 'solid 2px #000';
      ybtn.style.borderLeft = 'solid 1px #999';
      ybtn.style.borderRight = 'solid 2px #999';
      ybtn.style.paddingTop = '2px';
      ybtn.style.paddingBottom = '2px';
      ybtn.style.paddingLeft = '5px';
      ybtn.style.paddingRight = '5px';
      ybtn.style.fontFamily = 'verdana';
      ybtn.style.fontSize = '12px';
      ybtn.style.textDecoration = 'none';
      ybtn.style.fontWeight = 'bold';
      ybtn.style.backgroundColor = '#d4d0c8';
      ybtn.href = '#';
      ybtn.id = 'Yes';
      ybtn.onclick = function() { return false; };
      //no
      nbtnc = mbox.appendChild(d.createElement("span"));
      nbtnc.style.padding = '10px';
      nbtn = nbtnc.appendChild(d.createElement("a"));
      nbtn.appendChild(d.createTextNode('No'));
      nbtn.style.borderTop = 'solid 1px #999';
      nbtn.style.borderBottom = 'solid 2px #000';
      nbtn.style.borderLeft = 'solid 1px #999';
      nbtn.style.borderRight = 'solid 2px #999';
      nbtn.style.paddingTop = '2px';
      nbtn.style.paddingBottom = '2px';
      nbtn.style.paddingLeft = '5px';
      nbtn.style.paddingRight = '5px';
      nbtn.style.fontFamily = 'verdana';
      nbtn.style.fontSize = '12px';
      nbtn.style.textDecoration = 'none';
      nbtn.style.fontWeight = 'bold';
      nbtn.style.backgroundColor = '#d4d0c8';
      nbtn.href = '#';
      nbtn.id = 'No';
      nbtn.onclick = function() { return false; };

      xbtnc = mbox.appendChild(d.createElement("span"));
      xbtnc.style.padding = '10px';
      xbtn = xbtnc.appendChild(d.createElement("a"));
      xbtn.appendChild(d.createTextNode('Cancel'));
      xbtn.style.borderTop = 'solid 1px #999';
      xbtn.style.borderBottom = 'solid 2px #000';
      xbtn.style.borderLeft = 'solid 1px #999';
      xbtn.style.borderRight = 'solid 2px #999';
      xbtn.style.paddingTop = '2px';
      xbtn.style.paddingBottom = '2px';
      xbtn.style.paddingLeft = '5px';
      xbtn.style.paddingRight = '5px';
      xbtn.style.fontFamily = 'verdana';
      xbtn.style.fontSize = '12px';
      xbtn.style.textDecoration = 'none';
      xbtn.style.fontWeight = 'bold';
      xbtn.style.backgroundColor = '#d4d0c8';
      xbtn.href = '#';
      xbtn.id = 'No';
      xbtn.onclick = function() { clearMagic(); return false; };
   }
   else {
      //covr.style.top = document.body.parentNode.scrollTop + "px";
      //mdoc.style.top = document.body.scrollTop + "px";
      //mdoc.style.left = (d.documentElement.scrollWidth - mdoc.offsetWidth)/2 + "px";
      //divsizetowin("MagicCover");
      //mdoc.style.top = Math.round(document.body.scrollTop + 100) + "px";

   }
   //set defaults if not provided already
   if (!covr.style.backgroundColor) { covr.style.backgroundColor = '#999'; }
   if (!mbox.style.width) { mbox.style.width = '500px'; }

   if (!MagicOpacity) { Fade(covr, true, false, 200, 95); }
   else { Fade(covr, true, false, 200, MagicOpacity); }

   window.onresize = function() {
	   if (databasik_covr == 'on') {
              divsizetowin("MagicCover");
              if (scrollMagic === true) { mdoc.style.top = document.body.scrollTop + "px"; }
              covr.style.top = document.body.parentNode.scrollTop + "px";
              mdoc.style.left = (d.documentElement.scrollWidth - mdoc.offsetWidth)/2 + "px";
              if (type != 'mbox') { mdoc.style.top = Math.round(document.body.scrollTop + 100) + "px"; }
           }
   };
   window.onscroll = function() {
	   if (databasik_covr == 'on') {
	      divsizetowin("MagicCover");
	      if (scrollMagic === true) { mdoc.style.top = document.body.scrollTop + "px"; }
	      covr.style.top = document.body.parentNode.scrollTop + "px";
          mdoc.style.left = (d.documentElement.scrollWidth - mdoc.offsetWidth)/2 + "px";
           if (type != 'mbox') { mdoc.style.top = Math.round(document.body.scrollTop + 100) + "px"; }

	   }
   };
   MagicGone = false;
   resetBox();
   if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) { setTimeout("window.scrollBy(0,1)", 200); }
   //setTimeout("window.scrollBy(0,1)", 300);
}
/*
	css(): Include css file on demand!
	Usage: css('filename')
	Created: 5-17-09
*/
function css(path) {
	//step 1 - begin building object:
	var cssfile = document.createElement("link");
	cssfile.setAttribute("rel", "stylesheet");
	cssfile.setAttribute("type", "text/css");
	cssfile.setAttribute("href", path);
 document.getElementsByTagName("head")[0].appendChild(cssfile);
}

/*
	inc(): Include javascript libraries to current environment/page load
	Usage: inc('filename', callback, delay)
	Note:  Only add the part of the file after databasik_ and leave off the .js extension (it's assumed)
*/
function inc(lib, callback, delay, id)
{

   // step 1 - capture the path to the js (scripts) library (grabbed from the Databasik_jspath attribute of the
   var home = javabasik_home_dir;

   //create object "e" and attach the creation of a new <script> tag/object
   var e = document.createElement("script");

   // Step 2 - Determine if the path is specified or not:
   if (lib.match("/") == "/") {

      if (lib.match("http:") == "http:") {
		  e.src = lib + ".js";
	  }
	  else {
		  e.src = home + lib + '.js';
	  }
   }
   else
   {
      // define the source path to this object
      e.src = home + 'javabasik_' + lib + '.js';
   }

   // define the type attribute
   e.type="text/javascript";

   // dv.0.159: id argument added
   if (id) {
	   e.id = id;
   }

   // append this new object/tag to the document tree
   var ap = document.getElementsByTagName("head")[0].appendChild(e);

   // if callback is supplied, execute it!
   // dv0.150
   if (!delay) delay = 500;
   if (callback) { ap.onload = setTimeout("eval(" + callback + ")", delay); }

   // return the appended object:
   return ap;

}
/*
	addEvent(): adds javascript events to document. Used to clean up the window.onload = function() { dfdf... } mess...
	Usage:  addEvent(window,'load',func1,false);
		addEvent(window,'load',func2,false);
		addEvent(window,'load',func3,false);
*/
function addEvent(elm, evType, fn, useCapture) {
	if (elm.addEventListener) {
		elm.addEventListener(evType, fn, useCapture);
		return true;
	}
	else if (elm.attachEvent) {
		var r = elm.attachEvent('on' + evType, fn);
		return r;
	}
	else {
		elm['on' + evType] = fn;
	}
}
/*
	xconfirm(): Confirm Dialog popup
	Usage:  xconfirm("your message",'title of popup','functionName()');
	Note:   Uses MagicBox() of type "confirm"
*/
function xconfirm(msg, title, callback) {
   if (msg) {
      if (!title) { title = 'Confirm Message'; }
      MagicBox(msg, title, 'confirm');
      if (callback) {
         ybtn.onclick = function() {
            clearMagic();
            //need to work in this.id as the value || maybe find a way to gather this info without the id attribute
            eval(callback);
            return false;
         };
         nbtn.onclick = function() {
            clearMagic();
            eval(callback);
            return false;
         };
      }
   }
}


/*
	xbutton(): creates X button for MagicBox
*/
function xbutton() {
   d = document;
   xparagraph = mbox.appendChild(d.createElement("p"));
   xparagraph.style.display = 'block';
   xparagraph.style.width = '100%';
   xparagraph.style.textAlign = 'right';
   xbt = xparagraph.appendChild(d.createElement("a"));
   xbt.href = '#';
   xbt.onclick = function() { clearMagic(); return false; };
   xbt.appendChild(d.createTextNode('Close'));
   ximg = xbt.appendChild(d.createElement("img"));
   ximg.style.paddingRight = '10px';
   ximg.src = Databasik_data + 'icons/delete.gif';
   ximg.style.border = 'none';
   xbt.style.fontFamily = 'verdana';
   xbt.style.fontSize = '10px';
   xbt.style.textDecoration = 'none';
}
MagicGone = true;

/*
	clearMagic(): Clears MagicBox popup. Used by MagicBox buttons
				  you can call it on demand from your own scripts.
*/
function clearMagic() {
    JFX_state = 'kill';
	if (MagicGone === false) {
	document.getElementsByTagName("body")[0].removeChild(document.getElementById("MagicCover"));
	document.getElementsByTagName("body")[0].removeChild(document.getElementById("MagicDoc"));
   if (document.all) {
      var selectObjs = document.getElementsByTagName('select');
	  //Put the select objects back into visible state
      for (var i=0; i<selectObjs.length; ++i) {
         if (!selectObjs[i].md_nohide) {
            selectObjs[i].md_vis = selectObjs[i].style.visibility;
            selectObjs[i].style.visibility = 'visible';
         }
      }
    }
    databasik_covr = 'off';
    MagicGone = true;
    scrollMagic = true;
}
}

/*
	resetBox(): Required function to reset the position of the MagicBox div after making a css/size change.
*/
scrollMagic = true;
function resetBox() {
   covr.style.top = document.body.parentNode.scrollTop + "px";
   if (scrollMagic === true) { mdoc.style.top = document.body.parentNode.scrollTop + "px"; }
   mdoc.style.left = (d.documentElement.scrollWidth - mdoc.offsetWidth)/2 + "px";
   //if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) setTimeout("window.scrollBy(1,0)", 600);
   if (scrollMagic === true) { mdoc.style.paddingTop = '50px'; }
}
function showelogBox(syslogfile, loglevel) {
   mdoc.style.width = '800px';
   covr.style.backgroundColor = '#333';
   resetBox();
   mbox.innerHTML += '<h2>Databasik Syslog:</h2><div id="syslogdiv"><iframe id="systemlog" src="' + syslogfile + '" style="width: 750px; height: 500px;"></iframe></div>';
   mbox.innerHTML += '<p style="padding-bottom: 50px;">This alert was generated because your <span style=\"font-weight: bold;\">$databasik_error_reporting</span> <span style=\"font-weight: bold; color: #0000ff;\">display</span> level is set to <span style=\"font-weight: bold; text-decoration: underline; color: #0000ff;\">' + loglevel + '</span></p>';
   //AddMagicButton('Close', 'clearMagic()');
}

/*
   AddMagicButton(): Adds a button to the MagicBox popup
*/
function AddMagicButton(text, callback) {
   ubtn = mbox.appendChild(d.createElement("a"));
   ubtn.appendChild(d.createTextNode(text));
   ubtn.style.borderTop = 'solid 1px #999';
   ubtn.style.borderBottom = 'solid 2px #000';
   ubtn.style.borderLeft = 'solid 1px #999';
   ubtn.style.borderRight = 'solid 2px #999';
   ubtn.href = 'clear';
   ubtn.onclick = function() { return false; };
   ubtn.style.paddingTop = '2px';
   ubtn.style.paddingBottom = '2px';
   ubtn.style.paddingLeft = '5px';
   ubtn.style.paddingRight = '5px';
   ubtn.style.fontFamily = 'verdana';
   ubtn.style.fontSize = '12px';
   ubtn.style.textDecoration = 'none';
   ubtn.style.fontWeight = 'bold';
   ubtn.style.backgroundColor = '#d4d0c8';
   ubtn.onclick = function() {
	   eval(callback);
	   return false;
	};
}

/*
	clearSysLogReq(): Sends a "clear the system log" system call to the databasik framework.
	NOTE: This only works if the display is set to the correct setting
*/
function clearSysLogReq() {

   var wordId = 'clearSysLog';
   var filename = '';
   var variable = 'databasik_ajax_req';
   var divid = 'systemlog';
   var logdisplay = document.getElementsByTagName("iframe");

   for (l=0; l<logdisplay.length; l++) {
	   if (logdisplay[l].id == 'systemlog') {
		   logdisplay[l].src = '?databasik_ajax_req=clearSysLog';
	   }
   }
}

/*
	getElementsByClass(): Extend the getElements js to include classes too!
	Usage: getElementsByClass("className", node#, tag);
*/
function getElementsByClass(searchClass,node,tag) {
	var classElements = [];
	if ( node === null ) { node = document; }
	if ( tag === null ) { tag = '*'; }
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp('(^|\\\\s)'+searchClass+'(\\\\s|$)');
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}
/*
	cleanr(): DOM function to clear html content of specified divID
	Usage: cleanr("divname");
	will turn <div id="divname"><p>paragraph text</p></div> into <div id="divname"></div>
	or <p id="DOMp">Paragraph Text</p> into <p id="DOMp"></p>
*/
function cleanr(objID) {
	cleaning = $(objID);
	for (c=0; c<cleaning.length; c++) {
		cleaning.innerHTML = "";
	}
}
/*
	insertAfter(): Extend DOM
*/
function insertAfter(parent, node, referenceNode) {
	parent.insertBefore(node, referenceNode.nextSibling);
}

/*
	extlinks(): Externalize links with rel="new" added to anchor tags
	Usage: <a href="http://link_to_open_in/new.window" rel="new">Open new window</a>
	Call this function at window.onload
*/
function extlinks() {
	if (!document.getElementsByTagName) { return; }
		var lynkz = document.getElementsByTagName("a");
		for (a=lynkz.length; a--;) {
		var lynk = lynkz[a];
		if (lynk.getAttribute("href") && lynk.getAttribute("rel") == "new") { lynk.target = "_blank"; }
	}
}
/*
   autolink(): automagically add hyperlink to input string (s)
*/
function autolink(s)
{
   var hlink = /\s(ht|f)tp:\/\/([^ \,\;\:\!\)\(\"\'\<\>\f\n\r\t\v])+/g;
   return (s.replace (hlink, function ($0,$1,$2) { s = $0.substring(1,$0.length);
                                                   // remove trailing dots, if any
                                                   while (s.length>0 && s.charAt(s.length-1)=='.')
                                                      s=s.substring(0,s.length-1);
                                                   // add hlink
                                                   return " " + s.link(s);
                                                 }
                     )
           );
}

function ext(link) {
	link.setAttribute("rel", "new");
	extlinks();
}
/* EXPERIMENTAL
	dorun(): Scans a provided object for rel="Function" tag, and then runs the commands that
		 follow it separated by commas
	Usage: add the following to your anchor tags: <a rel="Function, function1, function2, etc">link that triggers events</a>,

*/
function dorun(click) {
	if (click.getAttribute("rel") !== null) {
		if (click.getAttribute("rel").match("Function") == "Function") {
			var broken = click.getAttribute("rel").split(",");
			run(click, stripSpaces(broken[1]));
		}
	}
}
/* EXPERIMENTAL
	 run(): Runs specified command (VERY EXPERIMENTAL AND APROACH THIS WITH CAUTION)
	 Usage run([object HTMLInputElement], "function Name");
*/
function run(e, func) {
	if (typeof window[func] != 'undefined') {
		window[func](e);
	}
	else { alert('unknown function: ' + func); }
}
/*
	SetCookie("cookieName", "cookieValue", Number of Days to keep alive): Sets cookie on user's browser as long as cookies are enabled in their browser settings
	Usage: window.onload = function() { SetCookie("testcookie", "exampleAttribute", 1); }
	Call this function at window.onload or inline
*/
function SetCookie(cookieName,cookieValue,nDays,path) { //Need to add path argument!
 	var today = new Date();
 	var expire = new Date();
 	if (nDays === null || nDays === 0) { nDays = 1; }
 	expire.setTime(today.getTime() + 3600000*24*nDays);
 	if (path) {
		document.cookie = cookieName+"="+escape(cookieValue) + ";expires="+expire.toGMTString() + ";path="+path;
	}
	else {
 	   document.cookie = cookieName+"="+escape(cookieValue) + ";expires="+expire.toGMTString();
    }
}
/*
	ReadCookie(): Sets cookie on user's browser as long as cookies are enabled in their browser settings
	Usage: window.onload = function() { ReadCookie("cookieName"); }
	cookieName = the name of the cookie who's attribute you want the value of
	Call this function at window.onload or inline
*/
function ReadCookie(cookieName) {
 	var theCookie=""+document.cookie;
 	var ind=theCookie.indexOf(cookieName);
 	if (ind==-1 || cookieName=="") { return ""; }
 	var ind1=theCookie.indexOf(';',ind);
 	if (ind1==-1) { ind1=theCookie.length; }
 	return unescape(theCookie.substring(ind+cookieName.length+1,ind1));
}
/*
	deleteCookie(): Delete provided cookie name
	Usage: deleteCookie("name", "path", "domain");
*/
function deleteCookie( name, path, domain ) {
   if ( getCookie( name ) ) { document.cookie = name + '=' +
      ( ( path ) ? ';path=' + path : '') +
      ( ( domain ) ? ';domain=' + domain : '' ) +
      ';expires=Thu, 01-Jan-1970 00:00:01 GMT';
   }
}
/* EXPERIMENTAL
	divsizetowin(): Resizes provided div (by id) to the browser's full size
	Usage: divsizetowin("maxdiv");

- this will make <div id="maxdiv"> become full screen size
(good for making a screen takeover with background: #000; and transparent css ;)
*/
function divsizetowin(divid) {
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  }
  else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  }
  else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
  var fxdiv = $(divid);
  fxdiv.style.width = myWidth;
  fxdiv.style.height = myHeight;
}

/*
	makeGetRequest(): make ajax Get Request
	Usage: makeGetRequest(wordId, filename, variable, divid)
		Above will open a connection to the server with these attributes:
		get: filename?variable=wordId
*/
function makeGetRequest(url, parameters, callback) {
    //make a connection to the server ... specifying that you intend to make a GET request
    //to the server. Specifiy the page name and the URL parameters to send
    //This is where it needs some personalizing
    http.open('get', url + '?' + parameters);

    //assign a handler for the response
    ajax_gback = callback;
    http.onreadystatechange = processGetResponse;

    //actually send the request to the server
    http.send(null);
}
function processGetResponse() {
    //check if the response has been received from the server
    if(http.readyState == 4){
       //read and assign the response from the server
       var response = http.responseText;
	   // if there is a callback specified, execute it
       if (ajax_gback) { eval(ajax_gback); }
    }
}

/*
	makePOSTRequest(): make ajax POST request
*/
http_request = false;


function makePOSTRequest(url, parameters, callback) {

      http_request = false;
      if (window.XMLHttpRequest) { // Mozilla, Safari,...
         http_request = new XMLHttpRequest();
         if (http_request.overrideMimeType) {
         	// set type accordingly to anticipated content type
            //http_request.overrideMimeType('text/xml');
            http_request.overrideMimeType('text/html');
         }
      }
      else if (window.ActiveXObject) { // IE
         try {
            http_request = new ActiveXObject("Msxml2.XMLHTTP");
         } catch (e) {
            try {
               http_request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {}
         }
      }
      if (!http_request) {
         alert('Cannot create XMLHTTP instance');
         return false;
      }
      ajax_post_callback = callback;
      http_request.onreadystatechange = processPost;
      http_request.open('POST', url, true);
      http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      http_request.setRequestHeader("Content-length", parameters.length);
      http_request.setRequestHeader("Connection", "close");
      http_request.send(parameters);
   }
/*
	processPost():

	EXAMPLE:
	      	var poststr = "mytextarea1=" + encodeURI( document.getElementById("mytextarea1").value ) +
	        "&mytextarea2=" + encodeURI( document.getElementById("mytextarea2").value );
            makePOSTRequest('post.php', poststr);
*/
function processPost() {
      if (http_request.readyState == 4) {
         if (http_request.status == 200) {
            result = http_request.responseText;

		    if (ajax_post_callback) {
	           eval(ajax_post_callback);
			}

         } else {
            alert('There was a problem with the request: HTTP.REQUEST.STATUS' + http_request.status);
         }
      }
   }
/*
	createRequestObject(): Ajax creat request function
			       (create XMLThhpRequest object based on supported browser functionality)
	Usage: var http = createRequestObject(); //PART OF THIS JS FILE!
*/
function createRequestObject() {
    var tmpXmlHttpObject;
    //depending on what the browser supports, use the right way to create the XMLHttpRequest object
    if (window.XMLHttpRequest) {
        // Mozilla, Safari uses this method ...
        tmpXmlHttpObject = new XMLHttpRequest();
    }
    else if (window.ActiveXObject) {
        // IE uses this method ...
        tmpXmlHttpObject = new ActiveXObject("Microsoft.XMLHTTP");
    }
    return tmpXmlHttpObject;
}

//call the above function to create the XMLHttpRequest object
var http = createRequestObject();

/*
	BACKBUTTON-DISABLE This script pushes you back forward if you try to get to it with the back button ;)

	//To run this script:
	//window.onload = backButtonOverride();

	// Needs to be more flexible otherwise it just traps the visiter
*/
function backButtonOverride()
{
  // Work around a Safari bug
  // that sometimes produces a blank page
  setTimeout("backButtonOverrideBody()", 1);

}
/*
   backButtonOverrideBody():
*/
function backButtonOverrideBody()
{
  // Works if we backed up to get here
  try {
    history.forward();
  }
  catch (e) {
    // OK to ignore
  }

  // Every quarter-second, try again. The only
  // guaranteed method for Opera, Firefox,
  // and Safari, which don't always call
  // onLoad but *do* resume any timers when
  // returning to a page
  setTimeout("backButtonOverrideBody()", 500);
}
/*
	Fade(): This fade library was designed by Erik Arvidsson for WebFX
			For more info and examples see: http://webfx.eae.net
			or contact Erik at http://webfx.eae.net/contact.html#erik
*/
var __fadeArray = [];
function Fade(el, fadeIn, steps, msec, opacity, onfinish)
{
    if (steps == null) { steps = 4; }
    if (msec == null) { msec    = 25; }
    if (opacity == null) { opacity = 100; }
    if (onfinish == null) { onfinish = ''; }

    if (el.fadeIndex == null) {
        el.fadeIndex = __fadeArray.length;
    }

    __fadeArray[el.fadeIndex] = el;

    if (el.style.visibility == "hidden") {
        el.style.display  = 'block';
        el.fadeStepNumber = 0;
    }
    else {
        el.fadeStepNumber = steps;
    }

    if (fadeIn) {
        el.style.filter = "Alpha(Opacity=0)";
        el.style.MozOpacity = '0';
    }
    else {
        el.style.filter = "Alpha(Opacity=" + opacity + ")";
        el.style.MozOpacity = opacity / 100;
    }
    window.setTimeout("RepeatFade(" + fadeIn + "," + el.fadeIndex + "," + steps + "," + msec + ", " + opacity + ", '" + onfinish + "')", msec);
}

/*
     RepeatFade():

*/
function RepeatFade(fadeIn, index, steps, msec, opacity, onfinish) {
   el = __fadeArray[index];

   c = el.fadeStepNumber;
   if (el.fadeTimer !== null) {
      window.clearTimeout(el.fadeTimer);
   }

   if (c === 0 && !fadeIn) {            // Done fading out!
      el.style.visibility = "hidden"; // If the platform doesn't support filter it will hide anyway
      el.style.display    = "none"; // If the platform doesn't support filter it will hide anyway

      if (onfinish) {
         eval(onfinish + "()");
      }
   return;

   }
   else if (c == steps && fadeIn) {    // Done fading in!
      el.style.filter = "Alpha(Opacity=" + opacity + ")";
      el.style.MozOpacity = opacity / 100;
      el.style.visibility = "visible";

   /*if (onfinish && onfinish !== "undefined") {
      eval(onfinish + "()");
   }*/
   return;

   }
   else {
      fadeIn ? c++ : c--;
      el.style.visibility = "visible";
      el.style.filter = "Alpha(Opacity=" + opacity*c/steps + ")";
      el.style.MozOpacity = (opacity / 100) * c/steps;

      el.fadeStepNumber = c;
      el.fadeTimer = window.setTimeout("RepeatFade(" + fadeIn + "," + index + "," + steps + "," + msec + ", " + opacity + ", '" + onfinish + "' )", msec);
   }
}



addEvent(window,'load',extlinks,false); //open links in new window with rel="new"


/**************************************************
 * dom-drag.js
 * 09.25.2001
 * www.youngpup.net
 * Script featured on Dynamic Drive (http://www.dynamicdrive.com) 12.08.2005
 **************************************************
 * 10.28.2001 - fixed minor bug where events
 * sometimes fired off the handle, not the root.
 **************************************************

Example #1 (basic)
<img id="example" src="lips.gif" style="position: relative" />

<script type="text/javascript">
Drag.init(document.getElementById("example"));
</script>

Example #2 (with handle)
<div id="root" style="left:50px; top:50px;">
<div id="handle">Handle</div>
Some text
</div>

<script type="text/javascript">
var theHandle = document.getElementById("handle");
var theRoot = document.getElementById("root");
Drag.init(theHandle, theRoot);
</script>

#Example #3 (provided events)
.onDragStart(x,y)
.onDragEnd(x,y)
.onDrag(x,y)
	Example:
------------------------------------
<div id="objkt"></div>
var objekt = $("objkt");
Drag.init(objekt);
objekt.onDrag = function(x, y) {// x, y contains current offset coords of drag
   //code goes here
}
------------------------------------
*/

var Drag = {

	obj : null,

	init : function(o, oRoot, minX, maxX, minY, maxY, bSwapHorzRef, bSwapVertRef, fXMapper, fYMapper)
	{
		o.onmousedown	= Drag.start;

		o.hmode			= bSwapHorzRef ? false : true ;
		o.vmode			= bSwapVertRef ? false : true ;

		o.root = oRoot && oRoot !== null ? oRoot : o ;

		if (o.hmode  && isNaN(parseInt(o.root.style.left  ))) { o.root.style.left   = "0px"; }
		if (o.vmode  && isNaN(parseInt(o.root.style.top   ))) { o.root.style.top    = "0px"; }
		if (!o.hmode && isNaN(parseInt(o.root.style.right ))) { o.root.style.right  = "0px"; }
		if (!o.vmode && isNaN(parseInt(o.root.style.bottom))) { o.root.style.bottom = "0px"; }

		o.minX	= typeof minX != 'undefined' ? minX : null;
		o.minY	= typeof minY != 'undefined' ? minY : null;
		o.maxX	= typeof maxX != 'undefined' ? maxX : null;
		o.maxY	= typeof maxY != 'undefined' ? maxY : null;

		o.xMapper = fXMapper ? fXMapper : null;
		o.yMapper = fYMapper ? fYMapper : null;

		o.root.onDragStart	= new Function();
		o.root.onDragEnd	= new Function();
		o.root.onDrag		= new Function();
	},

	start : function(e)
	{
		var o = Drag.obj = this;
		e = Drag.fixE(e);
		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
		o.root.onDragStart(x, y);

		o.lastMouseX	= e.clientX;
		o.lastMouseY	= e.clientY;

		if (o.hmode) {
			if (o.minX !== null)	{ o.minMouseX	= e.clientX - x + o.minX; }
			if (o.maxX !== null)	{ o.maxMouseX	= o.minMouseX + o.maxX - o.minX; }
		}
		else {
			if (o.minX !== null) { o.maxMouseX = -o.minX + e.clientX + x; }
			if (o.maxX !== null) { o.minMouseX = -o.maxX + e.clientX + x; }
		}
		if (o.vmode) {
			if (o.minY !== null)	{ o.minMouseY	= e.clientY - y + o.minY; }
			if (o.maxY !== null)	{ o.maxMouseY	= o.minMouseY + o.maxY - o.minY; }
		} else {
			if (o.minY !== null) { o.maxMouseY = -o.minY + e.clientY + y; }
			if (o.maxY !== null) { o.minMouseY = -o.maxY + e.clientY + y; }
		}

		document.onmousemove = Drag.drag;
		document.onmouseup = Drag.end;

		return false;
	},

	drag : function(e)
	{
		e = Drag.fixE(e);
		var o = Drag.obj;

		var ey	= e.clientY;
		var ex	= e.clientX;
		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
		var nx, ny;

		if (o.minX !== null) ex = o.hmode ? Math.max(ex, o.minMouseX) : Math.min(ex, o.maxMouseX);
		if (o.maxX !== null) ex = o.hmode ? Math.min(ex, o.maxMouseX) : Math.max(ex, o.minMouseX);
		if (o.minY !== null) ey = o.vmode ? Math.max(ey, o.minMouseY) : Math.min(ey, o.maxMouseY);
		if (o.maxY !== null) ey = o.vmode ? Math.min(ey, o.maxMouseY) : Math.max(ey, o.minMouseY);

		nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));
		ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));

		if (o.xMapper) { nx = o.xMapper(y) }
		else if (o.yMapper)	ny = o.yMapper(x)

		Drag.obj.root.style[o.hmode ? "left" : "right"] = nx + "px";
		Drag.obj.root.style[o.vmode ? "top" : "bottom"] = ny + "px";
		Drag.obj.lastMouseX	= ex;
		Drag.obj.lastMouseY	= ey;

		Drag.obj.root.onDrag(nx, ny);
		return false;
	},

	end : function()
	{
		document.onmousemove = null;
		document.onmouseup   = null;
		Drag.obj.root.onDragEnd(	parseInt(Drag.obj.root.style[Drag.obj.hmode ? "left" : "right"]),
									parseInt(Drag.obj.root.style[Drag.obj.vmode ? "top" : "bottom"]));
		Drag.obj = null;
	},

	fixE : function(e)
	{
		if (typeof e == 'undefined') { e = window.event; }
		if (typeof e.layerX == 'undefined') { e.layerX = e.offsetX; }
		if (typeof e.layerY == 'undefined') { e.layerY = e.offsetY; }
		return e;
	}
};

/**
*
*  MD5 (Message-Digest Algorithm)
*  http://www.webtoolkit.info/
*
**/

var mcrypt = function (string) {

	function RotateLeft(lValue, iShiftBits) {
		return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
	}

	function AddUnsigned(lX,lY) {
		var lX4,lY4,lX8,lY8,lResult;
		lX8 = (lX & 0x80000000);
		lY8 = (lY & 0x80000000);
		lX4 = (lX & 0x40000000);
		lY4 = (lY & 0x40000000);
		lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
		if (lX4 & lY4) {
			return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
		}
		if (lX4 | lY4) {
			if (lResult & 0x40000000) {
				return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
			} else {
				return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
			}
		} else {
			return (lResult ^ lX8 ^ lY8);
		}
 	}

 	function F(x,y,z) { return (x & y) | ((~x) & z); }
 	function G(x,y,z) { return (x & z) | (y & (~z)); }
 	function H(x,y,z) { return (x ^ y ^ z); }
	function I(x,y,z) { return (y ^ (x | (~z))); }

	function FF(a,b,c,d,x,s,ac) {
		a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
		return AddUnsigned(RotateLeft(a, s), b);
	};

	function GG(a,b,c,d,x,s,ac) {
		a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
		return AddUnsigned(RotateLeft(a, s), b);
	};

	function HH(a,b,c,d,x,s,ac) {
		a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
		return AddUnsigned(RotateLeft(a, s), b);
	};

	function II(a,b,c,d,x,s,ac) {
		a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
		return AddUnsigned(RotateLeft(a, s), b);
	};

	function ConvertToWordArray(string) {
		var lWordCount;
		var lMessageLength = string.length;
		var lNumberOfWords_temp1=lMessageLength + 8;
		var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
		var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
		var lWordArray=Array(lNumberOfWords-1);
		var lBytePosition = 0;
		var lByteCount = 0;
		while ( lByteCount < lMessageLength ) {
			lWordCount = (lByteCount-(lByteCount % 4))/4;
			lBytePosition = (lByteCount % 4)*8;
			lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
			lByteCount++;
		}
		lWordCount = (lByteCount-(lByteCount % 4))/4;
		lBytePosition = (lByteCount % 4)*8;
		lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
		lWordArray[lNumberOfWords-2] = lMessageLength<<3;
		lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
		return lWordArray;
	};

	function WordToHex(lValue) {
		var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
		for (lCount = 0;lCount<=3;lCount++) {
			lByte = (lValue>>>(lCount*8)) & 255;
			WordToHexValue_temp = "0" + lByte.toString(16);
			WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
		}
		return WordToHexValue;
	};

	function Utf8Encode(string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	};

	var x=Array();
	var k,AA,BB,CC,DD,a,b,c,d;
	var S11=7, S12=12, S13=17, S14=22;
	var S21=5, S22=9 , S23=14, S24=20;
	var S31=4, S32=11, S33=16, S34=23;
	var S41=6, S42=10, S43=15, S44=21;

	string = Utf8Encode(string);

	x = ConvertToWordArray(string);

	a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;

	for (k=0;k<x.length;k+=16) {
		AA=a; BB=b; CC=c; DD=d;
		a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
		d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
		c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
		b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
		a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
		d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
		c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
		b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
		a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
		d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
		c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
		b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
		a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
		d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
		c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
		b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
		a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
		d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
		c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
		b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
		a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
		d=GG(d,a,b,c,x[k+10],S22,0x2441453);
		c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
		b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
		a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
		d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
		c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
		b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
		a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
		d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
		c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
		b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
		a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
		d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
		c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
		b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
		a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
		d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
		c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
		b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
		a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
		d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
		c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
		b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
		a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
		d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
		c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
		b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
		a=II(a,b,c,d,x[k+0], S41,0xF4292244);
		d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
		c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
		b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
		a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
		d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
		c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
		b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
		a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
		d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
		c=II(c,d,a,b,x[k+6], S43,0xA3014314);
		b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
		a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
		d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
		c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
		b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
		a=AddUnsigned(a,AA);
		b=AddUnsigned(b,BB);
		c=AddUnsigned(c,CC);
		d=AddUnsigned(d,DD);
	}

	var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);

	return temp.toLowerCase();
}

/*
   pause(): like sleep() in unix, php, etc...
   Example: pause(1000);
*/
function pause(numberMillis)
{
var now = new Date();
var exitTime = now.getTime() + numberMillis;
while (true)
{
now = new Date();
if (now.getTime() > exitTime)
return;
}
}

/******************

   New Chategory: RegExp object!


   RegExp().escape: Escape pesky characters that need to be escaped in regex.
   Example: Reg
*/
RegExp.escape = function(str) {

   var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); // .*+?|()[]{}\
   return str.replace(specials, "\\$&");
}

/***
*   Second Generation Ajax functions
*
*   http://www.hunlock.com/blogs/The_Ultimate_Ajax_Object
*   Notes: This looks like it might require some tweaking.
*   	   For instance, the initial design adds a timestamp including ?timestamp=
*	       This should check to see IF there is a timestamp or not.
*
*	var myRequest = new ajaxObject('http://www.somedomain.com/process.php', processData);
*
*	function processData(responseText, responseStatus) {
*	  if (responseStatus==200) {
*	    alert(responseText);
*	  } else {
*	    alert(responseStatus + ' -- Error Processing Request);
*	  }
*	}

*	----------- OR -----------------
*
*   myRequest = new ajaxObject('http://somedomain.com/ad.html');
*	myRequest.callback = function(responseText) {
*	  document.getElementById('someAdDiv').innerHTML=responseText;
*	}
*	myRequest.update();
*
**/
/*
   ajaxObject(): Create ajax object
*/
function ajaxObject(url, callbackFunction) {
  var that = this;
  this.updating = false;
  this.path;
  /*
   * abort(): abort current executing request.
   */
  this.abort = function() {
    if (that.updating) {
      that.updating=false;
      that.AJAX.abort();
      that.AJAX=null;
    }
  }
  /*
     update(): updates this object with data and a post method
  */
  this.update = function(passData,postMethod) {
    if (that.updating) { return false; }
    that.AJAX = null;
    if (window.XMLHttpRequest) {
      that.AJAX=new XMLHttpRequest();
    } else {
      that.AJAX=new ActiveXObject("Microsoft.XMLHTTP");
    }
    if (that.AJAX==null) {
      return false;
    } else {
      that.AJAX.onreadystatechange = function() {
        if (that.AJAX.readyState==4) {
          that.updating=false;
          that.callback(that.AJAX.responseText,that.AJAX.status,that.AJAX.responseXML);
          that.AJAX=null;
        }
      }
      that.updating = new Date();
      if (/post/i.test(postMethod)) {
        var uri=urlCall+'?'+that.updating.getTime();
        that.AJAX.open("POST", uri, true);
        that.AJAX.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        that.AJAX.setRequestHeader("Content-Length", passData.length);
        that.AJAX.send(passData);
      } else {
        //var uri=urlCall+'?'+passData+'&timestamp='+(that.updating.getTime());
        var uri=urlCall;
        that.AJAX.open("GET", uri, true);
        that.AJAX.send(null);
      }
      return true;
    }
  }
  var urlCall = url;
  this.callback = callbackFunction || function () { };
}




/*
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 <;
 <;	Databasik Javascript Framework 1.0
 <;	xhtml fx Magic Library
 <;	This is a library of functions and utilities which add magic fx to Databasik rendered xhtml.
 <;
 <;
 <;	Auth: Russ Stratfull
 <;	WebSite: http://databasik.com
 <;
 <;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
*/

// REGISTERED GLOBALS
JFX_state = false;
/*

	fade(): Fade animation
	Usage:
		<div id="fadeBlock" style="background-color:Lime;width:250px;
      				height:65px;text-align:center;">
  				<br />
  				I'm Some Text
		</div>
		<br />
		<br />
		<input type="button" onclick="fade('fadeBlock');" value="Go" />

		//WEBSITE 	-	http://www.switchonthecode.com/tutorials/javascript-tutorial-simple-fade-animation

*/

TimeToFade = 1000.0;

function fade(eid, reverse)
{

  var element = $(eid);


	/* dv0.151: direction (optional) added. */
	if (reverse) {
		element.style.opacity = '0';
		element.FadeState = "-2";

	}


  if(element == null) {
    return;
   }
  if(element.FadeState == null)
  {
    if(element.style.opacity == null || element.style.opacity == '' || element.style.opacity == '1') {
       element.FadeState = 2;
    }
    else {
       element.FadeState = -2;
    }
  }

  if(element.FadeState == 1 || element.FadeState == -1) {
     element.FadeState = element.FadeState == 1 ? -1 : 1;
     element.FadeTimeLeft = TimeToFade - element.FadeTimeLeft;
  }
  else {
     element.FadeState = element.FadeState == 2 ? -1 : 1;
     element.FadeTimeLeft = TimeToFade;
     setTimeout("animateFade(" + new Date().getTime() + ",'" + eid + "')", 33);
  }
}

function animateFade(lastTick, eid)
{
  var curTick = new Date().getTime();
  var elapsedTicks = curTick - lastTick;

  var element = document.getElementById(eid);

  if(element.FadeTimeLeft <= elapsedTicks)
  {
    element.style.opacity = element.FadeState == 1 ? '1' : '0';
    element.style.filter = 'alpha(opacity = ' + (element.FadeState == 1 ? '100' : '0') + ')';
    element.FadeState = element.FadeState == 1 ? 2 : -2;
    return;
  }

  element.FadeTimeLeft -= elapsedTicks;
  var newOpVal = element.FadeTimeLeft/TimeToFade;
  if(element.FadeState == 1)
    newOpVal = 1 - newOpVal;

  element.style.opacity = newOpVal;
  element.style.filter = 'alpha(opacity = ' + (newOpVal*100) + ')';

  setTimeout("animateFade(" + curTick + ",'" + eid + "')", 33);
}

/*
	Blink(): id'd object blinks in and out of "visibility"
	example: blink('examplediv');
*/
function Blink(eid, Blinkrate, iterations) {
   //catch object
   var element = $(eid);

   // Evaluate of element object has style attribute
   // if not, cancel. This stops error message
   if (element.style == null) {
      return false;
   }

   //check for rate, otherwise set default value
   // This might not be right. I've noticed sometimes
   // variables MUST be initialized
   if (!Blinkrate) var Blinkrate = 500;
   else var Blinkrate = Blinkrate;
   //check for iterations, otherwise set default value
   if (!iterations) var iterations = 10;
   if (!element || element == null) return;
   //first iteration:
   if (element.iteration == null) {
      //init first of (var):iterations iterations
      element.iteration = 1;
   }
   else if (element.iteration <= iterations) {
      element.iteration = element.iteration + 1;

   }
   else {
      element.style.visibility = "visible";
      element.iteration = null;
      return;
   }
   if (element.style.visibility == "visible") { element.style.visibility = "hidden"; }
   else { element.style.visibility = "visible"; }
   setTimeout("Blink('" + eid + "', " + Blinkrate + ", " + iterations + ")", Blinkrate);
}
/*
	highlight(): Div (object highlighter function
	Notes: This function takes the requested object and makes it's backgroundColor attribute change.
		   You can define the color, rate, and times it blinks.

	Example: Highlight('examplediv', '#000000';
	Bugs/Issues: This currently might only accept 6 digit hex
	Plans: Adapt this to accept words, and rgb even maybe???
*/
function Highlight(eid, Blinkrate, HightlightColor, iterations, defaultbackground) {

   //catch object
   var element = $(eid);

   if (element.style == null) {
      return false;
   }

   //check for rate, otherwise set default value
   if (!Blinkrate) var Blinkrate = 500;
   else var Blinkrate = Blinkrate;

   //check for rate, otherwise set default value
   if (!HightlightColor) var HightlightColor = '#ffff88';
   else var HightlightColor = HightlightColor;

   //check for iterations, otherwise set default value
   if (!iterations) var iterations = 6;
   if (!element || element == null) return;

   //Trickery to deal with default background logic
   if (!defaultbackground) var defaultbg = rgbConvert(element.style.backgroundColor);
   else var defaultbg = defaultbackground;

   //check if the default is null
   if (!defaultbg) {
	   defaultbg = 'none';
   }

   //first iteration:
   if (element.iteration == null) {

      //init first of (var):iterations iterations
      element.iteration = 1;

      //Do the first color flash:
      element.style.backgroundColor = HightlightColor;
   }

   //Body of the iterations
   else if (element.iteration < iterations) {

	  //increment current iteration number
      element.iteration = element.iteration + 1;

      //switching color logic
      if (rgbConvert(element.style.backgroundColor) == HightlightColor) {

		  if (defaultbg == 'none') element.style.backgroundColor = '';
		  else element.style.backgroundColor = defaultbg;
	  }
      else {
		  element.style.backgroundColor = HightlightColor;
	  }

   }
   else {

	  //last iteration (resolve values back to default state)
      element.iteration = null;
      return; //kill thread
   }

   //flash between the default color and the highlight one
   if (rgbConvert(element.style.backgroundColor) == HightlightColor) {

   //set the display longer on this round
   setTimeout("Highlight('" + eid + "', " + Blinkrate + ", '" + HightlightColor + "', '" + iterations + "', '" + defaultbg + "')", Blinkrate);
   }
   //or give it half the highlight time
   else {
	   setTimeout("Highlight('" + eid + "', " + Blinkrate + ", '" + HightlightColor + "', '" + iterations + "', '" + defaultbg + "')", Blinkrate/2);
   }
}
/*
   rgbConvert(): Converts string to rgb color type
   Notes: This was needed to bridge a rendering mismatch between browsers.
   	      (Mozilla renders css color attributes in rgb color... Even if you supply it! Not cool.)
   	      Example: var rgbcolor = rgbConvert('rgb(255,255,255)');
   	      		   This would return #ffffff
*/
function rgbConvert(str) {
   if (str.match("rgb") == "rgb") {
      str = str.replace(/rgb\(|\)/g, "").split(",");
      str[0] = parseInt(str[0], 10).toString(16).toLowerCase();
      str[1] = parseInt(str[1], 10).toString(16).toLowerCase();
      str[2] = parseInt(str[2], 10).toString(16).toLowerCase();
      str[0] = (str[0].length == 1) ? '0' + str[0] : str[0];
      str[1] = (str[1].length == 1) ? '0' + str[1] : str[1];
      str[2] = (str[2].length == 1) ? '0' + str[2] : str[2];
      //alert('#' + str.join(""));
      return ('#' + str.join(""));
  }
  else return str;
}

/*
	collapseExpand(): Collapses or Expands the requested div
	Options: sliderHeight, slideSpeed
*/
sliderIntervalId = 0;
sliderHeight = 0;
sliding = false;
slideSpeed = 10;

function collapseExpand(eid, tosize, speed) { //speed not complete yet

   //check to see if we are currently processing a request
   if(sliding) return;

   //otherwise, start the processing
   sliding = true;

   //set the overflow to hide everything in our element when it's collapsed
   $(eid).style.overflow = 'hidden';

   //if the object is not 0px tall = collapse it
   if(parseInt($(eid).style.height) > 0) {

	   //Make sure "tosize" has a value:
	   if (!tosize) tosize = $(eid).style.height + 20;
      sliderHeight = tosize;
      sliderIntervalId = setInterval('collapseUp("' + eid + '")', slideSpeed);
   }
   //otherwise, expand the object by the amount requested
   else {
      sliderIntervalId = setInterval('expandDown("' + eid + '", ' + tosize + ')', slideSpeed);
  }
}
/*
   collapseUp(): Collapse up the div. Works with collapseExpand
*/
function collapseUp(eid, tosize)
{
   slider = $(eid);

   if (!tosize) tosize = 0;

   if(sliderHeight <= tosize)
   {
      sliding = false;
      sliderHeight = tosize;
      slider.style.height = tosize + 'px';
      clearInterval(sliderIntervalId);
   }
   else
   {
      sliderHeight -= slideSpeed;
      if(sliderHeight < tosize)
         sliderHeight = tosize;
      slider.style.height = sliderHeight + 'px';
   }
}

/*
   expandDown(): Expand div down. Works with collapseExpand
*/
function expandDown(eid, tosize)
{
   slider = $(eid);
   if(sliderHeight >= tosize)
   {
      sliding = false;
      sliderHeight = tosize;
      slider.style.height = tosize + 'px';
      clearInterval(sliderIntervalId);
   }
   else
   {
      sliderHeight += slideSpeed;
      if(sliderHeight > tosize)
         sliderHeight = tosize;
      slider.style.height = sliderHeight + 'px';
   }
}
/*
	SlideShut(): Slide div shut.
*/
//Options:
shutIntervalId = 0;
shutWidth = 0;
shutting = false;
shutSpeed = 10;

function SlideShut(eid, tosize, speed) { //speed not complete yet

   //check to see if we are currently processing a request
   if(shutting) return;

   //otherwise, start the processing
   shutting = true;

   //set the overflow to hide everything in our element when it's collapsed
   $(eid).style.overflow = 'hidden';

   //if the object is not 0px wide = collapse it
   if(parseInt($(eid).style.width) > 0) {
      shutWidth = tosize;
      shutIntervalId = setInterval('slideIn("' + eid + '")', 30);
   }
   //otherwise, expand the object by the amount requested
   else {
      shutIntervalId = setInterval('slide("' + eid + '", ' + tosize + ')', 30);
  }
}

/*
   slideIn(): Slide div in
*/
function slideIn(eid, tosize)
{
   shut = $(eid);

   if (!tosize) tosize = 0;

   if(shutWidth <= 0)
   {
      shutting = false;
      shutWidth = 0;
      shut.style.width = tosize + 'px';
      clearInterval(shutIntervalId);
   }
   else
   {
      shutWidth -= shutSpeed;
      if(shutWidth < 0)
         shutWidth = 0;
      shut.style.width = shutWidth + 'px';
   }
}

/*
   slide(): Slide div to destination size.
*/
function slide(eid, tosize)
{
   shut = $(eid);
   if(shutWidth >= tosize)
   {
      shutting = false;
      shutWidth = tosize;
      shut.style.width = tosize + 'px';
      clearInterval(shutIntervalId);
   }
   else
   {
      shutWidth += shutSpeed;
      if(shutWidth > tosize)
         shutWidth = tosize;
      shut.style.width = shutWidth + 'px';
   }
}

/*
   growto(): Grow div to a specific width and height.
*/
function growto(eid, width, height) {

	//catch object
	var grow = $(eid);
	$(eid).style.overflow = 'hidden';

	//catch current widht/height
	var growWidth = parseInt(grow.style.width);
	var growHeight = parseInt(grow.style.height);

	//if they aren't defined by height/width use scroll:
	if (!growWidth) { var growWidth = parseInt(grow.offsetWidth); }
	if (!growHeight) { var growHeight = parseInt(grow.offsetHeight); }

	//begin with width:
	if (growWidth < width) {

		shutIntervalId = setInterval('slide("' + eid + '", ' + width + ')', 30);
	}

	//then adjust height:
	if (growHeight < height) {
		sliderIntervalId = setInterval('expandDown("' + eid + '", ' + height + ')', 30);
	}
}

/*
   shrinkto(): Shrink div to specific width and height.
*/
function shrinkto(eid, width, height) {

	//catch object
	var shrink = $(eid);
	$(eid).style.overflow = 'hidden';

	//catch current widht/height
	var shrinkWidth = parseInt(shrink.style.width);
	var shrinkHeight = parseInt(shrink.style.height);

	//if they aren't defined by height/width use scroll:
	if (!shrinkWidth) { var shrinkWidth = parseInt(shrink.offsetWidth); }
	if (!shrinkHeight) { var shrinkHeight = parseInt(shrink.offsetHeight); }

	//begin with width:
	if (shrinkWidth > width) {
        shutWidth = width;
		shutIntervalId = setInterval('slideIn("' + eid + '", ' + width + ')', 30);
	}

	//then adjust height:
	if (shrinkHeight > height) {
		slideHeight = height;
		sliderIntervalId = setInterval('collapseUp("' + eid + '", ' + height + ')', 30);
	}
}

//TO BE CONTINUED:
//http://www.switchonthecode.com/tutorials/javascript-and-css-tutorial-how-to-make-sliding-panels

/*
	Animate(): Method to animate div positioning and size

function Animate(divobj, newLeft, newTop, newWidth, newHeight, time, callback) {

	//catch object
	var e = $(divobj);

	//make sure we found it
	if (!e || e == null) return;

	//build model of object's current state:
	var curLeft = parseInt(e.style.left);
	var curTop = parseInt(e.style.top);
	var curWidth = parseInt(e.style.width);
	var curHeight = parseInt(e.style.height);

	//If our values are NULL, then use offset to catch the static locations/values and add them to bakUp variables
	if (!curLeft) { curLeft = parseInt(e.offsetLeft); }
	if (!curTop) { curTop = parseInt(e.offsetTop); }
	if (!curWidth) { curWidth = parseInt(e.offsetWidth); }
	if (!curHeight) { curHeight = parseInt(e.offsetHeight); }

	if (!newLeft) newLeft = curLeft;
	if (!newTop) newTop = curTop;
	if (!newWidth) newWidth = curWidth;
	if (!newHeight) newHeight = curHeight;
	//figure out the number of frames to animate by
	var Frames = 1;
	if (time > 0) Frames = time/40;

    //Math to calculate frame changes
    var fLeft = newLeft - curLeft;
    if(fLeft != 0) { fLeft /= Frames; }

    var fTop = newTop - curTop;
    if(fTop != 0) { fTop /= Frames; }

     var fWidth = newWidth - curWidth;
     if(fWidth != 0) { fWidth /= Frames; }

     var fHeight = newHeight - curHeight;
     if(fHeight != 0) { fHeight /= Frames; }

     //alert(fTop);


   doFrame(divobj, curLeft, curTop, curWidth, curHeight,
      newLeft, newTop, newWidth, newHeight,
      fLeft, fTop, fWidth, fHeight, callback);


}


	//doFrame(): run frame logic

function doFrame(eid, cLeft, cTop, cWidth, cHeight,
                 newLeft, newTop, newWidth, newHeight,
                 fLeft, fTop, fWidth, fHeight, callback) {

   //catch object:
   var e = $(eid);

   //Animate one frame:
   cLeft = aFrame(cLeft, newLeft, fLeft);
   cTop = aFrame(cTop, newTop, fTop);
   cWidth = aFrame(cWidth, newWidth, fWidth);
   cHeight = aFrame(cHeight, newHeight, fHeight);

   e.style.left = Math.round(cLeft) + 'px';
   e.style.top = Math.round(cTop) + 'px';
   e.style.width = Math.round(cWidth) + 'px';
   e.style.height = Math.round(cHeight) + 'px';

   if(cLeft == newLeft && cTop == newTop && cHeight == newHeight
    && cWidth == newWidth)
   {
    if(callback != null)
      eval(callback);
    return;
   }

   setTimeout( 'doFrame("' + eid + '",'+cLeft+','+newLeft+','+fLeft+','+cTop+','
      +newTop+','+fTop+','+cWidth+','+newWidth+','+fWidth+','+cHeight+','
      +newHeight+','+fHeight+','+callback+')', 40);

}


	//aFrame(): Move one frame

function aFrame(curVal, endVal, frameAmt) {
   if (frameAmt == 0 ||curVal == endVal) return endVal;

   curVal += frameAmt;
   if ((frameAmt > 0 && curVal >= endVal) || (frameAmt < 0 && curVal <= endVal)) {
	   return endVal;
   }
   return curVal;
}
*/


/*
	tooltiptool(): tooltip listener default browser tooltip over ride function
	Usage: Any object with class="tooltip" will be affected.
		   Can also be directly applied against with tooltip.show() and in turn tooltip.hide() to hide it


*/
ToolTiptitleInMemory = "";
ToolTipClass = "";
//if (!ToolTipClass) ToolTipClass = 'data/tooltip/tooltip.css';

function tooltiptool() {

	//load the required css attributes for this to work correctly:
	var dbjspath = javabasik_home_dir;
	css(dbjspath + 'data/dat/tooltip.class.css');

	//parse page tags into a variable:
	var tools = $('a', 'img');

	//go through each collected object
	//for (t=0; t<tools.length; t++) { // removed for inneficiency
	for (var t=tools.length; t--;) {

		//if the object has the "class" listener of "tooltip" then...
		if (tools[t].className.match('tooltip') == 'tooltip' && tools[t].title) {

		   var toolrelate = tools[t].className.match(/tooltip-[a-zA-Z0-9]*/);

		   //convert to string:
		   toolrelate = String(toolrelate);

		   //remove the listener from the attribute to get the relationship:
		   toolrelate = toolrelate.replace("tooltip-", "");

		   //var csspath = dbjspath + 'data/tooltip/' + tooltemplate + '.css';
		   //css(csspath);

		   //over-ride default tooltip and replace with the enhanced one
		   tools[t].onmouseover = function() {

			   //create variable with the value (text to display) gathered from the title="" attribute
			   var ttext = this.title;

			   //display tooltip:
			   tooltip.show(ttext);

			   //EXPERIMENT: assign it an attribute...
			   //this.var = ttext;
			   ToolTiptitleInMemory = this.title;

			   this.title = '';

		   }

		   //when return to normal state when mouseout occurs
		   tools[t].onmouseout = function() {
			   tooltip.hide();
			   //alert(this.var);
			   this.title = ToolTiptitleInMemory;
		   }
		}
	}
}
/*
	tooltip class:
	Usage ( from it's origin at http://www.leigeber.com/2008/06/javascript-tooltip/ )

	...href="#" onmouseover="tooltip.show('Testing 123 <strong>Testing 123</strong>');"
	   More to study: http://www.quirksmode.org/js/events_properties.html
*/
var tooltip = function(){

   //configurations (these need to be externalized... Someday... :( )
   var id = 'tt';
   var top = 3;
   var left = 3;
   var maxw = 300;
   var speed = 10;
   var timer = 20;
   var endalpha = 100;
   var alpha = 0;
   var tt,t,c,b,h;
   var ie = document.all ? true : false;
   return{
   //NOTES:
   // Need to add option to place above or below the mouse location.
      show:function(v,w){
         if(tt == null){

            tt = document.createElement('div');
            tt.setAttribute('id',id);
            t = document.createElement('div');
            t.setAttribute('id',id + 'top');
            c = document.createElement('div');
            c.setAttribute('id',id + 'cont');
            b = document.createElement('div');
            b.setAttribute('id',id + 'bot');
            tt.appendChild(t);
            tt.appendChild(c);
            tt.appendChild(b);
            document.body.appendChild(tt);
            tt.style.opacity = 0;
            //parseInt(e.offsetLeft);
            tt.style.filter = 'alpha(opacity=0)';

            //this adjusts the position when the mouse moves?
            document.onmousemove = this.pos;
         }
            tt.style.display = 'block';
            c.innerHTML = v;
            tt.style.width = w ? w + 'px' : 'auto';
            if(!w && ie){
               t.style.display = 'none';
               b.style.display = 'none';
               tt.style.width = tt.offsetWidth;
               t.style.display = 'block';
               b.style.display = 'block';
            }
            if(tt.offsetWidth > maxw){tt.style.width = maxw + 'px'}
            h = parseInt(tt.offsetHeight) + top;
            clearInterval(tt.timer);
            tt.timer = setInterval(function(){tooltip.fade(1)},timer);
         },

         //This is where we apply the pos function to "this"
         //It functions such that when you move your mouse, it redraws the location of our div ;)
	 pos:function(e){

		    //bugfix that eliminates user's ability to define the width attribute (it breaks the display)
			if ($('tt').style.width) $('tt').style.width = 'auto';
			if ($('ttcont').style.width) $('ttcont').style.width = 'auto';

            //var u = ie ? event.clientY + document.documentElement.scrollTop + tt.scrollTop : e.pageY;
            var u = ie ? event.clientY + document.documentElement.scrollTop : e.pageY;

            var l = ie ? event.clientX + document.documentElement.scrollLeft : e.pageX;

            //change directional property issue (keep it in the screen)
            //begin by defining the browser window's width and height
            var BrowserWidth = document.documentElement.clientWidth;
            var BrowserHeight = document.documentElement.clientHeight;

            //Then, if it's within the maximum width as defined in your environment maxw distance from the right side of the screen
            if (l > BrowserWidth - maxw) {
               //too close to the right
               //Change it to 80%
               tt.style.left = (l + left-maxw) + 'px';

            }
            else {
               //normal tooltip
               tt.style.left = (l + left + 20) + 'px';
            }
	    /*
	    	Logic to determine position of the top goes here.
	    */
            if (ie) {
               tt.style.top = ( event.clientY + document.body.scrollTop + 10) + 'px';
            }
            else tt.style.top = (u - h + 20) + 'px';
         },
         fade:function(d){
            var a = alpha;
            if ((a != endalpha && d == 1) || (a != 0 && d == -1)) {
               var i = speed;
               if (endalpha - a < speed && d == 1) {
                  i = endalpha - a;
               }
               else if (alpha < speed && d == -1) {
//stopped here
					i = a;
				}
				alpha = a + (i * d);
				tt.style.opacity = alpha * .01;
				tt.style.filter = 'alpha(opacity=' + alpha + ')';
			}else{
				clearInterval(tt.timer);
				if(d == -1){tt.style.display = 'none'}
			}
		},
		hide:function(){
			clearInterval(tt.timer);
			tt.timer = setInterval(function(){tooltip.fade(-1)},timer);
		}
	};
}();
/*
	Add the above event to your js environment/load
*/
addEvent(window, 'load', tooltiptool, false);


