// create the html string - easy to do this way instead of one big string
var menuTemplate = new Ext.XTemplate(
	'<div class="{className}">', 
	'  <table cellspacing="0" cellpadding="0" class="menuBox">', 
	'    <tbody>', 
	'        <tr>', 
	'            <td class="menuBoxHeader" colspan="3"></td>', 
	'		 </tr>', 
	'        <tr>', 
	'            <td class="menuBoxBody" colspan="3">', 
	'                <ul>', 
	'                <tpl for="data">', 
	'                    <li>',
    '                       {[this.getLine(values)]}', 	
	'                    </li>', 
	'                </tpl>', 
	'                </ul>', 
	'            </td>', 
	'        </tr>', 
	'        <tr>',
        '          <td>',
	'           <table width="100%" border="0" cellspacing="0" cellpadding="0">',
        '              <tr>',
        '                <td class="menuBoxFootLeft"></td>',
        '                <td class="menuBoxFootCenter fontTenPixels" >&nbsp;</td>',
        '                <td class="menuBoxFootRight"></td>',
        '              </tr>',
        '             </table>',
        '         </td>',
	'        </tr>', 
	'    </tbody>', 
	'  </table>', 
	'</div>', 
	{
		// this will create the image, the text and the link in the correct order, depending on what the status is.
		getLine : function (values) {
			var line = "";
			var img = '<img width="35" height="30" align="absmiddle" src="' + (values.imgSrc == "" ? Ext.BLANK_IMAGE_URL : values.imgSrc) + '" />';
			var text = "<span>" + values.text + "</span>";
			
			// start url - add any attributes that were part of the option tag
			var url = '<a href="#null" value="' + values.value + '"';
			if (values.attributes instanceof Object) {
				// set the A tag attributes based on what's in the object
				for (var prop in values.attributes) {
					url = url + ' ' + prop + '="' + values.attributes[prop] + '"';
				}
			}
			url += '>';
			
			if (values.imgSrc != "" && values.value != "")
				// there's a real image source AND there's a value for the onclick.  wrap the image in the link value
				line = url + img + text +  "</a>";
			else if (values.imgSrc == "" && values.value != "")
				// no image source, but there's a value for onclick, so only wrap text in the link
				line = img + url + text +  "</a>";
			else
				// no link, so no url
				line = img + text;

			return line;
		}
	}
); 

// this holds the ids of the menus that live on this page.  used for "hidemenus" code
var menus = new Array();
// track the desired styles as an object so that we can add styles as needed without
var menuStyles = new Object();

Ext.onReady(function() {
	// create a button in place of the "select" box where there is an attribute of "ims_menu=true"
	var hasMenus = false;
	
	var selects = document.getElementsByTagName("select");
	for (var x = 0 ; x < selects.length ; x++) {
		var menu = selects[x].getAttribute("menu");
		if (menu) {
			if (menu == "1" || menu.substring(0, 1) == "t" || menu.substring(0, 1) == "y") {
				hasMenus = true;
				// found - do the replacement
				// strip out the text from the select
				var templateValues = menuGetTemplateValues(selects[x]);
				menuCreate(selects[x], templateValues);
			}
		}
	}

	// add "click" event to close the popupWindow whenever the user clicks anywhere on screen when the popup is active
	if (hasMenus) {
		Ext.getDoc().on("click", menuHidePopups);
		
		// hide menus on a resize event
		if (typeof window.onresize != "function") {
			// no onresize = create anew
			window.onresize = menuHidePopups;
		} else {
			var oldonresize = window.onresize;
			window.onresize = function() {
				oldonresize();
				menuHidePopups();
			}
		}
		
		// load the necessary stylesheets
		// check to make sure they're not loaded yet
		var links = document.getElementsByTagName("link");
		for (var x = 0 ; x < links.length ; x++) {
			// check href against our href
			if (links[x].href) {
				var href = links[x].href;
				if (menuStyles[href.toLowerCase()]) {
					// found in our to-be-loaded list, which means that it's already loaded
					// remove from our list
					delete menuStyles[href.toLowerCase()];
				}
			}
		}
		// now load our remaining style href, as those are the ones that aren't currently loaded
		for (var prop in menuStyles) {
			loadMenuCss(menuStyles[prop]);
		}

	}
	
});

function menuHidePopups() {
	for (var x = 0 ; x < menus.length ; x++) {
		var el = Ext.get(menus[x]);
		
		if (el.isVisible()) 
			el.hide();
			el.setDisplayed('none');
			var oSelect = Ext.DomQuery.selectNode("select[name=state]");
			if (oSelect) {
    	    	var selEl = Ext.get(oSelect);
    	    	selEl.show();
    	    }
	}
}

/** parse the options and optgroups within the select and return an same-sized array of object values that contain what we're after */
function menuGetTemplateValues(select) {
	var values = new Array();
	// get all subelements under the select
	var options = select.getElementsByTagName("*");
	for (var x = 0 ; x < options.length ; x++) {
		// only get option and optgroup elements
		if (options[x].tagName.toUpperCase() != "OPTION" && options[x].tagName.toUpperCase() != "OPTGROUP")
			continue;
		
		// imgSrc = the image src
		var obj = {imgSrc:"", text: "", value: "", attributes: undefined};

		// only get options that have a value
		if (options[x].tagName.toUpperCase() == "OPTION") {
			if (options[x].value == "")
				continue;
		
			// for option tags, get the value
			obj.value = options[x].value;
			options[x].removeAttribute("value");
		}
		
		if (options[x].label) {
			// label - mostly optgroup, but valid for option as weell
			obj.text = options[x].label;
			options[x].removeAttribute("label");
		} else {
			// text
			obj.text = options[x].innerHTML;
		}

		// look for specific attributes
		if (options[x].getAttribute("menuImageSrc")) {
			obj.imgSrc = options[x].getAttribute("menuImageSrc");
			options[x].removeAttribute("menuImageSrc");
		}
		
		// get non-specific attributes
		if (options[x].attributes.length > 0) {
			var attributeObject = new Object();
			for (var y = 0 ; y < options[x].attributes.length ; y++) {
				// attrs is a namednodemap
				var attribute = options[x].attributes.item(y);
				if (attribute.nodeValue)
					attributeObject[attribute.nodeName] = attribute.nodeValue;
			}
			obj.attributes = attributeObject;
		}
		
		// push onto stack
		values.push(obj);
	}
	
	return values;
}

function menuCreate(select, values) {
	// create new div to hold the new trigger/menu element
	var div = document.createElement("div");
	// insert new div BEFORE the select
	select.parentNode.insertBefore(div, select);
	
	// get the onchange attribute as a string, not an event
	var js_onchange = select.getAttributeNode("onchange").value;
	
	// now get the select sizes
	var selEl = Ext.get(select);
	var s = {
		width     : selEl.getWidth(), 
		bottom    : selEl.getBottom(), 
		right     : selEl.getRight(), 
		menuwidth : selEl.getWidth(), 
		className : ""
	};
	
	// look for width setting in select.  if so, then adjust menuwidth to that.
	if (select.getAttribute("menuWidth"))
		s.menuwidth = parseInt(select.getAttribute("menuWidth"));

	// add the class
	if (select.getAttribute("menuClass"))
		s.className = select.getAttribute("menuClass");

	// pick up any additional style sheets
	if (select.getAttribute("menuCssHref"))
		// convert property to lowercase so that we don't have to deal with mixed case strings, but keep the value as it was originally entered
		menuStyles[select.getAttribute("menuCssHref").toLowerCase()] = select.getAttribute("menuCssHref");
	else
		// add our default, so there's at least the one.
		menuStyles["/css/menu.css"] = "/css/menu.css";

	// remove the select
	select = select.parentNode.removeChild(select);

	// create trigger, and put it into the div created above
	var trigger = new Ext.form.TriggerField(
		{
			readOnly: true, 
			value: select.options[0].innerHTML,
			width: s.width,
			focusClass: "", 
			style: "cursor:pointer;", 
			renderTo : div
		}
	);
	// create onclick to the div that is the parent of the trigger.  this is NOT the div we created above, but the div that is part of the trigger UI
	//trigger.getEl().dom.parentNode.onclick = function(e) {
	Ext.EventManager.on(trigger.getEl().dom.parentNode, 'click', 
		function(e) {
	    	var selEl2 = Ext.get(Ext.DomQuery.selectNode("select[name=state]"));
		    // t = the triggerfields
			if (layerEl.isVisible()) {
				layerEl.hide();
				layerEl.setDisplayed('none');
				if (selEl2) selEl2.show();
			} else {
				// adjust the left side - this handles the scrollbar shifting the trigger to the left/right
				var t = Ext.get(trigger.getId());
    			if (selEl2) selEl2.hide();
				layerEl.show();
				// the triggerfield is a field contained within a div.  we want the right position of the div, so get the parent
				layerEl.setX(t.findParentNode("div", 1, true).getRight() - layerEl.getWidth());
				layerEl.setY(t.getBottom());
			}
			e.stopEvent();
		});

	// insert into doc and hide, el is an Ext.Element
	//var el = menuTemplate.insertFirst(Ext.getBody(), {className: s.className, data: values}, true);
	//layerEl.setVisibilityMode(Element.DISPLAY);
	//layerEl.hide();

    var layerEl = new Ext.Layer({shim:false});

    var menuEl = menuTemplate.insertFirst(layerEl,{className: s.className,data:values}, true);
    //layerEl.setX(Ext.get(selEl.findParentNode("div")).getRight()-menuEl.getComputedWidth());
    //layerEl.setY(selEl.getBottom());
	//layerEl.setVisibilityMode(Ext.Element.DISPLAY);
	//menuEl.hide();

	// add the js_onchange event call to the a tags
	var arrayOfA = layerEl.query("A");
	for (var x = 0 ; x < arrayOfA.length ; x++) {
	    //console.log(js_onchange);
		arrayOfA[x].onclick = new Function("event", js_onchange);
		//Ext.get(arrayOfA[x]).on("click",new Function("event",js_onchange));
		// set value as the direct property
		arrayOfA[x].value = arrayOfA[x].getAttribute("value");
	}
	
	// set size and position - and we're done!
	layerEl.setWidth(s.menuwidth);
	layerEl.position("absolute", 100, s.right - s.menuwidth, s.bottom);
	
	// save menu id - this is for menuHidePopup
	menus.push(layerEl);
	
}

function loadMenuCss(strHref) {
	var oLink  = document.createElement("link");
	oLink.rel  = "stylesheet";
	oLink.type = "text/css";
	oLink.href = strHref;
	// add to header
	document.getElementsByTagName("head")[0].appendChild(oLink)
}

