var oVox = {

		DUMMY_LINK	: "javascript:void(false);",
		
		oBroadcast 	: {}, // broadcaster
		aResizers 	: [], // resize statements
		aLoaders 	: [], // onload statements
		
		// initialization
		mPush		: function () { arguments [ 0 ][ arguments [ 0 ].length ] = arguments [ 1 ]},
		mOnload 	: function () { var i = 0; while ( i < arguments.length ) oVox.mPush ( oVox.aLoaders,  arguments [ i++ ])},
		mOnresize 	: function () { var i = 0; while ( i < arguments.length ) oVox.mPush ( oVox.aResizers, arguments [ i++ ])},
		mExecute 	: function () { var i = 0; while ( i < arguments [ 0 ].length ) arguments[ 0 ][ i++ ](); },
		mResize 	: function () { oVox.mExecute ( oVox.aResizers ); },
		mLoad 		: function () { oVox.mExecute ( oVox.aLoaders ); oVox.mBroadcast ( "onload statements evaluated" );},
		
		// central broadcasting service
		mSubscribe : function ( sBroadcast, oFunction ) {
			if ( !oVox.oBroadcast [ sBroadcast ]) oVox.oBroadcast [ sBroadcast ] = [ oFunction ];
			else oVox.mPush ( oVox.oBroadcast [ sBroadcast ], oFunction );
		},
		mUnsubscribe : function ( sBroadcast, oFunction ) {
			var aSubscribers = oVox.oBroadcast [ sBroadcast ]; 
			var i = 0; while ( aSubscribers [ i ]) {
				if ( aSubscribers [ i ] == oFunction ) aSubscribers [ i ] = new Function ();
				i++;
			}
		},
		mBroadcast : function ( sBroadcast ) {
			if ( oVox.oBroadcast [ sBroadcast ]) oVox.mExecute ( oVox.oBroadcast [ sBroadcast ] );
		},
		
    // Initialize flash objects
    mActivateEmbeddedObjects : function(oParent){
      if(oClnt.bIE){
        oParent = oParent ? oParent : document;
        objects = oParent.getElementsByTagName("object");
        for (var i = 0; i < objects.length; i++)
          objects[i].outerHTML = objects[i].outerHTML;
      }
    },
    
    mGetAttribute : function(oNode, sAttrName) {
      var oAttribute;
      if (oNode.NodeType!=Node.TEXT_NODE) {
        for (var i=0; i < oNode.attributes.length; i++) {
          if (oNode.attributes[i].name == sAttrName) {
            oAttribute = oNode.attributes[i].value;
            break;
          }
        }
      }
      else oAttribute=null;
      return oAttribute;
    }
}

var oClnt = {
    mEval : function ( bStatement ) { return bStatement ? true : false; },
		mPass : function () {
			oClnt.bMozilla	= oClnt.mEval ( document.evaluate );
			oClnt.bOpera		= oClnt.mEval ( window.opera && document.addEventListener );
			oClnt.bIE			= oClnt.mEval ( document.all && document.createElement && !oClnt.bOpera );
			oClnt.bIEwin 		= oClnt.mEval ( oClnt.bIE && navigator.platform.indexOf ( "Win" ) !=-1 );
			oClnt.bIEmac 		= oClnt.mEval ( oClnt.bIE && !oClnt.bIEwin );
			oClnt.bSafari 	= oClnt.mEval ( navigator.appVersion.toLowerCase ().indexOf ( "safari" ) !=-1 );
			oClnt.bPass		= oClnt.bMozilla || oClnt.bOpera || oClnt.bIE || oClnt.bSafari;
			return oClnt.bPass;
		}
}

var oTools = {

		// extend native interfaces
		mInit : function () {
			
			if ( !window.Node ) window.Node = { ELEMENT_NODE: 1, ATTRIBUTE_NODE: 2, TEXT_NODE: 3 };
			if ( !Array.prototype.push ) {
				Array.prototype.push = function () {
					var iLength = this.length;
					var i = 0; while ( i < arguments.length ) this [ iLength + i ] = arguments [ i++ ];
					return this.length;
				}
			}
			String.prototype.contains = function ( sString ) {
				return this.indexOf ( sString ) !=-1;
			}
			String.prototype.attach = function ( sClass ) {
				var string = this;
				return string += ( string == "" ? "" : " " ) + sClass;
			}
			String.prototype.detach = function ( sClass ) {
				var string = this;
				return string.replace (( string.contains ( " " ) ? " " : "" ) + sClass, "" );
			}
			String.prototype.trim = function () {
				var string = this;
				string = string.replace( /^\s+/g, "" );// strip leading
				return string.replace( /\s+$/g, "" );// strip trailing				
			}
			
			if ( !String.prototype.splitStr ) {
				String.prototype.splitStr = function ( sep ) {
					var tempArr=[];
					var rest=true;
					var val=this;
					while (rest) 
					{
						var start=val.indexOf(sep);
						if (start!=-1) 
						{
							tempArr.push(val.substring(0,start));
							val=val.substring(start + sep.length);
						}
						else 
						{
							tempArr.push(val);
							rest=false;
						}
					}
					return tempArr;
				}
			}
			
			String.prototype.replaceAll = function (item, replacement) {
			 var retVal = '';
			 try{
			  item=item.replace('\\','\\\\').replace('$','\\$').replace('*','\\*').replace('.','\\.').replace('?','\\?').replace('+','\\+').replace('(','\\(').replace(')','\\)').replace('/','\\/').replace('[','\\[').replace(']','\\]').replace('{','\\{').replace('}','\\}').replace('|','\\|');
			  //alert(item);
			  retVal=this.replace( new RegExp(item,"g"), replacement );
			 }
			 catch(ex){
			  //alert(ex);
			  var str=this, aOccurs = str.splitStr(item);
			  for(var i = 0; i < aOccurs.length; i++)
			  retVal += aOccurs[i] + ((aOccurs.length - 1)==i ? '' : replacement);
			 }
			 return retVal;
			},
			
			String.prototype.startsWith = function(sSearchString){
        return this.indexOf(sSearchString) == 0;
			}
		},
		
		mMap : function (arr, func) {
			for (var word in arr) {
				arr[word]=func(arr[word]);
			}
		},
		
		// add-remove event listener
		mListener : function ( bAdd, oNode, sEvent, oHandler, bCapture ) {
			if ( document.addEventListener ) oNode [ bAdd ? "addEventListener" : "removeEventListener" ] ( sEvent, oHandler, bCapture );
			else if ( document.attachEvent ) oNode [ bAdd ? "attachEvent" : "detachEvent" ] ( "on" + sEvent, oHandler );
			else oNode [ "on" + sEvent ] = bAdd ? oHandler : null;
		},
		
		// emulate Element.contains
		mContains : function ( oNode, oTarget ) {
			var bContains = false;
			while ( oNode.parentNode ) 
				if ( oNode.parentNode == oTarget ) { bContains = true; break; }
				else oNode = oNode.parentNode;
			return bContains;
		},
		
		// get ancestor by nodename
		mGetAncestorByNodeName : function ( oNode, sNodeName ) {
			while ( oNode.parentNode ) {
				if ( oNode.parentNode.nodeName.toLowerCase () == sNodeName ) { 
					return oNode.parentNode; 
					break; 
				}
				else oNode = oNode.parentNode;
			}
			return null;
		},
		
		// recursive nodetree infiltrator
		mInfectnodetree : function ( oNode, oHandler ) {
			oHandler ( oNode );
			var i = 0; while ( i < oNode.childNodes.length ) {
				if ( oNode.childNodes.item ( i ).nodeType == Node.ELEMENT_NODE ) {
					oTools.mInfectnodetree ( oNode.childNodes.item ( i ), oHandler );
				}
				i++;
			}
		},
		
		// hack stylesheets
		mDeclare : function ( sClasses ) {
			if ( oClnt.bMozilla ) {
				var oSheet = document.styleSheets [ document.styleSheets.length - 1 ];
				if ( oSheet ) oSheet.insertRule ( sClasses, oSheet.cssRules.length );
			}
			else document.write ( "<style type=\"text/css\">" + sClasses + "</style>" );
		},
		
		// shorthand elements by ID
		mMount : function () {
			var i = 0, sRef; 
			while (( sRef = arguments [ i++ ]) != null ) {
				this [ sRef ] = document.getElementById ( sRef ) ? document.getElementById ( sRef ) : null; 
			}
		},
		
		// measure
		mWindow : function ( sProperty ) {
			var iReturn;
			var oDocelement = document [ "documentElement" ? "documentElement" : "body" ];
			switch ( sProperty ) {
				case "xscroll":	iReturn = window.pageXOffset ? window.pageXOffset : oDocelement.scrollLeft; break;
				case "yscroll":	iReturn = window.pageYOffset ? window.pageYOffset : oDocelement.scrollTop; break;
				case "height" : iReturn = window.innerHeight ? window.innerHeight : document.body.clientHeight; break;
				case "width"  :	iReturn = window.innerWidth ? window.innerWidth : document.body.clientWidth+15; break;
				case "top"    :	iReturn = oClnt.bIE ? window.screenTop : window.screenY; break;
				case "left"   :	iReturn = oClnt.bIE ? window.screenLeft : window.screenX; break;
			}
			return isNaN ( iReturn ) ? 0 : iReturn;
		},
		
		mInicializeCalendars : function(oCalendars){
      for (var cal in oCalendars) {
        try{
          Calendar.setup(
            {
              inputField : oCalendars[cal].inputField, // ID of the input field
              ifFormat : oCalendars[cal].ifFormat, // the date format
              button : oCalendars[cal].button, // ID of the button
              firstDay : oCalendars[cal].firstDay,
              weekNumbers : oCalendars[cal].weekNumbers,
              showsTime : oCalendars[cal].showsTime,
              timeFormat : oCalendars[cal].timeFormat,
              onUpdate : oCalendars[cal].onUpdate
            }
          );
        }
        catch(e){alert(e);}
      }
		}
}

var oXMLLib = {
		// Constants
	sIEPrefix4XSLParam : "xsl:",
	sDOMProgId : "",
	sXMLHTTPProgId : "",
	mInit : function () {
		
		if(window.XMLHttpRequest) 
			oXMLLib.mGetXMLHttpRequest=function() {
				return new window.XMLHttpRequest;
			}
		else {
      // Initializes constants
      oXMLLib.sDOMProgId=oXMLLib.mPickRecentProgId(["Msxml2.DOMDocument.5.0", "Msxml2.DOMDocument.4.0", "Msxml2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"], [["SelectNodes", 2],["TransformNode", 2]]);
      oXMLLib.sXMLHTTPProgId=oXMLLib.mPickRecentProgId(["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"], [["XMLHTTP", 4]]);
      oXMLLib.sThreadedDomProgId=oXMLLib.mPickRecentProgId(["Msxml2.FreeThreadedDOMDocument.5.0", "MSXML2.FreeThreadedDOMDocument.4.0", "MSXML2.FreeThreadedDOMDocument.3.0"]);
      oXMLLib.sXSLTemplateProgId=oXMLLib.mPickRecentProgId(["Msxml2.XSLTemplate.5.0", "Msxml2.XSLTemplate.4.0", "MSXML2.XSLTemplate.3.0"], [["XSLTProc", 2]]);
		
			oXMLLib.mGetXMLHttpRequest=function() {
				return new ActiveXObject(oXMLLib.sXMLHTTPProgId);
			}
		}
	},
	
	
	mPickRecentProgId : function(idList, enabledList){
        // found progId flag
        var bFound = false;
        var ex, o2Store;
        for(var i=0; i < idList.length && !bFound; i++){
            try{
                var oDoc = new ActiveXObject(idList[i]);
                o2Store = idList[i];
                bFound = true;
                for(var j=0;j<enabledList.length;j++)
                    if(i <= enabledList[j][1])
                        oXMLLib["bEnabled"+enabledList[j][0]] = true;
            }catch (oException){
                ex=oException;
            };
        };
        if (!bFound)
            //throw "Could not retreive a valid progID of Class: " + idList[idList.length-1]+". (original exception: "+ex+")";
        idList = null;
        return o2Store;
    },
    
  mGetHTTPRequest: function(url, proc){
		var oRequest=oXMLLib.mGetXMLHttpRequest();
		oRequest.open("GET", url, true);
		// Initiate handler
		if (proc!=null) oRequest.onreadystatechange=proc;
		else {
			oRequest.onreadystatechange=function() {
			  if (oRequest.readyState==4) {
				if (oRequest.status == 200) {
					alert(oRequest.responseText);
				}
				else {
					alert("There was a problem retrieving the XML data:\n" + oRequest.statusText);
				}
			  }
			}
		}
		oXMLLib.oRequest.send(null);
	},
    
    mCallBackEnd : function(url, params, proc, nodeId) {
		//alert(url + ' - ' + params + ' - ' +  proc);
		url=url.replaceAll('&amp;','&');
		var oRequest=oXMLLib.mGetXMLHttpRequest();
		oRequest.open("POST", url ,true);
		// Initiate handler
		oRequest.onreadystatechange=function() {
      var aborted = false;
      try {
        aborted = (oRequest.readyState == 4 && oRequest.status == 0);
      } catch (ex) {
        // Mozilla gets an exception throw here - you abort the thread, it calls
        // the readystatechange as part of the abort, and you're not
        // allowed to look at the status field. So, if we get one
        // just assume the request is aborted.
        aborted = true;
      }

      if (oXMLLib.mGenericCallback(oRequest) || (aborted)) {
        if (!aborted) {
          if (proc!=null) proc(oRequest, nodeId);
        }
        // Note that this is not just a simple detach call. IE has a bug where
        // it'll crash if we detach in the middle of this routine. So, we need to
        // delay a tiny bit, to get out of here, before we do the detach. Without
        // this, IE crashes badly.
        window.setTimeout(function() {
          // Get rid of circular reference leaks
          // Sometimes we see a readyState of 0 here, as though the object was being
          // reused. So, to be on the safe side, dont clear the handler in that case.
          if (oRequest.readyState == 4) {
            oRequest.onreadystatechange = oXMLLib.mFoofunc;
          }
        }, 10);
      }
      else if(aborted){
				alert("There was a problem retrieving the XML data:\n" + oRequest.statusText);
      }
		}
		//params = oXMLLib.mXMLEscape(params);
    oRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    oRequest.setRequestHeader('Content-Length', params.length);		
		oRequest.send(params);
	},

    mFoofunc : function() {},
  
    mGenericCallback : function (req) {
      return req.readyState == 4 && req.status == 200;
    },
    mXMLEscape : function(text) {
		return text.replaceAll('&','&amp;').replaceAll('<', '&lt;').replaceAll('>','&gt;').replaceAll('"','&quot;').replaceAll("'",'&apos;');
	},
	
    mXMLUnEscape : function(text) {
		return text.replaceAll('&lt;', '<').replaceAll('&gt;', '>').replaceAll('&quot;', '"').replaceAll('&apos;', "'").replaceAll('&amp;', '&');
	}
}

if ( oClnt.mPass ()) { // scripting for friendly browsers only
	// listen
	window.onload = oVox.mLoad;
	var oPageLoaderListener = setInterval('pageIsLoaded()', 50);
	
	oVox.mOnload ( // onload statements
		oTools.mInit,
		oXMLLib.mInit
	);

	function pageIsLoaded(){
		if(document.getElementById('worksheet')){
			clearInterval(oPageLoaderListener);
			window.onload = oVox.mLoad;
		}
	}
}