/*
 OJBSv2 Common v1.0 - James Wragg
 (c)Madgex: 2007, All rights reserved
 Common JavaScript functions used througout OJBSv2
*/


	// === utilities ===

	// trim whitespace from strings
	if(!String.trim){		
		String.prototype.trim=function(){ 
			return this.replace(/^\s*|\s*$/g,'');
		}
	}
	
	if(!String.contains){		
		String.prototype.contains=function(string, s){
			return (s) ? (s + this + s).indexOf(s + string + s) > -1 : this.indexOf(string) > -1;
		}
	}


	// IE does not handle indexOf on arrays.
	if(!Array.indexOf){
	    Array.prototype.indexOf = function(obj){
	        for(var i=0; i<this.length; i++){
	            if(this[i]==obj){
	                return i;
	            }
	        }
	        return -1;
	    }
	}




/* document.getElementsBySelector(selector)
   - returns an array of element objects from the current document
     matching the CSS selector. Selectors can contain element names, 
     class names and ids and can be nested. For example:
     
       elements = document.getElementsBySelect('div#main p a.external')
     
     Will return an array of all 'a' elements with 'external' in their 
     class attribute that are contained inside 'p' elements that are 
     contained inside the 'div' element which has id="main"

   New in version 0.4: Support for CSS2 and CSS3 attribute selectors:
   See http://www.w3.org/TR/css3-selectors/#attribute-selectors

   Version 0.4 - Simon Willison, March 25th 2003
   -- Works in Phoenix 0.5, Mozilla 1.3, Opera 7, Internet Explorer 6, Internet Explorer 5 on Windows
   -- Opera 7 fails 
*/

function getAllChildren(e) {
  // Returns all children of element. Workaround required for IE5/Windows. Ugh.
  return e.all ? e.all : e.getElementsByTagName('*');
}

document.getElementsBySelector = function(selector) {
  // Attempt to fail gracefully in lesser browsers
  if (!document.getElementsByTagName) {
    return new Array();
  }
  // Split selector in to tokens
  var tokens = selector.split(' ');
  var currentContext = new Array(document);
  for (var i = 0; i < tokens.length; i++) {
    token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
    if (token.indexOf('#') > -1) {
      // Token is an ID selector
      var bits = token.split('#');
      var tagName = bits[0];
      var id = bits[1];
      var element = document.getElementById(id);
      if (tagName && element.nodeName.toLowerCase() != tagName) {
        // tag with that ID not found, return false
        return new Array();
      }
      // Set currentContext to contain just this element
      currentContext = new Array(element);
      continue; // Skip to next token
    }
    if (token.indexOf('.') > -1) {
      // Token contains a class selector
      var bits = token.split('.');
      var tagName = bits[0];
      var className = bits[1];
      if (!tagName) {
        tagName = '*';
      }
      // Get elements matching tag, filter them for class selector
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      continue; // Skip to next token
    }
    // Code to deal with attribute selectors
    if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
      var tagName = RegExp.$1;
      var attrName = RegExp.$2;
      var attrOperator = RegExp.$3;
      var attrValue = RegExp.$4;
      if (!tagName) {
        tagName = '*';
      }
      // Grab all of the tagName elements within current context
      var found = new Array;
      var foundCount = 0;
      for (var h = 0; h < currentContext.length; h++) {
        var elements;
        if (tagName == '*') {
            elements = getAllChildren(currentContext[h]);
        } else {
            elements = currentContext[h].getElementsByTagName(tagName);
        }
        for (var j = 0; j < elements.length; j++) {
          found[foundCount++] = elements[j];
        }
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      var checkFunction; // This function will be used to filter the elements
      switch (attrOperator) {
        case '=': // Equality
          checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
          break;
        case '~': // Match one of space seperated words 
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
          break;
        case '|': // Match start with value followed by optional hyphen
          checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
          break;
        case '^': // Match starts with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
          break;
        case '$': // Match ends with value - fails with "Warning" in Opera 7
          checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
          break;
        case '*': // Match ends with value
          checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
          break;
        default :
          // Just test for existence of attribute
          checkFunction = function(e) { return e.getAttribute(attrName); };
      }
      currentContext = new Array;
      var currentContextIndex = 0;
      for (var k = 0; k < found.length; k++) {
        if (checkFunction(found[k])) {
          currentContext[currentContextIndex++] = found[k];
        }
      }
      // alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
      continue; // Skip to next token
    }
    // If we get here, token is JUST an element (not a class or ID selector)
    tagName = token;
    var found = new Array;
    var foundCount = 0;
    for (var h = 0; h < currentContext.length; h++) {
      var elements = currentContext[h].getElementsByTagName(tagName);
      for (var j = 0; j < elements.length; j++) {
        found[foundCount++] = elements[j];
      }
    }
    currentContext = found;
  }
  return currentContext;
}

/* That revolting regular expression explained 
/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
  \---/  \---/\-------------/    \-------/
    |      |         |               |
    |      |         |           The value
    |      |    ~,|,^,$,* or =
    |   Attribute 
   Tag
*/








    function addLoadEvent(func) {
        var oldonload = window.onload;
        if (typeof window.onload != "function") {
            window.onload = func;
        } else {
            window.onload = function () {oldonload();func();};
        }
    }

	function addEvent( obj, type, fn )
	{
		if (obj.addEventListener)
			obj.addEventListener( type, fn, false );
		else if (obj.attachEvent)
		{
			obj["e"+type+fn] = fn;
			obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
			obj.attachEvent( "on"+type, obj[type+fn] );
		}
	}
	
	function removeEvent( obj, type, fn )
	{
		if (obj.removeEventListener)
			obj.removeEventListener( type, fn, false );
		else if (obj.detachEvent)
		{
			obj.detachEvent( "on"+type, obj[type+fn] );
			obj[type+fn] = null;
			obj["e"+type+fn] = null;
		}
	}
	
	function findEventSource(e) {
		if (typeof e == 'undefined')
			var e = window.event;

		var source;
		if (typeof e.target != 'undefined') 
			source = e.target;
		else if (typeof e.srcElement != 'undefined') 
			source = e.srcElement;
		else 
			return true;

		if (source.nodeType == 3)
			source = source.parentNode;
			
		return source;
	}
	
	function noBubble(e)
	{
		if (e && e.stopPropagation)
			e.stopPropagation();
		else
			window.event.cancelBubble = true;
	}
	
	
	
	/*
	    Written by Jonathan Snook, http://www.snook.ca/jonathan
	    Add-ons by Robert Nyman, http://www.robertnyman.com
	*/
	function getElementsByClassName(oElm, strTagName, strClassName){
	    var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
	    var arrReturnElements = new Array();
	    strClassName = strClassName.replace(/\-/g, "\\-");
	    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
	    var oElement;
	    for(var i=0; i<arrElements.length; i++){
	        oElement = arrElements[i];      
	        if(oRegExp.test(oElement.className)){
	            arrReturnElements.push(oElement);
	        }   
	    }
	    return (arrReturnElements)
	}
	



function checkForCalendar(){
    var allInputs = document.getElementsByTagName("input");
    for( var i=0; i < allInputs.length; i++) {
        if( CSSClass.has( allInputs[i], "date" ) ) {
            var input = new InputFieldCalendar( allInputs[i] );
            input.Build();
        }
    }
}

function checkForFCKEditors(){
    var allTextAreas = document.getElementsByTagName("textarea");
    for( var i=0; i < allTextAreas.length; i++) {
        if( CSSClass.has( allTextAreas[i], "fckeditor" ) ) {            
            var oFCKeditor = new FCKeditor( allTextAreas[i].name );
            oFCKeditor.BasePath = "../JScript/FCKeditor/";
            oFCKeditor.ToolbarSet = "Madgex";
            oFCKeditor.ReplaceTextarea();
        }
    }
} 

function prepareHovers() {
	if ( !document.getElementById("mainContent") )
	    return;
	    
	var content = document.getElementById("mainContent");
	    
// document.body, "select", "autoSubmit"
// "#mainContent table.action tr:not(.tableHeader)"
	addTRHoverClass(content, "hover");

    //addHoverClass("div#mainContent table.action tr", "hover");
    addHoverClass(content, "listerContainer", "hover");
    addHoverClass(content, "resultsContainer", "resultsContainerOn");
}

function addTRHoverClass(oEle, hoverClass){
   
	var table = getElementsByClassName(oEle, "table", "action");
    
	for (var x = 0; x < table.length; x++){
		var rows = table[x].getElementsByTagName("tr");

		if ( rows.length > 0 ){

			for (var i=0; i<rows.length; i++) {
			    if ( !CSSClass.has(rows[i], "tableHeader") ){
				    if (!rows[i].className.match(hoverClass)) { 
				      rows[i].onmouseover = function() {
				       CSSClass.add(this, hoverClass);
				       return false;
				      }
				      rows[i].onmouseout = function() {
				       CSSClass.remove(this, hoverClass);
				       return false;
				      }
				    }
				}
			}
		}
	}
}

function addHoverClass(oEle, findClass, hoverClass) {
 // var elems = cssQuery(findElement);
 // var elems = document.getElementsBySelector(find);
 var elems = getElementsByClassName(oEle, "*", findClass);

 for (var i=0; i<elems.length; i++) {
	if (!elems[i].className.match(hoverClass) && !elems[i].className.match("tableHeader")) { 
	  elems[i].onmouseover = function() {
	   CSSClass.add(this, hoverClass);
	   return false;
	  }
	  elems[i].onmouseout = function() {
	   CSSClass.remove(this, hoverClass);
	   return false;
	  }
	}
 }
}



// CSSClass: utilities for manipulating the CSS class of an HTML element.
var CSSClass = {
    add: function(node, name) {
      if(node) node.className = ((node.className || '') == '' ? '' : node.className + ' ') + name;
    },

    remove: function(node, name) {
      if(node) node.className = node.className.replace(new RegExp("\\b"+ name+"\\b\\s*", "g"), "");
    },

    has: function(node, name) {
      return new RegExp('(^|\\s)' + name + '(\\s|$)').test(node.className);
    }
};


function radioToggle(objEvt, radioToWatch, radioActivateID, targetID, stateOfTarget, reverseAction) {
	// Watches a radio array and when the radioActivateID is checked the targetID and it's contents are enabled.
	// Otherwise the contents of targetID are disabled.
	// cssQuery and addClass/removeClass functions are required.

	/*
	radioToWatch = the name given to the radio array in which to attach the monitor
	radioActivateID = the id of the radio group that activates the target
	targetID = the id of the element/group of elemets that are affected. can be a single element or a container tag.
	targetActivate = if the contents of targetID can be checked then it is
	*/	

/*
e.g.
	formToggle('sService_3', 'sService_3on', 'accessRights');
	formToggle('sService_3', 'sService_3on', 'accessRights', 'check');
	formToggle('sService_3', 'sService_3on', 'accessRights', 'check', true);
	formToggle('sService_3', 'sService_3on', 'accessRights', 'uncheck', true);
*/
	
    if ( (rArr = document.getElementsByName(radioToWatch)).length > 0 ) {
		//tarNode = cssQuery("#" + targetID + " input");
        var tarNode = document.getElementById(targetID).getElementsByTagName('input');

        //reset the target
		if ( !reverseAction )
		    disableTarget(tarNode, stateOfTarget);
				
        for (col = 0; col < rArr.length; col++) {
            elem = rArr[col];
            if ( elem.id == radioActivateID ) {
                if ( reverseAction ){
					addEvent(elem, objEvt, function(){disableTarget(tarNode, stateOfTarget)}, false);
	                if (elem.checked == true) {
	                    disableTarget(tarNode, stateOfTarget);
	                }
				} else {
					addEvent(elem, objEvt, function(){enableTarget(tarNode, stateOfTarget)}, false);
	                if (elem.checked == true) {
	                    enableTarget(tarNode, stateOfTarget);
	                }
				}
            } else {
                if ( reverseAction ){
					addEvent(elem, objEvt, function(){enableTarget(tarNode, stateOfTarget)}, false);
				}else{
					addEvent(elem, objEvt, function(){disableTarget(tarNode, stateOfTarget)}, false);
				}
            }
        }
    }

    function enableTarget(tarNode, state) {
        if (tarNode.length > 0) {
            for (x = 0; x < tarNode.length; x++) {
                if (tarNode[x].nodeType == 1) {
                    tarNode[x].disabled = false;
                    CSSClass.remove(tarNode[x], "disabled");
					if (state == "check"){
						tarNode[x].checked = true;
					}else if (state == "uncheck"){
						tarNode[x].checked = false;
					}
                }
            }
        } else {
            var tarNode = document.getElementById(targetID);
            tarNode.disabled = false;
            CSSClass.remove(tarNode, "disabled");
				if (state == "check"){
					tarNode.checked = true;
				}else if (state == "uncheck"){
					tarNode.checked = false;
				}
        }
    }


    function disableTarget(tarNode, state) {
        if (tarNode.length > 0) {
            for (x = 0; x < tarNode.length; x++) {
                if (tarNode[x].nodeType == 1) {
                    tarNode[x].disabled = true;
                    CSSClass.add(tarNode[x], "disabled");
					if (state == "check"){
						tarNode[x].checked = true;
					}else if (state == "uncheck"){
						tarNode[x].checked = false;
					}
                }
            }
        } else {
            var tarNode = document.getElementById(targetID);
            tarNode.disabled = true;
            CSSClass.add(tarNode, "disabled");
			if (state == "check"){
				tarNode.checked = true;
			}else if (state == "uncheck"){
				tarNode.checked = false;
			}
        }
    }

}

	
	
	function enableAutoSubmits() {
	    // Find all dropdown selectors that have a class of 'autoSubmit' and make them automatically
	    // submit on change and hide the associated, but now un-needed apply button.

		// find all selects with class of .autoSubmit
		elemColl = getElementsByClassName(document.body, "select", "autoSubmit");
		
		for ( i = 0; i < elemColl.length; i++ ){
			// find the associated button
			var b = findAssocButton(elemColl[i]);
			//var f = findAssocForm(elemColl[i]);
	
			if ( b ) {
				// hide button
				b.style.display = 'none';
				
				// attach onchange event to dropdown
				addEvent(elemColl[i], 'change', submitForm , false);

			}

		}
		
		
		function findAssocButton( n ){
			if ( n == null ) return false;
			
			if( n.nodeName != "input" && n.type != "image" ){
				return findAssocButton( n.nextSibling );				
			}else{
				return n;
			}
		}

		function findAssocForm( n ){
			if ( n == null ) return false;
			
			if( n.nodeName != "FORM" ){
				return findAssocForm( n.parentNode );
			}else{
				return n;
			}
		}

		function submitForm( e ){
//			var f = findAssocForm(findEventSource(e));
//			f.submit();
			var b = findAssocButton(findEventSource(e));
			b.click();
		}
	
	}


function checkToggle(checkToWatch, targetID, reverse) {
    // checkToWatch - the checkbox to monitor for tick, untick
    // targetID - the target div id that contains all that needs enabling/disabling
    // reverse - reverses the check/uncheck
    
    if ( (e = document.getElementById(checkToWatch)) && (t = document.getElementById(targetID)) ) {
        //checkbox & target found, go attach event
        addEvent(e, 'click', function(){toggleTarget(e, t, reverse)}, false);
        toggleTarget(e, t, reverse);
    }
        
    function toggleTarget(e, t, reverse){        
        var elemColl = getWantedElems(t);
        
        if ( e.checked && !reverse ) {
            for ( var x = 0; x < elemColl.length; x++ ) {
                elemColl[x].disabled = false;
                CSSClass.remove(elemColl[x], "disabled");
            }
        }else if ( !e.checked && reverse ){
            for ( var x = 0; x < elemColl.length; x++ ) {
                elemColl[x].disabled = false;
                CSSClass.remove(elemColl[x], "disabled");
            }
        }else{
            for ( var x = 0; x < elemColl.length; x++ ) {
                elemColl[x].disabled = true;
                CSSClass.add(elemColl[x], "disabled");
            }
        }
        
    }
         
 
    
    function getWantedElems(t){        
        var targetElems = new Array();

        elemColl = t.getElementsByTagName('*');
        for ( var x = 0; x < elemColl.length; x++ ) {
            if ( elemColl[x].nodeName.toLowerCase() === 'select' || elemColl[x].nodeName.toLowerCase() === 'input' || elemColl[x].nodeName.toLowerCase() === 'textarea' )
                targetElems.push(elemColl[x]);
        }
        
        return targetElems;
    }

    
}



function initRadioToggle(){
    radioToggle('click', 'sService_2', 'sService_2on', 'accessRights', 'check', true);
    checkToggle('bSendEmail', 'appMsg', false);

}


function addPrintButton(){
    //look for #action with class .print-button
    if ( (e = document.getElementById('actions')) && CSSClass.has(e, 'print-button') ){
        
        printButton = document.createElement('img');
        printButton.setAttribute( 'src', '../images/button-print.gif' );
        printButton.setAttribute( 'alt', 'Print Button' );
        printButton.style.cursor = "pointer";
        addEvent(printButton, 'click', printPage);
        e.appendChild(printButton);    
    }
    
    function printPage(){
        window.print();
        return false;
    }
}


	// -------------------------------------------------------------------
	// Madgex Limited
	// Copyright (c) 2007 Madgex Limited. All Rights Reserved.
	// Automatically adds expand/collapse toggle to large multiSelects
	// James Wragg
	// 31 May 2007, Version 1.0
	// required = button-plus.gif, button-minus.gif, addEvent(), CSSClass()
	// -------------------------------------------------------------------
		

	function msExpandInit(){
	
		//setup variables
		var msToggleClass = "active";
		var msactivationLength = 61; // best to have above 60 - don't get it confused with min/sec time selectors!
		var expandIcon = "../images/button-plus.gif";
		var collapseIcon = "../images/button-minus.gif";
		
		// msposMethod = "class" = the positioning is handled via the CSS class of "expandToggle"
		// msposMethod = "absolute" = the positioning is absolute top right of select
		var msposMethod = "absolute"; 

		// get all selects
		var elems = document.getElementsByTagName("select");
		
		for ( var x = 0; x < elems.length; x++ ){
			if ( elems[x].length > msactivationLength ) {
				var obj = elems[x];
				var toggleButton = document.createElement("img");
				toggleButton.src = expandIcon;
				toggleButton.title = toggleButton.alt = "Expand";
				toggleButton.id = "target-" + elems[x].id;
				
				if ( msposMethod == "class" ) {
					toggleButton.className = "expandToggle";
				} else if ( msposMethod == "absolute" ) {
					var top = obj.offsetTop;
					var left = obj.offsetWidth + obj.offsetLeft + 5;
					toggleButton.style.position = 'absolute';
					toggleButton.style.top = top + 'px';
					toggleButton.style.left = left + 'px';
				}

				addEvent( toggleButton, 'click', toggleExpand );
				obj.parentNode.appendChild(toggleButton);
			}
		}
		
		function toggleExpand(e){
			var sourceElt = findEventSource(e);
			var targetID = sourceElt.id.replace("target-", "");
			var targetSelect = document.getElementById(targetID);
			
			if ( CSSClass.has(targetSelect, msToggleClass) ){
				sourceElt.src = expandIcon;
				sourceElt.title = "Expand";
				CSSClass.remove(targetSelect, msToggleClass);
			}else{
				sourceElt.src = collapseIcon;
				sourceElt.title = "Collapse";
				CSSClass.add(targetSelect, msToggleClass);		
				targetSelect.focus();
			}
			
		}
		
	}
	
	
	addEvent(window, 'load', msExpandInit, false);
	// YAHOO.util.Event.onDOMReady(msExpandInit);






YAHOO.util.Event.onDOMReady(addPrintButton);
YAHOO.util.Event.onDOMReady(enableAutoSubmits);
YAHOO.util.Event.onDOMReady(prepareHovers);
YAHOO.util.Event.onDOMReady(initRadioToggle);
//YAHOO.util.Event.onDOMReady(checkForCalendar);

// Temporarily(?) commented out due to FCKeditor issues.
// YAHOO.util.Event.onDOMReady(checkForFCKEditors);


addEvent(window, 'load', checkForCalendar, false);
//    addEvent(window, 'load', enableAutoSubmits, false);   
//    addEvent(window, 'load', prepareHovers, false);
//    addEvent(window, 'load', checkForFCKEditors, false);
//    addEvent(window, 'load', initRadioToggle, false);


