// ////////////////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////////////////
//
// SELECT BOX REPLACE v1.0
//
// Written by: Ara Pehlivanian
// Completed: January 14, 2005
//
// Instructions:
//		Place this script in your document head and then specify an array of SELECT BOX IDs in 
//		your body's onload like so: <body onload="sBR(['id1', 'id2', 'idn'])">
//
// ////////////////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////////////////




// Objects
var oSelectBox;
var oClosedSBR;
var oClosedSBRAnchor;
var oDownArrowAnchor
var oOpenedSBRTable;
var oOpenedSBRContainer;
var object;

// IDs
var idClosedSBRAnchor;
var idClosedSBR;
var idDownArrowAnchor;
var idOpenedSBR;
var idOpenedSBRContainer;

// Classes
var classDownArrowAnchor = "sBRDownArrowAnchor";
var classDownArrowAnchorClicked = "sBRDownArrowAnchorClicked"; // it is necessary to have the word "Clicked" attached here as it is manipulated programatically in the toggleArrowImage() function.
var classOpenedSBRContainer = "sBROpenedContainer";
var classClosedSBR = "sBRClosed";

// Constants
// These are base strings for id building
var CLOSED_SBR_ANCHOR = "closedSBRAnchor_";
var CLOSED_SBR = "closedSBR_";
var DOWN_ARROW_ANCHOR = "downArrowAnchor_";
var OPENED_SBR = "openedSBR_";
var OPENED_SBR_CONTAINER = "openedSBRContainer_";





function sBR(IDs)
{
	if ( !( ( checkPlatform("msie") || checkPlatform("safari") ) && checkPlatform("mac") ) )
	{
		for ( var i = 0; i < IDs.length; i++ )
		{
			selectBoxReplace(IDs[i]);
		}
	}
}




function selectBoxReplace(selectBoxId)
{
	// //////////////////////////////////////////////////////////////////////////
	// Grab Select Box in question
	// //////////////////////////////////////////////////////////////////////////
		oSelectBox = document.getElementById(selectBoxId);
		setIDs(oSelectBox.id); // oSelectBox must be set in order for this to work


	// //////////////////////////////////////////////////////////////////////////
	// Read contents of select box into 2D array "arrOptions"
	// //////////////////////////////////////////////////////////////////////////
		var arrOptions = new Array(oSelectBox.options.length);
				for ( var i = 0; i < oSelectBox.options.length; i++ )
				{
					arrOptions[i] = new Array(2);
					arrOptions[i][0] = oSelectBox.options[i].text;
					arrOptions[i][1] = oSelectBox.options[i].value;
				}


	// //////////////////////////////////////////////////////////////////////////
	// Create DIV representing Closed Select Box
	// //////////////////////////////////////////////////////////////////////////
				oClosedSBRAnchor = document.createElement("a");
				oClosedSBRAnchor.id = idClosedSBRAnchor;
				oClosedSBRAnchor.innerHTML = arrOptions[0][0];
				oClosedSBRAnchor.onclick = sBRAnchorClick;

			//oClosedSBR.onfocus = oSelectBox.getAttribute("onfocus");
				oClosedSBR = document.createElement("div");
				oClosedSBR.id = idClosedSBR;
				oClosedSBR.className = classClosedSBR;
			//oClosedSBR.style.position = "absolute";
			//oClosedSBR.style.left = oSelectBox.offsetLeft.toString() + "px";
			//oClosedSBR.style.top = oSelectBox.offsetTop.toString() + "px";
				oClosedSBR.style.width = oSelectBox.offsetWidth.toString() + "px";
				
				oClosedSBR.style.left = getTrueOffsets(oSelectBox, new trueOffsets()).Left;
				oClosedSBR.style.top = getTrueOffsets(oSelectBox, new trueOffsets()).Top;

				oClosedSBR.appendChild(oClosedSBRAnchor);


	// //////////////////////////////////////////////////////////////////////////
	// Create and append Anchor for Down Arrow
	// //////////////////////////////////////////////////////////////////////////
				oDownArrowAnchor = document.createElement("a");
				oDownArrowAnchor.id = idDownArrowAnchor;
				oDownArrowAnchor.innerHTML = "&gt;";
				oDownArrowAnchor.className = classDownArrowAnchor;
				oDownArrowAnchor.onclick = sBRAnchorClick;

				oClosedSBR.appendChild(oDownArrowAnchor);
				oSelectBox.parentNode.insertBefore(oClosedSBR, oSelectBox);
				//document.body.insertBefore(oClosedSBR, document.body.firstChild);
				
				oDownArrowAnchor.style.position = "absolute";
				oDownArrowAnchor.style.left = ( getTrueOffsets(oClosedSBR, new trueOffsets()).Left + oClosedSBR.offsetWidth - oDownArrowAnchor.offsetWidth ).toString() + "px";
				oDownArrowAnchor.style.top = ( getTrueOffsets(oClosedSBR, new trueOffsets()).Top + ( ( oClosedSBR.offsetHeight - oDownArrowAnchor.offsetHeight ) / 2 ) ).toString() + "px";
				oDownArrowAnchor.style.zIndex = 10000;

				//alert(oDownArrowAnchor.style.left + "/"+ oDownArrowAnchor.style.top);
				//alert(getTrueOffsets(oClosedSBR, new trueOffsets()).Debug);


	// //////////////////////////////////////////////////////////////////////////
	// Create Container DIV for and TABLE representing Select Box Options
	// //////////////////////////////////////////////////////////////////////////
				oOpenedSBRTable = document.createElement("table");
				oOpenedSBRTable.id = idOpenedSBR;

				for ( var i = 0; i < arrOptions.length; i++ )
				{
					var oRow = oOpenedSBRTable.insertRow(i);
					var oCell = oRow.insertCell(0);
					oCell.innerHTML = arrOptions[i][0];
					
					oCell.onclick = sBROptionClick;
					oCell.onmouseover = function () {this.className = "sBROver";}
					oCell.onmouseout = function () {this.className = "sBROut";}
				}

				oOpenedSBRContainer = document.createElement("div");
				oOpenedSBRContainer.id = idOpenedSBRContainer;
				oOpenedSBRContainer.className = classOpenedSBRContainer;
				oOpenedSBRContainer.style.position = "absolute";
				oOpenedSBRContainer.style.width = oClosedSBR.offsetWidth.toString() + "px";
				oOpenedSBRContainer.style.display = "none";

				oOpenedSBRContainer.appendChild(oOpenedSBRTable);
				oSelectBox.parentNode.insertBefore(oOpenedSBRContainer, oSelectBox);


	// //////////////////////////////////////////////////////////////////////////
	// Turn off Select Box
	// //////////////////////////////////////////////////////////////////////////
		oSelectBox.style.display = "none";
}




function sBRAnchorClick(e)
{
	// Cross browser event handling for source element
	if ( !e ) var e = window.event;
	setCurrentObjects(e);

	toggleArrowImage(e);
	toggleOptions(e);
	if ( oSelectBox.getAttribute("onclick") ) oSelectBox.onclick();
}




function sBROptionClick(e)
{
	// Cross browser event handling for source element
	if ( !e ) var e = window.event;
	setCurrentObjects(e);
	
	// Find clicked Cell & Row in oOpenedSBRTable
	var srcEl;
	if ( e.srcElement ) srcEl = e.srcElement;
	else if ( e.target ) srcEl = e.target;
	if( e.nodeType == 3 ) srcEl = srcEl.parentNode;

	srcEl.className = "sBROut"; // reset hover highlight
	oSelectBox.selectedIndex = srcEl.parentNode.rowIndex;
	if ( oSelectBox.getAttribute("onChange") ) oSelectBox.onchange();

	oClosedSBRAnchor.innerHTML = srcEl.innerHTML;

	toggleArrowImage(e);
	toggleOptions(e);
}




function toggleArrowImage(e)
{
	// Cross browser event handling for source element
	if ( !e ) var e = window.event;

	// Note: the parent event (either sBRAnchorClick or sBROptionClick has already set the current objects)
	if ( oDownArrowAnchor.className.lastIndexOf("Clicked") == -1 )
		oDownArrowAnchor.className += "Clicked";
	else
		oDownArrowAnchor.className = oDownArrowAnchor.className.substring(0, oDownArrowAnchor.className.lastIndexOf("Clicked"));
}




function toggleOptions(e)
{
	// //////////////////////////////////////////////////////////////////////////
	// Activate Select Box Replacement Options
	// //////////////////////////////////////////////////////////////////////////
		if ( !oOpenedSBRContainer.style.display || oOpenedSBRContainer.style.display == "none" )
		{
			oOpenedSBRContainer.style.display = "block"; // NOTE: It's a bit of a pain but calculations using the oOpenedSBRContainer object cannot be performed while it is hidden. :-(
			oOpenedSBRContainer.style.zIndex++;
			var intOffsetBottom = oOpenedSBRContainer.offsetTop + oOpenedSBRContainer.offsetHeight; // The bottom most pixel of Options when visible
			var intTopYCoord = getTrueOffsets(oClosedSBR, new trueOffsets()).Top - oOpenedSBRContainer.offsetHeight // The Y coord if we display Options on top of SBR
			var intBottomYCoord = getTrueOffsets(oClosedSBR, new trueOffsets()).Top + oClosedSBR.offsetHeight // The Y coord if we display Options below SBR
			if ( intOffsetBottom > document.body.clientHeight && intTopYCoord >= 0 )
			{
				oOpenedSBRContainer.style.top = intTopYCoord;
			}
			else
			{
				oOpenedSBRContainer.style.top = intBottomYCoord;
			}
			oOpenedSBRContainer.style.left = getTrueOffsets(oClosedSBR, new trueOffsets()).Left.toString() + "px";
		}
		else
		{
			oOpenedSBRContainer.style.display = "none";
		}
}




function setCurrentObjects(e)
{
	// Determine which selectbox we're in
	var srcEl;
	if ( e.srcElement ) srcEl = e.srcElement;
	else if ( e.target ) srcEl = e.target;
	if ( srcEl.nodeType == 3 ) srcEl = srcEl.parentNode; // Safari fix
	
	// oSelectBox
	var tmpId = srcEl.id; // try three times because you may be in a table cell
	if ( !tmpId ) tmpId = srcEl.parentNode.id;
	if ( !tmpId ) tmpId = srcEl.parentNode.parentNode.id;
	if ( !tmpId ) tmpId = srcEl.parentNode.parentNode.parentNode.id;
	var tmpSelectBoxId = tmpId.substring( tmpId.lastIndexOf("_") + 1, tmpId.length );
			oSelectBox = document.getElementById(tmpSelectBoxId);

	// Set IDs relative to current select box
	setIDs(oSelectBox.id);

	// Go grab all objects based on IDs
	oClosedSBR = document.getElementById(idClosedSBR);
	oClosedSBRAnchor = document.getElementById(idClosedSBRAnchor);
	oDownArrowAnchor = document.getElementById(idDownArrowAnchor);
	oOpenedSBRTable = document.getElementById(idOpenedSBR);
	oOpenedSBRContainer = document.getElementById(idOpenedSBRContainer);
}




function setIDs(selectBoxId)
{
	idClosedSBRAnchor = CLOSED_SBR_ANCHOR + selectBoxId;
	idClosedSBR = CLOSED_SBR + selectBoxId;
	idDownArrowAnchor = OPENED_SBR + selectBoxId;
	idOpenedSBR = OPENED_SBR + selectBoxId;
	idOpenedSBRContainer = OPENED_SBR_CONTAINER + selectBoxId;
}




function trueOffsets()
{
	this.Left = 0;
	this.Top = 0;
	this.Debug = "";
}


function getTrueOffsets(object, trueOffsets)
{
	if ( object.offsetParent ){
		trueOffsets.Left += object.offsetLeft;
		trueOffsets.Top += object.offsetTop;
		trueOffsets.Debug = object.nodeName + "[" + object.id + "] (offsetParent: " + object.offsetParent.nodeName + " [" + object.offsetParent + "], offsetLeft: " + object.offsetLeft + ", offsetTop: " + object.offsetTop + ", nodeType: " + object.nodeType + ")" + "\n" + trueOffsets.Debug;
		return getTrueOffsets(object.offsetParent, trueOffsets);
	}
	else{
		return trueOffsets;
	}	
}




function checkPlatform(string)
{
	var nav = navigator.userAgent.toLowerCase();
	return ( nav.lastIndexOf(string) + 1 ) ? true : false
}