//v1.7
// Flash Player Version Detection
// Detect Client Browser type
// Copyright 2005-2007 Adobe Systems Incorporated.  All rights reserved.
var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;

function ControlVersion()
{
	var version;
	var axo;
	var e;

	// NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry

	try {
		// version will be set for 7.X or greater players
		axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
		version = axo.GetVariable("$version");
	} catch (e) {
	}

	if (!version)
	{
		try {
			// version will be set for 6.X players only
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
			
			// installed player is some revision of 6.0
			// GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
			// so we have to be careful. 
			
			// default to the first public version
			version = "WIN 6,0,21,0";

			// throws if AllowScripAccess does not exist (introduced in 6.0r47)		
			axo.AllowScriptAccess = "always";

			// safe to call for 6.0r47 or greater
			version = axo.GetVariable("$version");

		} catch (e) {
		}
	}

	if (!version)
	{
		try {
			// version will be set for 4.X or 5.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
			version = axo.GetVariable("$version");
		} catch (e) {
		}
	}

	if (!version)
	{
		try {
			// version will be set for 3.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
			version = "WIN 3,0,18,0";
		} catch (e) {
		}
	}

	if (!version)
	{
		try {
			// version will be set for 2.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
			version = "WIN 2,0,0,11";
		} catch (e) {
			version = -1;
		}
	}
	
	return version;
}

// JavaScript helper required to detect Flash Player PlugIn version information
function GetSwfVer(){
	// NS/Opera version >= 3 check for Flash plugin in plugin array
	var flashVer = -1;
	
	if (navigator.plugins != null && navigator.plugins.length > 0) {
		if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
			var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
			var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
			var descArray = flashDescription.split(" ");
			var tempArrayMajor = descArray[2].split(".");			
			var versionMajor = tempArrayMajor[0];
			var versionMinor = tempArrayMajor[1];
			var versionRevision = descArray[3];
			if (versionRevision == "") {
				versionRevision = descArray[4];
			}
			if (versionRevision[0] == "d") {
				versionRevision = versionRevision.substring(1);
			} else if (versionRevision[0] == "r") {
				versionRevision = versionRevision.substring(1);
				if (versionRevision.indexOf("d") > 0) {
					versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
				}
			}
			var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
		}
	}
	// MSN/WebTV 2.6 supports Flash 4
	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
	// WebTV 2.5 supports Flash 3
	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
	// older WebTV supports Flash 2
	else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
	else if ( isIE && isWin && !isOpera ) {
		flashVer = ControlVersion();
	}	
	return flashVer;
}

// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
{
	versionStr = GetSwfVer();
	if (versionStr == -1 ) {
		return false;
	} else if (versionStr != 0) {
		if(isIE && isWin && !isOpera) {
			// Given "WIN 2,0,0,11"
			tempArray         = versionStr.split(" "); 	// ["WIN", "2,0,0,11"]
			tempString        = tempArray[1];			// "2,0,0,11"
			versionArray      = tempString.split(",");	// ['2', '0', '0', '11']
		} else {
			versionArray      = versionStr.split(".");
		}
		var versionMajor      = versionArray[0];
		var versionMinor      = versionArray[1];
		var versionRevision   = versionArray[2];

        	// is the major.revision >= requested major.revision AND the minor version >= requested minor
		if (versionMajor > parseFloat(reqMajorVer)) {
			return true;
		} else if (versionMajor == parseFloat(reqMajorVer)) {
			if (versionMinor > parseFloat(reqMinorVer))
				return true;
			else if (versionMinor == parseFloat(reqMinorVer)) {
				if (versionRevision >= parseFloat(reqRevision))
					return true;
			}
		}
		return false;
	}
}

function AC_AddExtension(src, ext)
{
  if (src.indexOf('?') != -1)
    return src.replace(/\?/, ext+'?'); 
  else
    return src + ext;
}

function AC_Generateobj(objAttrs, params, embedAttrs) 
{ 
  var str = '';
  if (isIE && isWin && !isOpera)
  {
    str += '<object ';
    for (var i in objAttrs)
    {
      str += i + '="' + objAttrs[i] + '" ';
    }
    str += '>';
    for (var i in params)
    {
      str += '<param name="' + i + '" value="' + params[i] + '" /> ';
    }
    str += '</object>';
  }
  else
  {
    str += '<embed ';
    for (var i in embedAttrs)
    {
      str += i + '="' + embedAttrs[i] + '" ';
    }
    str += '> </embed>';
  }

  document.write(str);
}

function AC_FL_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
     , "application/x-shockwave-flash"
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_SW_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".dcr", "src", "clsid:166B1BCA-3F9C-11CF-8075-444553540000"
     , null
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
  var ret = new Object();
  ret.embedAttrs = new Object();
  ret.params = new Object();
  ret.objAttrs = new Object();
  for (var i=0; i < args.length; i=i+2){
    var currArg = args[i].toLowerCase();    

    switch (currArg){	
      case "classid":
        break;
      case "pluginspage":
        ret.embedAttrs[args[i]] = args[i+1];
        break;
      case "src":
      case "movie":	
        args[i+1] = AC_AddExtension(args[i+1], ext);
        ret.embedAttrs["src"] = args[i+1];
        ret.params[srcParamName] = args[i+1];
        break;
      case "onafterupdate":
      case "onbeforeupdate":
      case "onblur":
      case "oncellchange":
      case "onclick":
      case "ondblClick":
      case "ondrag":
      case "ondragend":
      case "ondragenter":
      case "ondragleave":
      case "ondragover":
      case "ondrop":
      case "onfinish":
      case "onfocus":
      case "onhelp":
      case "onmousedown":
      case "onmouseup":
      case "onmouseover":
      case "onmousemove":
      case "onmouseout":
      case "onkeypress":
      case "onkeydown":
      case "onkeyup":
      case "onload":
      case "onlosecapture":
      case "onpropertychange":
      case "onreadystatechange":
      case "onrowsdelete":
      case "onrowenter":
      case "onrowexit":
      case "onrowsinserted":
      case "onstart":
      case "onscroll":
      case "onbeforeeditfocus":
      case "onactivate":
      case "onbeforedeactivate":
      case "ondeactivate":
      case "type":
      case "codebase":
      case "id":
        ret.objAttrs[args[i]] = args[i+1];
        break;
      case "width":
      case "height":
      case "align":
      case "vspace": 
      case "hspace":
      case "class":
      case "title":
      case "accesskey":
      case "name":
      case "tabindex":
        ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
        break;
      default:
        ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
    }
  }
  ret.objAttrs["classid"] = classid;
  if (mimeType) ret.embedAttrs["type"] = mimeType;
  return ret;
}

	/**
	* Cross-browser event handling for IE5+,  NS6 and Mozilla
	* By Scott Andrew
	*
	*/
	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 {
		alert("Handler could not be removed");
	  }
	} 
	
	/**
	* Gets nearest parent (grandparent, etc.) with tagname pTagName
	*/
	function getParent(el, pTagName) {
		if (el == null) return null;
		else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase())	// Gecko bug, supposed to be uppercase
			return el;
		else
			return getParent(el.parentNode, pTagName);
	}
	
	
	
	/**
	* BEGIN TABLE SORTING FUNCTIONALITY
	*/
	
	var SORT_COLUMN_INDEX;
	
	/**
	* Goes through all document tables and calls ts_makeSortable
	* on any table with a class of "sortable".
	*/
	function sortables_init() {
		// Find all tables with class sortable and make them sortable
		if (!document.getElementsByTagName) return;
		tbls = document.getElementsByTagName("table");
		for (ti=0;ti<tbls.length;ti++) {
			thisTbl = tbls[ti];
			if (((' '+thisTbl.className+' ').indexOf("sortable") != -1) && (thisTbl.id)) {
				//initTable(thisTbl.id);
				ts_makeSortable(thisTbl);
			}
		}
	}
	
	/**
	* Adds events and styles to handle sorting behavior.
	*/
	function ts_makeSortable(table) {
		if (table.rows && table.rows.length > 0) {
			var firstRow = table.rows[0];
		}
		if (!firstRow) return;
		
		// We have a first row: assume it's the header, and make its contents clickable links
		for (var i=0;i<firstRow.cells.length;i++) {
			var cell = firstRow.cells[i];
			if (cell.className.indexOf("sortable") < 0) {
				continue;
			}
			var txt = ts_getInnerText(cell);
			cell.innerHTML = '<a href="#" class="sortheader" '+ 
			'onclick="ts_resortTable(this, '+i+');stripe();return false;">' + 
			txt+'<span class="sortarrow">&nbsp;&nbsp;&nbsp;</span></a>';
		}
	}
	
	/**
	* Returns the inner text of an element.
	*/
	function ts_getInnerText(el) {
		if (typeof el == "string") return el;
		if (typeof el == "undefined") { return el };
		if (el.innerText) return el.innerText;	//Not needed but it is faster
		var str = "";
		
		var cs = el.childNodes;
		var l = cs.length;
		for (var i = 0; i < l; i++) {
			switch (cs[i].nodeType) {
				case 1: //ELEMENT_NODE
					str += ts_getInnerText(cs[i]);
					break;
				case 3:	//TEXT_NODE
					str += cs[i].nodeValue;
					break;
			}
		}
		return str;
	}
	
	
	/**
	* Calls a sort function a table column for each table body.
	*/
	function ts_resortTable(lnk,clid) {
		// get the span
		var span;
		for (var ci=0;ci<lnk.childNodes.length;ci++) {
			if (lnk.childNodes[ci].tagName && lnk.childNodes[ci].tagName.toLowerCase() == 'span') {
				span = lnk.childNodes[ci];
			}
		}
		
		var spantext = ts_getInnerText(span);
		var td = lnk.parentNode;
		var column = clid || td.cellIndex;
		var table = getParent(td,'table');
		
		// Work out a type for the column
		if (table.rows.length <= 1) return;
		var itm = ts_getInnerText(table.rows[1].cells[column]);
		sortfn = ts_sort_caseinsensitive;
	
		//ts_sort_date currently only handles these two formats
		if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/)) sortfn = ts_sort_date;
		if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d$/)) sortfn = ts_sort_date;
		
		if (itm.match(/^[£$]/)) sortfn = ts_sort_currency;
		if (itm.match(/^[\d\.]+$/)) sortfn = ts_sort_numeric;
		if (itm.match(/^(-)?[\d\.]+$/)) sortfn = ts_sort_numeric;
		if (itm.match(/^(-)?(\d{1,3}\,)*(\d{1,3})+\.?\d*$/)) sortfn = ts_sort_numeric;		

		
		SORT_COLUMN_INDEX = column;
		
		
		var tbodies = table.getElementsByTagName("tbody");
		for (var h = 0; h < tbodies.length; h++) {
			var tableBody = tbodies[h];
			var newRows = new Array();
			
		
			var trs = tableBody.getElementsByTagName("tr");
	
			for (var i = 0; i < trs.length; i++) {
				newRows[i] = trs[i]; 
			}
			newRows.sort(sortfn);
	
	
			if (span.getAttribute("sortdir") == 'down') {
				newRows.reverse();
			}
			
			// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
			// don't do sortbottom rows
			for (var i=0;i<newRows.length;i++) { 
				if (!newRows[i].className || (newRows[i].className && (newRows[i].className.indexOf('sortbottom') == -1))) {
					tableBody.appendChild(newRows[i]);
				}
			}
		
			// do sortbottom rows only
			for (var i=0;i<newRows.length;i++) { 
				if (newRows[i].className && (newRows[i].className.indexOf('sortbottom') != -1)) { 
					tableBody.appendChild(newRows[i]);
				}
			}
	
	
		}

	
		if (span.getAttribute("sortdir") == 'down') {
			ARROW = '&nbsp;&nbsp;&uarr;';
			span.setAttribute('sortdir','up');
		} else {
			ARROW = '&nbsp;&nbsp;&darr;';
			span.setAttribute('sortdir','down');
		}
		
		// Delete any other arrows there may be showing
		var allspans = document.getElementsByTagName("span");
		for (var ci=0;ci<allspans.length;ci++) {
			if (allspans[ci].className == 'sortarrow') {
				if (getParent(allspans[ci],"table") == getParent(lnk,"table")) { // in the same table as us?
					allspans[ci].innerHTML = '&nbsp;&nbsp;&nbsp;';
				}
			}
		}
			
		span.innerHTML = ARROW;
	}
	
	
	/**
	* Sorts strings as dates.
	*/
	function ts_sort_date(a,b) {
		// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
		aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);
		bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);
		if (aa.length == 10) {
			dt1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);
		} else {
			yr = aa.substr(6,2);
			if (parseInt(yr) < 50) { yr = '20'+yr; } else { yr = '19'+yr; }
			dt1 = yr+aa.substr(3,2)+aa.substr(0,2);
		}
		if (bb.length == 10) {
			dt2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2);
		} else {
			yr = bb.substr(6,2);
			if (parseInt(yr) < 50) { yr = '20'+yr; } else { yr = '19'+yr; }
			dt2 = yr+bb.substr(3,2)+bb.substr(0,2);
		}
		if (dt1==dt2) return 0;
		if (dt1<dt2) return -1;
		return 1;
	}
	
	/**
	* Sorts strings as an amount of currency.
	*/
	function ts_sort_currency(a,b) { 
		aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');
		bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');
		return parseFloat(aa) - parseFloat(bb);
	}
	
	/**
	* Sorts strings numerically.
	*/
	function ts_sort_numeric(a,b) { 
		aa = parseFloat(ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).replace(/\,/g,''));
		if (isNaN(aa)) aa = 0;
		bb = parseFloat(ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).replace(/\,/g,'')); 
		if (isNaN(bb)) bb = 0;
		return aa-bb;
	}
	
	/**
	* Sorts strings case insensitively.
	*/
	function ts_sort_caseinsensitive(a,b) {
		aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).toLowerCase();
		bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).toLowerCase();
		if (aa==bb) return 0;
		if (aa<bb) return -1;
		return 1;
	}
	
	/**
	* Sorts strings by the default sort behavior.
	*/
	function ts_sort_default(a,b) {
		aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);
		bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);
		if (aa==bb) return 0;
		if (aa<bb) return -1;
		return 1;
	}



	/**
	* BEGIN ZEBRA STRIPING AND SELECTION/SUBMISSION CODE
	*/


	/**
	* Performs a "zebra striping" of all tables with the class name of "striped".
	*/
	var stripe = function() {
		var tables = document.getElementsByTagName("table");	

		for(var x=0;x!=tables.length;x++){
			var table = tables[x];
			if (! table) { return; }
			
			if (table.className.indexOf("striped") < 0) {
				continue;
			}
			
			var tbodies = table.getElementsByTagName("tbody");
			var even = true;
			for (var h = 0; h < tbodies.length; h++) {
				
				var trs = tbodies[h].getElementsByTagName("tr");
						
				
				for (var i = 0; i < trs.length; i++) {
					if(even) {
						if (trs[i].className.indexOf("even") < 0) {
							trs[i].className += " even";
						}
					}
					else {
						trs[i].className = trs[i].className.replace("even", "");
					}
					
					even = !even;
				}
			}
		}
	}
	
	
	/**
	* Gets all rows within the table body of a table with class name "selectable"
	* and allows them to be selected.  They highlight on mouseover and are selected on click.
	*
	* Since these rows are selectable, the function also tries to make the table
	* submittable.
	* SEE: makeTableSubmittable(table);
	*/
	var makeSelectable = function() {
		var tables = document.getElementsByTagName("table");	



		for(var x=0;x!=tables.length;x++){
			var table = tables[x];
			if (! table) { return; }
	
			hideElements(table.getElementsByTagName("td"));			
	
			if (table.className.indexOf("selectable") < 0) {
				continue;
			}
			
			var tbodies = table.getElementsByTagName("tbody");
			
			for (var h = 0; h < tbodies.length; h++) {

				var trs = tbodies[h].getElementsByTagName("tr");
				
				for (var i = 0; i < trs.length; i++) {
					if (trs[i].className.indexOf("disabled") >= 0) {
						//disableChildCheckBoxes(this);
						continue;
					}
				
							
					if(isChecked(trs[i])) {
						if (trs[i].className.indexOf("selected") < 0) {
							trs[i].className += " selected";
						}
					}
				
					trs[i].onmouseover=function(){
						this.className += " ruled"; return false
					}
					trs[i].onmouseout=function(){
						this.className = this.className.replace("ruled", ""); return false
					}

					trs[i].onclick=function(){
						if (this.className.indexOf("selected") < 0) {
							this.className += " selected";
							checkChildCheckboxes(this, true);
							return true;	
						}
						else {
							this.className = this.className.replace("selected", ""); 
							checkChildCheckboxes(this, false);
							return true;
						}
					}					

				}
			}

			makeTableSubmittable(table);

		}
	}


	
	/**
	* Takes a list of elements and an optional input type (for 'input' elements)
	* and sets their display to none.  If the inputType parameter is set, then it
	* will check to make sure that the type matches.
	*/
	var hideElements = function(els, inputType) {
		for (var i=0; i<els.length; i++) {
			var isRightType = true;
			if (inputType != 'undefined' && els[i].type != inputType) {
				isRightType = false;
			}
			if (isRightType && els[i].className.indexOf("hideme") >= 0) {
				els[i].style.display = 'none';
			}
		}
	}
	
	
	/**
	* Searches the element passed in (a tr in our case) for any child input elements 
	* which are checkboxes.  If it finds one that is checked, it returns true.
	*/
	var isChecked = function(el) {
		var inpts = el.getElementsByTagName("input");
		for (var n=0; n<inpts.length; n++) {
			if (inpts[n].getAttribute("type") == "checkbox") {
				return (inpts[n].checked);
			}
		}
		return false;
	}
	
	
	/**
	* Gets all checkboxes which are a child of the element passed in and sets
	* their "checked" value to the parameter chk.
	*/
	var checkChildCheckboxes = function(el, chk) {
		var inpts = el.getElementsByTagName("input");
		for (var n=0; n<inpts.length; n++) {
			if (inpts[n].getAttribute("type") == "checkbox") {
				inpts[n].checked = chk;
			}
		}
	}
	

	/**
	* Gets forms within the table passed in.
	* Makes any button with a class of "select_all" highlight all rows.
	* Makes any button with a class of "select_none" unhighlight all rows.
	*
	* SEE: selectAllRows(table, highlight);
	*/
	var makeTableSubmittable = function(table) {

		var inputs = table.getElementsByTagName("input");
		for (var h = 0; h < inputs.length; h++) {
			if (inputs[h].type == "button") {
				if (inputs[h].className.indexOf("select_all") >= 0) {
					inputs[h].onclick = function() {selectAllRows(table, true);}
				}
				if (inputs[h].className.indexOf("select_none") >= 0) {
					inputs[h].onclick = function() {selectAllRows(table, false);}
				}				
			}
		}
	}



	/**
	* Will select or deselect all of the rows in the table specified.
	*
	*/
	var selectAllRows = function(table, highlight) { 

			if (! table) { return; }
			
			if (table.className.indexOf("striped") < 0) {
				return;
			}
			
			var tbodies = table.getElementsByTagName("tbody");
			
			for (var h = 0; h < tbodies.length; h++) {
				var trs = tbodies[h].getElementsByTagName("tr");
					for (var i = 0; i < trs.length; i++) {
					
						if (trs[i].className.indexOf("disabled") >= 0) {
							continue;
						}

						if (highlight) {
								if (trs[i].className.indexOf("selected") < 0) {
									trs[i].onclick();
								}
						}
						else {
								if (trs[i].className.indexOf("selected") >= 0) {
									trs[i].onclick();
								}
						}
					}
			}			
	}




addEvent(window, "load", sortables_init);
addEvent(window, "load", stripe);
addEvent(window, "load", makeSelectable);
