/*
$Id: m4.common.js,v 1.23 2008-01-07 15:33:13 cde Exp $
*/

var m4Common=
{
    Version : "2.1"
}

function m4Browsers()
{
    var userAgent      = navigator.userAgent.toLowerCase();
    var ieVersion      =0;
    
    this.isIE          = (userAgent.indexOf("msie") != -1);
    
    if (this.isIE)
    {
        ieVersion=Number(userAgent.substr(userAgent.indexOf("msie ")+5,3));
    }
    
    this.isIE55     =(this.isIE && ieVersion==5.5);    
    this.isIE55Up   =(this.isIE && ieVersion>=5.5);    
    this.isIE6      =(this.isIE && ieVersion==6);    
    this.isIE6Up    =(this.isIE && ieVersion>=6);
    this.isIE7      =(this.isIE && ieVersion==7);    
    this.isIE7Up    =(this.isIE && ieVersion>=7);
    this.isFF       =(userAgent.indexOf("firefox/")!=-1);
    this.isNS6      =(userAgent.indexOf("netscape6/")!=-1);
    this.isMOZ      =((userAgent.indexOf("firefox/")!=-1 || userAgent.indexOf("mozilla/5.0")!=-1) && !this.isNS6);
    this.isNS7      =(userAgent.indexOf("netscape/7")!=-1 || this.isMOZ);
    this.isNS       =(this.isNS7 || this.isMOZ || this.isNS6);
    this.isWinXP    =(userAgent.indexOf("windows nt 5.1")!=-1);
    this.isPreXP    =(userAgent.indexOf("windows")!=-1 && !this.winXP);
}


var browser=new m4Browsers();

var querystring={
    fullQS : "",
    arrQS : new Array(),
    
    _init :  function ()
    {
        var strQS=document.URL;
    	strQS=strQS.substr(strQS.indexOf("?")+1);
	    this.fullQS=strQS;
    
    	//Split the querystring into its name/value pairs
	    var arrTempQS=strQS.split("&")

	    //For each name/value pair. Add the value to the global array, using its name as the index
	    for (i=0;i<arrTempQS.length;i++){
		    if (arrTempQS[i]!=""){
			    arrValue=arrTempQS[i].split("=");
			    if (!arrValue[1]) arrValue[1]="";
			    this.arrQS[arrValue[0].toLowerCase()]=unescape(arrValue[1]);
		    }
	    }
    },
    
    get : function(strKey)
    {
        return this.arrQS[strKey];
    },
    
    getFullString :  function()
    {
        return this.fullQS;
    },
    
    getAsNumber : function(strKey)
    {
    	var strValue=this.get(strKey);
	    strValue=(!strValue || isNaN(strValue)) ? 0 : Number(strValue);
	    return strValue;
    },
    
    getAsString : function(strKey)
    {
    	var strValue=this.get(strKey);
	    strValue=(!strValue) ? "" : String(strValue);
	    return strValue;
    },
    
    //Crate a new querystring based on an array
    create : function(arrParams)
    {
        var qs="";
    
       for (var key in arrParams) {
	        qs+="&"+key+"="+escape(arrParams[key]);     
	   }
	   
	   if (qs.length>1){
	    qs="?"+qs.substr(1);
	   }
	   
	   return qs;
    }
}

querystring._init();



var cookie={
    get : function(name)
    {
        var dc=document.cookie;
        var strCookie = document.cookie.toLowerCase();
        var prefix = name + "=";
        var intBegin = strCookie.indexOf("; " + prefix);

        if (intBegin == -1)
        {
        intBegin = strCookie.indexOf(prefix);
        if (intBegin != 0) return null;
        } 
        else 
        intBegin += 2;
        
        var end = document.cookie.indexOf(";", intBegin);
        if (end == -1) end = dc.length;
        name = dc.substring(intBegin + prefix.length, end)
        var arrSpace = name.split("+");
        intBegin = arrSpace.length;
        name = arrSpace[0];
        var index = 1;
        while (index < intBegin)
        {
          name = name + " " + arrSpace[index];
          index = index + 1;
        }
        
        name = unescape(name);
        return name;   
    },
    
    set : function(name, value, path, expires, domain, secure)
    {
        var curCookie = name + "=" + escape(value) +
                        ((expires) ? "; expires=" + expires : "") +
                        ((path) ? "; path=" + path : "") +
                        ((domain) ? "; domain=" + domain : "") +
                        ((secure) ? "; secure" : "");
                        
        document.cookie = curCookie;
    }    
}

var m4Utils={
    /*******************************************************************************
    ** check
    **
    ** Sets a checkbox checked
    *******************************************************************************/
    check : function (strControl){
	    var objControl=$(strControl);
	    if (objControl && objControl.disabled==false) objControl.checked=!objControl.checked;
    },
    
    toBoolean : function (strValue){
        if (!strValue) return false;
	    if (String(strValue).toLowerCase()=="true") return true;
	    if (String(strValue).toString()=="1") return true;
    	
	    return false;
    },
   
    /******************************************************************************
    ** cloneArrayOfObjects
    **
    ** Clones an array which is built up of objects and returns a new array
    *******************************************************************************/  
    cloneArrayOfObjects : function(arr)
    {
        var newArr=[];
        for (var i=0;i<arr.length;i++)
        {   
            if (typeof(arr[i])=="object")
            {
               newArr[i]=Object.clone(arr[i]); 
            }
            else{
               newArr[i]=arr[i]; 
            }
        }
        
        return newArr;
    },

    /******************************************************************************
    ** purgeArrayOfObjects
    **
    ** Delete an array of objects
    *******************************************************************************/  
    purgeArrayOfObjects : function(arr)
    {
        for (var i=arr.length-1;i>=0;i--)
        {   
            delete arr[i];
            arr.splice(i);       
        }
    },
   
    /******************************************************************************
    ** lcompare
    **
    ** Does a case insenstive comparsion of two values
    *******************************************************************************/
    lcompare : function(strT1,strT2){
	    return (strT1.toLowerCase()==strT2.toLowerCase())
    },
    
    /******************************************************************************
    ** removePX
    **
    ** Removes the px Pixel text from a measurement
    *******************************************************************************/
    removePX : function(strValue){
        if (!strValue) return 0;
        
	    var intPos=strValue.toLowerCase().indexOf("px")
    	
	    if (intPos>=0){
		    strValue=strValue.substr(0,intPos)
	    }

	    return Number(strValue);
    },
    
    /******************************************************************************
    ** yesNoBox
    **
    ** Does a yesno box in IE (Needed by DW, do not remove)
    *******************************************************************************/
    yesNoBox : function(strMessage, strTitle) {
       var conYes=6;
      
       
       if (browser.isIE) {
          if (!strTitle) strTitle="Columbus";
          try{
            retVal = vbConfirmationDialog(strTitle,strMessage,292);
            retVal = (retVal==conYes);
          }
          catch(er){
            alert("Error : Cannot instantiate YesNo Dialog Box\niedialogs.vbs has not been included in this page");
          }
       }
       else {
          retVal = confirm(strMessage);
       }
       
       return retVal;
    },

    /*******************************************************************************
    ** PRIVATE : compareNumbers
    **
    ** Compare function for the array sort
    *******************************************************************************/
    _compareNumbers :  function(a, b) {
	    return a - b
    },
    
    /*******************************************************************************
    ** sortArray
    **
    ** Sort an array ascending
    *******************************************************************************/
    sortArray : function(arrArray){
        arrArray.sort(this._compareNumbers);
        return arrArray;
    },
      
    /*********************************************************************
    ** stopCaching
    **
    ** Creates a unique string to stop caching from occurring
    ************************************************************************/
    stopCaching : function()
    {
        var time=new Date();
	    return String(time.getHours())+String(time.getMinutes())+String(time.getSeconds())+String(time.getFullYear())+String(time.getMonth())+String(time.getDate());
    },

    /**********************************************************************
    ** getServerRoot
    **
    ** Get the root website name
    ************************************************************************/
    getServerRoot : function(){
	    var blnPort=(location.port!="") ? true : false;
	    var strServer=location.protocol+"//"+location.hostname;
	    
	    if (blnPort==true) strServer+=":"+location.port;
	    strServer+="/";
	    
	    return strServer;
    },
    
    
    /******************************************************************************
    ** getWebsiteRoot
    **
    ** Get the root of where the website is running from
    *******************************************************************************/
    getWebsiteRoot : function(){
	    var strRoot=document.location.href;

	    if (strRoot.indexOf("?")>0){
		    strRoot=strRoot.substr(0,strRoot.indexOf("?")-1);
	    }
    	
	    strRoot=strRoot.substr(0,strRoot.lastIndexOf("/"));
    	
	    if (strRoot.charAt(strRoot.length-1)!="/") strRoot+="/";
	    return strRoot;
    },

    
    /*******************************************************************************
    ** RgbToHex
    **
    ** Converts RGB to Hex
    *******************************************************************************/
     RgbToHex : function(str)
    {
	     if (!str) return "";
	     var s = str.substring(0, 1);
	     if (s=='#') return str;	 
    	 
	     s = str.substring(4, str.length - 1).split(",");
	     for (i=0;i<s.length;i++){
		    s[i]=s[i].trim();
	     }
    	 
	     var hexStr = "#";
	     hexStr += (s[0]>0) ? Number(s[0]).toString(16) : "00";
	     hexStr += (s[1]>0) ? Number(s[1]).toString(16) : "00";
	     hexStr += (s[2]>0) ? Number(s[2]).toString(16) : "00";
	     return hexStr;
    },
    
    
    /******************************************************************************
    ** splitRangeString
    **
    ** Converts 1,2-5,10 into 1,2,3,4,5,10
    ******************************************************************************/
    splitRangeString : function(strRange){
	    var arrRows=strRange.split(",");
	    var arrNewRows=new Array();
	    var a;
	    var b;
	    var i;
	    var i2;

	    try{
		    for (i=0;i<arrRows.length;i++){
			    if (arrRows[i].indexOf("-")>0){
				    a=Number(arrRows[i].substr(0,arrRows[i].indexOf("-")));
				    b=Number(arrRows[i].substr(arrRows[i].indexOf("-")+1));
    				
				    //Generate all number in range a-b
				    for (i2=a;i2<=b;i2++){
					    arrNewRows[arrNewRows.length]=i2;
				    }
			    }
			    else{
				    if (isNaN(arrRows[i])==false){
					    arrNewRows[arrNewRows.length]=Number(arrRows[i]);
				    }
				    else{
					    throw "Invalid";
				    }
			    }
    			
			    if (arrNewRows[arrNewRows.length-1]<0) throw "Minus value";
		    }		
	    }
	    catch(er){
		    return null;
	    }
    	
	    return arrNewRows;
    },
    
    
    /*******************************************************************************
    ** removeLastChar
    ** 
    ** Removes the last character from a string. If strChar is specified it will
    ** only remove the last character if it matches strChar
    *******************************************************************************/
    removeLastChar :function (strText,strChar){
	    var removeChar=(!strChar) ? true : (strText.charAt(strText.length-1)==strChar);
    	
	    if (removeChar==true)
		    strText=strText.substr(0,strText.length-1);
    	
	    return strText;
    },
        
    /*******************************************************************************
    ** removeFirstChar
    ** 
    ** Removes the 1st character from a string. If strChar is specified it will
    ** only remove the first character if it matches strChar
    *******************************************************************************/
    removeFirstChar : function(strText,strChar){
	    var removeChar=(!strChar) ? true : (strText.charAt(0)==strChar);
	    if (removeChar==true) strText=strText.substr(1);
	    return strText;
    },
    
    getWindowWidth : function(){
	    return (!browser.isIE) ? window.innerWidth : document.documentElement.clientWidth;
    },
    
    getWindowHeight : function(){
	    return (!browser.isIE) ? window.innerHeight : document.documentElement.clientHeight;
    },

    getWindowWidthPx : function(){
	    return this.getWindowWidth()+"px"
    },

    getWindowHeightPx : function(){
	    return this.getWindowHeight()+"px"
    },

    setCurrentCSS : function (title) {
        var i, a, main;
        for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
            if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) 
            {
                a.disabled = true;
                if(a.getAttribute("title") == title) {
                    a.disabled = false;
	            }
            }
        }
    },
    
    nonNullString : function(value)
    {
        return (!value) ? "" : value;
    },
    
    nonNullInt : function(value)
    {
        return (!value) ? 0 : value;
    },
   
    
    /******************************************************************************
    *** focusComponent
    *** Set focus on specified component
    ***
    ******************************************************************************/
     focusComponent : function(component){
        var objComponent=$(component);

        if (objComponent.disabled==false)
        { 
            objComponent.focus();
            objComponent.select();
        }
    },
    
    debugWindow : null,
    
    /******************************************************************************
    *** debug
    *** Opens a debug window, and 
    ******************************************************************************/
    debug : function(strText)
    {
          if (this.debugWindow==null){
            this.debugWindow=window.open('',"debug","location=0,status=0,scrollbars=1,resizable=1,width=800,height=600");
            this.debugWindow.document.write("<html>\n");
            this.debugWindow.document.write("<head>\n");
            this.debugWindow.document.write("<title>Columbus OM - IOP Message</title>\n");
            this.debugWindow.document.write("</head>\n");
            this.debugWindow.document.write("<body style=\"font-family: Courier New,Arial; font-size: 12px; background: #ffffff\">\n");
          }
          
          this.debugWindow.document.write(strText+"<br>");
    },
    
    /******************************************************************************
    ** addToDocumentOnClick
    **
    ** Append a function to the document.onclick event
    ******************************************************************************/  
    addToDocumentOnClick : function(func){
		Element.addEventListener(document,"onclick",func);
	}
}

var m4PopupBlockerTest={
    _popupBlockerMessage : "A pop-up blocker has been detected.\n\nYou need to configure your pop-up blocker to always allow pop-ups for this site and then restart your browser",

    test : function(strUserMessage)
    {
        if (strUserMessage)
        {
            this._popupBlockerMessage=strUserMessage;
        }
    
        //This setTimeout will trigger any popup blockers
        setTimeout("m4PopupBlockerTest._test()",100);
    },
    
    _test : function ()
    {
	    if (cookie.get("m4popupcheck")!="1"){
	        window.open("m4popuptest.html","popuptest","toolbar=no,Status=off,menubar=no,scroll=no,resizable=no,help=no,height=100px,width=100px,left=5000px,top=5000px");
        }
    },
    
    _returned :  function()
    {
        cookie.set("m4popupcheck","1");
    },
    
    popupsAllowed : function()
    {
        if (cookie.get("m4popupcheck")!="1"){
		    alert(this._popupBlockerMessage);
		    return false;
	    }
	    
	    return true;
    }
}


/******************************************************************************
** FUNCTION : m4Lang
**
** Get a key from the language file
*******************************************************************************/
//Create the global langauge object and load in the correct file
var m4Lang={

    phrases : {},
    language : null,
      
    get : function(strKey,strReplace0,strReplace1)
    {
        //Get the phrase
        try{
            var strPhrase=eval("m4Lang.phrases['"+strKey+"'];");
        }
        catch(er)
        {
            
        }
        
        //If the phrase cannot be found output the error string
        if (!strPhrase || strPhrase==""){
            strPhrase="** STRING NOT FOUND **";
        }
        
        //If the string contains {0} then replace it with the passed in value
        if (strReplace0 && strPhrase.indexOf("{0}")>=0)
        {
            strPhrase=strPhrase.replace("{0}",strReplace0);
        }
        
        //If the string contains {1} then replace it with the passed in value
        if (strReplace1 && strPhrase.indexOf("{1}")>=0)
        {
            strPhrase=strPhrase.replace("{1}",strReplace1);
        }
        
        return strPhrase;
    },
    
    getUiToolkitLanguage : function()
    {
       try{
           if (navigator.userLanguage) {
                m4Lang.language=(navigator.userLanguage.substring(0,2).toLowerCase());
           } 
           else if (navigator.language) {
                m4Lang.language=(navigator.language.substring(0,2).toLowerCase());
           }
           else{
                m4Lang.language="en";
           }
       }
       catch(er)
       {
          m4Lang.language="en";
       }
    },

    /******************************************************************************
    ** FUNCTION : m4LanguageHandler.loadFile
    **
    ** Load the correct language file
    *******************************************************************************/
    loadFile: function()
    {
        m4Lang.getUiToolkitLanguage();
        
        var kGuaranteedLanguages="en,fr,de,it";
    		
        //If the language is not one of the defaults then load in english as a default
        //in case the next language doesn't exist.
        if (kGuaranteedLanguages.indexOf(this.language)<0)
        {
        	this.language="en";
        }

		new Ajax.Request("js/lib/macro4/language/m4."+this.language+".js",{onComplete:m4Lang.langLoaded});
    },
    
    langLoaded : function(t)
    {
    	eval(t.responseText);
    },
    
    addPhrases: function(phrases)
    {
        Object.extend(m4Lang.phrases, phrases);
    }
}

//Load uiToolkit language in
//m4Lang.loadFile();

Object.extend(String.prototype, {

/*******************************************************************************
    ** removeLastChar
    ** 
    ** Removes the last character from a string. If strChar is specified it will
    ** only remove the last character if it matches strChar
    *******************************************************************************/
    removeLastChar :function (strChar){
	    var removeChar=(!strChar) ? true : (this.charAt(this.length-1)==strChar);
    	
	    if (removeChar==true)
		    return this.substr(0,this.length-1);
    	
	    return this;
    },
        
    /*******************************************************************************
    ** removeFirstChar
    ** 
    ** Removes the 1st character from a string. If strChar is specified it will
    ** only remove the first character if it matches strChar
    *******************************************************************************/
    removeFirstChar : function(strChar){
	    var removeChar=(!strChar) ? true : (this.charAt(0)==strChar);
	    if (removeChar==true) return this.substr(1);
	    
	    return this;
    },
    
    /******************************************************************************
    ** ltrim
    **
    ** Trim the character char from the left of a string
    *******************************************************************************/
    ltrim : function (){
	        return this.replace(/^\s+/g,"");
	},
	
    /******************************************************************************
    ** rtrim
    **
    ** Trim the character char from the right of a string
    *******************************************************************************/
    rtrim : function (){
	    return this.replace(/\s+$/g,"");
    },
    
    /******************************************************************************
    ** trim
    **
    ** Trim the character char from the left and right of a string
    *******************************************************************************/
    trim : function(){
	   return this.replace(/^\s+|\s+$/g,"");
    },
    
    /******************************************************************************
    *** trimBeforeChar
    *** Trims off the start of the text upto and including the strChar character
    ******************************************************************************/
    trimBeforeChar : function(strChar)
    {
          if (this.indexOf(strChar)>=0){
            return this.substring(this.indexOf(strChar)+1);
          }
          
          return this;
    },

    /******************************************************************************
    *** trimAfterChar
    *** Trims off the end of the text after and including the strChar character
    ******************************************************************************/
    trimAfterChar : function(strChar)
    {
          if (this.indexOf(strChar)>=0){
            return this.substring(0,this.indexOf(strChar));
          }
          
          return this;
    },
    
    /******************************************************************************
    *** replaceAll
    *** Replace's all occurences of a string
    *******************************************************************************/
    replaceAll : function(strMatch,strReplace)
    {    
        var re =new RegExp(strMatch,"g");
        return this.replace(re,strReplace);
    },
    
    /******************************************************************************
    *** extractStyles
    *** Extract CSS style tag from a string
    *******************************************************************************/
	extractStyles: function() {
		return this.extractTag("style");
	},
  
   	/******************************************************************************
    *** stripStyles
    *** Remove CSS style tag from a string
    *******************************************************************************/
  	stripStyles: function() {
    	return this.stripTag("style");
	},
	
	/******************************************************************************
    *** extractTag
    *** Extract a tag from a string. Excepts a tag Name
    *******************************************************************************/
	extractTag: function(tag) {
		var fragment="<"+tag+"[^>]*>([\u0001-\uFFFF]*?)</"+tag+">";
		var matchAll = new RegExp(fragment, 'img');
	    var matchOne = new RegExp(fragment, 'im');
	    return (this.match(matchAll) || []).map(function(styleTag) {
	      return (styleTag.match(matchOne) || ['', ''])[1];
	    });
	},
	
  	/******************************************************************************
    *** stripTag
    *** Remove a tag from a string. Excepts a tag Name
    *******************************************************************************/
  	stripTag: function(tag) {
  		var fragment="<"+tag+"[^>]*>([\u0001-\uFFFF]*?)</"+tag+">";
    	return this.replace(new RegExp(fragment, 'img'), '');
	},
	
	extractXml : function()
	{

		var fragment="<xml[^>]*>([\u0001-\uFFFF]*?)</xml>";
		var matchAll = new RegExp(fragment, 'img');
		var matchOne = new RegExp(fragment, 'im');
	    var matchId=new RegExp('<xml[^>].*id=\".*\".*>', 'im');
	    
	    var arrXml=(this.match(matchAll) || []);
		var xml=[];
		
		for (var i=0;i<arrXml.length;i++)
		{
			var id=(arrXml[i].match(matchId))[0];
			var start=id.indexOf("id=\"")+4;
			var end=id.indexOf("\"",start)-start;
			id=id.substr(start,end);
			var sXml=arrXml[i].match(matchOne)[1];
			
			xml[id]=sXml.toXML();
		}
		
		return xml;
	},
	
	
	toXML : function()
	{
        var objXml;
        
        if (browser.isIE){
           objXml = new ActiveXObject("Microsoft.XMLDOM")
           objXml.async = false;
           objXml.loadXML(this);
        }
        else
        {
            var vParser = new DOMParser();
            objXml = vParser.parseFromString(this, "text/xml");
        }
        
        return objXml;
	},
	
	
	/******************************************************************************
    *** applyStyles
    *** Apply any styles in a string to the browser (IE only)
    *******************************************************************************/
  	applyStyles : function() {
    	if (Prototype.Browser.Gecko) return;

	    var headEl = null;
	
	    // find all styles in the string
	    var styles=this.extractStyles();
	    
	    // add all found style blocks to the HEAD element.
	    for (i = 0; i < styles.length; i++) {
	        if (!headEl)
	        {  
	            headEl = document.getElementsByTagName('head')[0];
	            if (!headEl)
	            {  
	                return;
	            }
	        }
	        var newStyleEl = document.createElement('style');
	        newStyleEl.type = 'text/css';
	        if (Prototype.Browser.IE)
	        {  
	            newStyleEl.styleSheet.cssText = styles[i];
	        }
	        else
	        {  
	            var cssDefinitionsEl = document.createTextNode(styles[i]);
	            newStyleEl.appendChild(cssDefinitionsEl);
	        }
	        headEl.appendChild(newStyleEl);
	    }
  	}
});

Object.extend(Element, {
   
    /*****************************************************************************
    *** showInline
    *** Show a DOM element inline
    ***
    ******************************************************************************/
    showInline: function() {
        for (var i = 0; i < arguments.length; i++) {
          var element = $(arguments[i]);
          element.style.display = "block" ;
        }
    },
   
    /******************************************************************************
    *** toggleInline
    *** Toggle the visible state of the image. (Show inline)
    ******************************************************************************/
    toggleInline: function(element) {
        element = $(element);
        Element[Element.visible(element) ? 'hide' : 'showInline'](element);
        return element;
    },
      
    /******************************************************************************
    *** getBackgroundImage
    *** Gets an elements background-image and removes the url() part
    ******************************************************************************/
    getBackgroundImage : function(el)
    {
        var strImg=this.getStyle(el,"background-image");
        strImg=strImg.trimBeforeChar("(");
        strImg=strImg.trimAfterChar(")");
        
        if (strImg.charAt(0)=="\"") strImg=strImg.substr(1);
        if (strImg.charAt(strImg.length-1)=="\"") strImg=strImg.substr(0,strImg.length-1);
        
        return strImg;
    },
      
    /*****************************************************************************
    *** getText
    *** Gets the text from within a tag eg. <tag><tag1>hello</tag1></tag>
    *** will return "hello"
    ******************************************************************************/
    getText : function(element){
       if (browser.isIE)
       {
        return element.innerText.trim();
       }

       return element.textContent.trim();
    },
    
    /*****************************************************************************
    *** replaceClassName
    *** Replace a classname in a list of classes
    ******************************************************************************/
    replaceClassName: function(element, classNameToRemove, classNameToAdd)
    {
        element = $(element);
        element.className=m4CSS.replaceClassName(element.className,classNameToRemove,classNameToAdd);
    },
    
    /******************************************************************************
    *** displayAt
    *** Displays an element, at the x,y position specified. Optional width & height
    *** can be set
    ******************************************************************************/
    displayAt : function(element, intLeft,intTop, intWidth, intHeight)
    {
        element=$(element);
        
        element.style.top=   intTop+"px";
	    element.style.left=  intLeft+"px";
    	
	    if (intWidth) element.style.width=intWidth+"px";
	    if (intHeight) element.style.height=intHeight+"px";
	    //setTimeout out fixes display delay in IE6, but causes flicker in IE7
	    if (browser.isIE6)
	    {
	    	setTimeout(function(){Element.showInline(element)},0);
	   	}
	   	else
	   	{
	   		Element.showInline(element);
	   	}
    },
    
    /******************************************************************************
    *** displayAtScreenCenter
    *** Displays an element, at the x,y position specified. Optional width & height
    *** can be set
    ******************************************************************************/
    displayAtScreenCenter : function(element)
    {
        element=$(element);
        
        //Get the element width and height        
        var intElWidth=element.getWidth();
        var intElHeight=element.getHeight();
        
        var intLeft=(m4Utils.getWindowWidth()/2)-(intElWidth/2);
        var intTop=(m4Utils.getWindowHeight()/2)-(intElHeight/2)-50;

        element.style.top=   intTop+"px";
	    element.style.left=  intLeft+"px";
    	
	    element.style.display="block"
    },
    
    
    /******************************************************************************
    *** findParentElementByClass
    *** Find an elements parent which has the specified class name
    *******************************************************************************/  
    findParentByClass : function(element,strClass)
    {
        var objEl=element.parentNode;

	    while(objEl && !Element.hasClassName(objEl,strClass))
	    {
	        
	        objEl=objEl.parentNode;
	    }
        
        //Check if the parent has been found
        if (!objEl){
            return null;
        }
        
        return objEl.id;
    },
    

    /*******************************************************************************
    ** getRealYpos
    **
    ** Gets the Y page co-ordinate of any element
    *******************************************************************************/
    getRealYpos : function(el,blnProcessScrollable)
    {
        if (!blnProcessScrollable) blnProcessScrollable=false;
    
        el=$(el);
        
        var nTopPos = el.offsetTop;            
        var eParElement = (browser.isIE) ? el.offsetParent : el.parentNode;   
        while (eParElement != null)
        {                                 
            nTopPos += eParElement.offsetTop;       

            if (blnProcessScrollable && eParElement.scrollTop>0){
                nTopPos=nTopPos-eParElement.scrollTop;
            }

            eParElement = eParElement.offsetParent; 
        }
        if (browser.isIE) nTopPos=nTopPos+2;
        
        return nTopPos;                             
    },
    
    /*******************************************************************************
    ** getRealXpos
    **
    ** Gets the X page co-ordinate of any element
    *******************************************************************************/
    getRealXpos : function(el)
    {
        el=$(el);
        
        var nLeftPos = el.offsetLeft;          
        var eParElement = el.offsetParent;     
        while (eParElement != null)
        {                                            
            nLeftPos += eParElement.offsetLeft;      
            eParElement = eParElement.offsetParent;  
        }
        
        return nLeftPos;                             
    },
    
    /******************************************************************************
    *** isType
    *** 
    *** Checks if object is a form
    ******************************************************************************/
    isType : function(el,type)
    {
	    return (el!=null && el.tagName.toLowerCase()==type.toLowerCase()) ? true : false;
    },
    
    /******************************************************************************
    *** preventSelection
    *** 
    *** Stop text drag selection in the browser on the object
    ******************************************************************************/
    preventSelection : function(el,eventCache)
    {
       var eventType=(browser.isIE) ? "selectstart" : "mousedown";
       
       if (eventCache==null) eventCache=Event;
   
       eventCache.observe(el,eventType,function(e){return false;});
    },
    
    /******************************************************************************
    *** purge
    *** 
    *** Removes functions from an element, and childnodes so that any memory can
    *** be freed up. This is essential for stopping memory leaks.
    ******************************************************************************/
    purge :  function(el) {
        if (!browser.isIE) return;
        
        var a = el.attributes;
        var i;
        var l;
        var n;
        
        if (a) {
            l = a.length;
            for (i = 0; i < l; i += 1) {
                n = a[i].name;
                if (typeof el[n] === 'function') {
                    el[n] = null;
                }
            }
        }
        a = el.childNodes;
        if (a) {
            l = a.length;
            for (i = 0; i < l; i += 1) {
                this.purge(el.childNodes[i]);
            }
        }
    },
    
    /******************************************************************************
    *** purgeChildren
    *** 
    *** Removes functions from the elements childnodes so that any memory can
    *** be freed up. This is essential for stopping memory leaks.
    ******************************************************************************/
    purgeChildren :  function(el) 
    {
        if (!browser.isIE) return;
    
        for(var i=el.children.length-1;i>=0;i--)
        {
            Element.purge(el.children.item(i));
        }  
    }, 
    
    /******************************************************************************
    *** setInnerHtml
    *** 
    *** Set the innerHtml without leaking any memory in IE
    ******************************************************************************/
    setInnerHtml : function (el,html)
    {
        el=$(el);
        Element.purgeChildren(el);
        el.innerHTML=html;
    },
    
    /******************************************************************************
    ** METHOD : fireEvent
    ** On change 
    ******************************************************************************/      
    fire : function(el,eventStr)
    {
    	el=$(el);
		//Fire event on the dependant so that chains of dependancies will work
   		if (browser.isIE)
   		{
   			el.fireEvent("on"+eventStr);
   		}
   		else
   		{
			var myEvent = window.document.createEvent("Event"); 
        	myEvent.initEvent(eventStr, false, true); 
        	el.dispatchEvent(myEvent);
   		}
    },
    
    /******************************************************************************
    ** METHOD : destroy
    ** Safely remove element without leaking any memory
    ******************************************************************************/    
    destroy : function(element)
    {
        element=$(element);
        
        if (!element) return;
        
        if (browser.isIE)
        {
            var garbageBin = document.getElementById('IELeakGarbageBin');
            if (!garbageBin)
            {
                garbageBin = document.createElement('DIV');
                garbageBin.id = 'IELeakGarbageBin';
                garbageBin.style.display = 'none';
                document.body.appendChild(garbageBin);
            }

            // move the element to the garbage bin
            garbageBin.appendChild(element);
            garbageBin.innerHTML = '';
        }
        else
        {
            element.parentNode.removeChild(element);
        }
    }
});


m4CSS={
    /*****************************************************************************
    *** hasClassName
    *** Checks if a string of classes contains a className
    ******************************************************************************/
    hasClassName: function(strFullClass, className) {
        return strFullClass.split(/\s+/).include(className);
    },
    
    /*****************************************************************************
    *** addClassName
    *** Adds a class to the string list of classes
    ******************************************************************************/
    addClassName: function(strFullClass, className) {
    
        return strFullClass.split(/\s+/).concat(className).join(' ');
    },

    /*****************************************************************************
    *** removeClassName
    *** Remove class from string list of classes
    ******************************************************************************/
    removeClassName: function(strFullClass, classNameToRemove) 
    {
      return strFullClass.split(/\s+/).select(function(className) {
            return className != classNameToRemove;
        }).join(' ');       
    },
    
    /*****************************************************************************
    *** replaceClassName
    *** Replace a classname in a string list of classes
    ******************************************************************************/
    replaceClassName: function(strFullClass, classNameToRemove, classNameToAdd)
    {
        var arrClass=strFullClass.split(/\s+/);
        
        for (i=0;i<arrClass.length;i++)
        {
            if (arrClass[i]==classNameToRemove){
                arrClass[i]=classNameToAdd;
                break;
            }
        }
        
        return arrClass.join(" ");
    }
}

/*****************************************************************************
*** $css1
*** Wraps up $css calls so that it doesn't crash if no element is found
******************************************************************************/
$css1=function(cssSelector,startElement)
{
    var arrElements=$css(cssSelector,startElement);
    
    if (arrElements.length>0)
    {
        return arrElements[0];
    }

    return null;
}

function $css(selector,startId) {

    if (typeof(selector)=="string")
    {
        selector=new Array(selector);
    }
    
    startId=$(startId);

    if (!startId) startId=document;

    return Selector.findChildElements(startId, $A(selector));
}

Object.extend(Form,{
        submitAndUpdate : function(_form, targetEl)
        {
          var data=$(_form).serialize(true);
          new Ajax.Updater(targetEl,$(_form).action,{parameters:data});
        }
    }
 );
 
 Object.extend(Object, {
    purge : function(obj)
    {
        for (property in obj)
        {
                obj[property]=null;
        }
    }
 });
 
 Object.extend(Array.prototype, {
    purge : function(obj)
    {
        for (var i=0;i<this.length;i++)
        {
            Object.purge(this[i]);
            this[i]=null;
        }
    }
 });
 