//document.write('<scr','ipt language="javascript" src="/inc/javascript/getElement.js" type="text\/javascript"><\/scr ','ipt>');
//document.write('<scr','ipt language="javascript" src="/inc/javascript/getControl.js" type="text\/javascript"><\/scr ','ipt>');
//document.write('<scr','ipt language="javascript" src="/inc/javascript/xml_util.js" type="text\/javascript"><\/scr ','ipt>');

var available_product_attributes_form;
var apaReq = new Array();
var apaDom;
var form_controls_xref = new Array();
var apaTimestamp = -1;
var apa_save_required = new Array();

function print_dom(dom)
{
var m = '';
var c = dom.childNodes;
for (var x=0;x<c.length;x++)
{
	m += c[x].nodeName+': ';
	var v = c[x].nodeValue;
	if (v)
		m += v+'\n';
	if (c[x].hasChildNodes)
		m += '\n'+print_dom(c[x]);
}
return m;
}

function in_array(v,arr)
{
	var len = arr.length;
	for (var i=0;v<len;v++)
	{
		if (v == arr[i])
			return true;
	}
	return false;
}

/*******************************************************************************
 * get_form_controls - put the form controls into a predictable look up
 *******************************************************************************/
function get_form_controls(form)
{
// Find out if we have form controls in the master array
	var form_name = form.name;
	if (!form_name)
		form_name = form.id;
	if (typeof form_controls_xref[form_name] != 'undefined')
		return form_controls_xref[form_name];

// Take only the attribute controls for easy lookup
	var form_controls = new Array();
    for (var i=0; i<form.elements.length; i++)
    {
        var ctl = form.elements[i];
        var name = ctl.name;
		if (!name)
			name = ctl.id;

	// Add to the array
		if (name.indexOf('[') < 0)
			name += '[]';
		var re = new RegExp(/^(\d+)\[(\d*)\]/);
		var matches = name.match(re);
		if (!matches)
			continue;
		var k = matches[1];
		var x = matches[2];
		if (typeof form_controls['a'+k] == 'undefined')
			form_controls['a'+k] = new Array();
		if (!x)
			x = form_controls['a'+k].length;
		form_controls['a'+k][x] = ctl;
    }
	form_controls_xref[form_name] = form_controls;
	return form_controls;
}

/*******************************************************************************
 * getAvailableProductAttributesRequestXML - Create an XML AvailableProductAttributesRequest string from the controls in the form
 *******************************************************************************/
function getAvailableProductAttributesRequestXML(form,attribute,callback)
{
	var xml = '';

// Start the request
	xml += '<'+"?xml version=\"1.0\" xml:lang=\"UTF-8\"?>\n";
	xml += "<maverick>\n";

// Start the request
	var t = new Date();
	apaTimestamp = t.getTime();
	xml += "<AvailableProductAttributesRequest name=\"req"+apaTimestamp+"\"";
	if (callback != null && callback != '')
		xml += " callback=\""+callback+"\"";
	if (attribute != null)
		xml += " attribute=\""+attribute+"\"";
	var dontDisable = document.getElementById('dontDisable');
	if (dontDisable && dontDisable.value != '')
		xml += ' dontDisable="true"';
	xml += ">\n";

// Add the quantity
	var qty = getControl(form,'qty');
	if (qty)
	{
		qty = qty.value;
		if (qty)
		{
			if (qty.indexOf('/'))
			{
				var tmp = qty.split('/');
				for (var n in tmp)
				{
					var q = tmp[n];
					if (!isNaN(q))
					{
						qty = q;
						break;
					}
				}
			}
			xml += "<Quantity>"+qty+"</Quantity>\n";
		}
	}

// Add the quantity
	var jobid = getControl(form,'jobid');
	if (jobid)
	{
		jobid = jobid.value;
		if (jobid)
			xml += "<JobId>"+jobid+"</JobId>\n";
	}

// Get the specs
	var job_attribute = getAttributesFromForm(form);

// Add the product
	xml += "<Product>"+job_attribute['product'][0]+"</Product>\n";

// Add the specs
	xml += getAttributeList(job_attribute);

// End request
	xml += "</AvailableProductAttributesRequest>\n";
	xml += "</maverick>\n";
//alert(xml);

	return xml;
}

/*******************************************************************************
 * updateAvailableProductAttributes - use XMLHttpRequest to get the available attributes and values for the product
 *******************************************************************************/
function updateAvailableProductAttributes(form)
{
	var xml_request = getAvailableProductAttributesRequestXML(form,null,null);
	var url = get_base_url()+'/xml/availableProductAttributes.php';
	available_product_attributes_form = form;
	var i = apaReq.length;
	if (window.XMLHttpRequest)
	{
	// Non-IE browsers
		apaReq[i] = new XMLHttpRequest();
		try {
			apaReq[i].onreadystatechange = processAvailableProductAttributes;
			apaReq[i].open("POST", url, true);
		} catch (e) {
			alert(e);
		}
		apaReq[i].setRequestHeader('Content-Type', 'text/xml');
		apaReq[i].send(xml_request);
	}
	else if (window.ActiveXObject)
	{
	// IE
		apaReq[i] = new ActiveXObject("Microsoft.XMLHTTP");
		if (apaReq[i])
		{
			apaReq[i].onreadystatechange = processAvailableProductAttributes;
			apaReq[i].open("POST", url, true);
			apaReq[i].setRequestHeader('Content-Type', 'text/xml');
			apaReq[i].send(xml_request);
		}
	}
}

/*******************************************************************************
 * updateAvailableProductAttributesRestricted - use XMLHttpRequest to get the available attributes and values for the product
 *******************************************************************************/
function updateAvailableProductAttributesRestricted(form,attributes)
{
	if (attributes == null)
	{
		updateAvailableProductAttributes(form);
		return;
	}
	for (var x in attributes)
	{
		var xml_request = getAvailableProductAttributesRequestXML(form,attributes[x],null);
		var url = get_base_url()+'/xml/availableProductAttributes.php';
		available_product_attributes_form = form;
		var i = apaReq.length;
		if (window.XMLHttpRequest)
		{
		// Non-IE browsers
			apaReq[i] = new XMLHttpRequest();
			try {
				apaReq[i].onreadystatechange = processAvailableProductAttributes;
				apaReq[i].open("POST", url, true);
			} catch (e) {
				alert(e);
			}
			apaReq[i].setRequestHeader('Content-Type', 'text/xml');
			apaReq[i].send(xml_request);
		}
		else if (window.ActiveXObject)
		{
		// IE
			apaReq[i] = new ActiveXObject("Microsoft.XMLHTTP");
			if (apaReq[i])
			{
				apaReq[i].onreadystatechange = processAvailableProductAttributes;
				apaReq[i].open("POST", url, true);
				apaReq[i].setRequestHeader('Content-Type', 'text/xml');
				apaReq[i].send(xml_request);
			}
		}
	}
}

/*******************************************************************************
 * updateAvailableProductAttributesWithCallback - use XMLHttpRequest to get the available attributes and values for the product
 *******************************************************************************/
function updateAvailableProductAttributesWithCallback(form,callback)
{
	var xml_request = getAvailableProductAttributesRequestXML(form,null,callback);
	var url = get_base_url()+'/xml/availableProductAttributes.php';
	available_product_attributes_form = form;
	var i = apaReq.length;
	if (window.XMLHttpRequest)
	{
	// Non-IE browsers
		apaReq[i] = new XMLHttpRequest();
		try {
			apaReq[i].onreadystatechange = processAvailableProductAttributes;
			apaReq[i].open("POST", url, true);
		} catch (e) {
			alert(e);
		}
		apaReq[i].setRequestHeader('Content-Type', 'text/xml');
		apaReq[i].send(xml_request);
	}
	else if (window.ActiveXObject)
	{
	// IE
		apaReq[i] = new ActiveXObject("Microsoft.XMLHTTP");
		if (apaReq[i])
		{
			apaReq[i].onreadystatechange = processAvailableProductAttributes;
			apaReq[i].open("POST", url, true);
			apaReq[i].setRequestHeader('Content-Type', 'text/xml');
			apaReq[i].send(xml_request);
		}
	}
}

/*******************************************************************************
 * updateAvailableProductAttributesRestrictedWithCallback - use XMLHttpRequest to get the available attributes and values for the product
 *******************************************************************************/
function updateAvailableProductAttributesRestrictedWithCallback(form,attributes,callback)
{
	if (attributes == null)
	{
		updateAvailableProductAttributesWithCallback(form,callback);
		return;
	}
	for (var x in attributes)
	{
		var xml_request = getAvailableProductAttributesRequestXML(form,attributes[x],callback);
		var url = get_base_url()+'/xml/availableProductAttributes.php';
		available_product_attributes_form = form;
		var i = apaReq.length;
		if (window.XMLHttpRequest)
		{
		// Non-IE browsers
			apaReq[i] = new XMLHttpRequest();
			try {
				apaReq[i].onreadystatechange = processAvailableProductAttributes;
				apaReq[i].open("POST", url, true);
			} catch (e) {
				alert(e);
			}
			apaReq[i].setRequestHeader('Content-Type', 'text/xml');
			apaReq[i].send(xml_request);
		}
		else if (window.ActiveXObject)
		{
		// IE
			apaReq[i] = new ActiveXObject("Microsoft.XMLHTTP");
			if (apaReq[i])
			{
				apaReq[i].onreadystatechange = processAvailableProductAttributes;
				apaReq[i].open("POST", url, true);
				apaReq[i].setRequestHeader('Content-Type', 'text/xml');
				apaReq[i].send(xml_request);
			}
		}
	}
}

/*******************************************************************************
 * updateAvailableProductAttributesRestrictedWithCallbacks - use XMLHttpRequest to get the available attributes and values for the product
 *******************************************************************************/
function updateAvailableProductAttributesRestrictedWithCallbacks(form,attributes)
{
	if (attributes == null)
	{
		updateAvailableProductAttributes(form);
		return;
	}
	for (var attribute in attributes)
	{
		var callback = attributes[attribute];
		var xml_request = getAvailableProductAttributesRequestXML(form,attribute,callback);
		var url = get_base_url()+'/xml/availableProductAttributes.php';
		available_product_attributes_form = form;
		var i = apaReq.length;
		if (window.XMLHttpRequest)
		{
		// Non-IE browsers
			apaReq[i] = new XMLHttpRequest();
			try {
				apaReq[i].onreadystatechange = processAvailableProductAttributes;

				apaReq[i].open("POST", url, true);
			} catch (e) {
				alert(e);
			}
			apaReq[i].setRequestHeader('Content-Type', 'text/xml');
			apaReq[i].send(xml_request);
		}
		else if (window.ActiveXObject)
		{
		// IE
			apaReq[i] = new ActiveXObject("Microsoft.XMLHTTP");
			if (apaReq[i])
			{
				apaReq[i].onreadystatechange = processAvailableProductAttributes;
				apaReq[i].open("POST", url, true);
				apaReq[i].setRequestHeader('Content-Type', 'text/xml');
				apaReq[i].send(xml_request);
			}
		}
	}
}

/*******************************************************************************
 * processAvailableProductAttributes - handle the response
 *******************************************************************************/
function processAvailableProductAttributes()
{
// Iterate over all of the requests in progress
	var length = apaReq.length;
	var processedChange = false;
	for (var ri=0;ri<length;ri++)
	{
	// Skip if there's no request or if it's  not ready
		if (apaReq[ri] == null || apaReq[ri].readyState != 4 || apaReq[ri].status != 200)
			continue;

	// Remove the request from the list
		var request = apaReq[ri];
		apaReq.splice(ri,1);

	// OK response
		if (typeof request.responseXML != 'undefined')
			apaDom = request.responseXML;
		else
			parseXMLIntoDOM(request.responseText);
//alert(request.responseText);
		if (!apaDom)
			continue;

	// Make sure the response isn't stale
		var maverick = apaDom.getElementsByTagName('maverick')[0];
		if (!maverick)
			continue;
		var response = maverick.getElementsByTagName('AvailableProductAttributesResponse')[0];
		if (!response)
			continue;
		var name = response.getAttribute('name');

	// Get the callback
		var callback = response.getAttribute('callback');
		if (callback != null && callback != '' && callback.value) callback = callback.value;

	// Look for errors
		var errors = response.getElementsByTagName('Error');
		if (errors && errors.length > 0)
		{
		// Try the backing store first
			if (typeof restore_from_backing_store != 'undefined')
			{
				alert(errors[0].firstChild.data);
				restore_from_backing_store(available_product_attributes_form);
				resubmit(callback);
				continue;
			}

		// No backing store; try disabling controls and resubmitting
			if (lookForResubmit(errors,callback))
				continue;
		}

	// Get the attribues
		var attributes = response.getElementsByTagName('Attribute');
		var restricted_attribute = response.getAttribute('attribute');
		if (name.substring(3,name.length) < apaTimestamp && restricted_attribute == null)
			continue;

	// Update controls
		var dontDisable = response.getAttribute('dontDisable');
		if (dontDisable != null && dontDisable != '' && dontDisable.value) dontDisable = dontDisable.value;
		performAvailableAttributeUpdate(available_product_attributes_form,restricted_attribute,attributes,callback,dontDisable);
		processedChange = true;
	}

// If anything changed and we're using backing store, refresh the backing store
	if (processedChange && document.backup_form)
		backup_form(available_product_attributes_form);

// If there are any more requests pending, reschedule this process
	if (apaReq.length > 0)
		setTimeout('processAvailableProductAttributes()',50);
}

function performAvailableAttributeUpdate(form,restricted_attribute,attributes,callback,dontDisable)
{
// Parse the attributes
	var parsed_attributes = parse_available_attributes(attributes);

// Iterate over all of the form's controls
//var msg = '';
	var has_changed = false;
	var form_controls = get_form_controls(form);
	var desc_updated = new Array();
	for (var n in form_controls)
	{
	// Get the control(s)
		var ctls = form_controls[n];
		var att = n.substring(1,n.length);
		if (n.charAt(0) != 'a' || isNaN(att) ||
			(restricted_attribute && restricted_attribute != att))
			continue;
		for (var i=0;i<ctls.length;i++)
		{
			var c = ctls[i];

		// Handle based on type
			var was_disabled = c.disabled;
			switch (c.type)
			{
			case 'select-one':
			case 'select':
			// If this is a required attribute and the control has a value, back up the value
				if (parsed_attributes[att] && 
					parsed_attributes[att].getElementsByTagName('Required') && 
					parsed_attributes[att].getElementsByTagName('Required').length > 0 && 
					c.value != '')
					apa_save_required[att] = c.value;
			case 'text':
			case 'hidden':
			case 'textarea':
			// Update the availablity
				c.disabled = (dontDisable) ? false : is_product_attribute_disabled(att,parsed_attributes);
				if (c.value != '' && was_disabled != c.disabled)
					has_changed = true;
				var label = document.getElementById('label'+att);
				if (label)
					label.style.color = (c.disabled) ? 'gray' : 'black';

			// If this is a menu, update the attribute values
				if (c.type == 'select-one' || c.type == 'select')
				{
					if (update_attribute_menu(att,parsed_attributes,c))
						has_changed = true;
				}
				else
				{
				// If this is a text or hidden field and there is an attribute value, set it
					if (typeof parsed_attributes[att] != 'undefined' && parsed_attributes[att].getElementsByTagName('Required').length > 0)
					{
						var attribute_values = parsed_attributes[att].getElementsByTagName('AttributeValue');
						if (attribute_values && attribute_values.length > 0)
						{
							var n1 = attribute_values[0];
							var av = n1.getAttribute('id');
							if (!av)
							{
								if (n1.firstChild)
									av = n1.firstChild.data;
							}
							if (c.value != av)
							{
								has_changed = true;
							}
							c.value = av;
						}
					}
				}

			// Get the default in case the original value isn't found
				var default_value = '';
				if (parsed_attributes[att])
				{
					default_value = parsed_attributes[att].getElementsByTagName('DefaultValue');
					if (default_value && default_value.length > 0)
						default_value = default_value[0].firstChild.data;
				}

			// If this is a menu and it's required, try to set the value to the last value
				if (typeof parsed_attributes[att] && 
					parsed_attributes[att] && 
					parsed_attributes[att].getElementsByTagName('Required') &&
					parsed_attributes[att].getElementsByTagName('Required').length > 0 && 
					(c.type == 'select-one' || c.type == 'select') && 
					((typeof apa_save_required[att] != 'undefined' && apa_save_required[att] != '') || default_value))
				{
				// Find the selection index
					var backupSelection = null;
					for (var x=0;x<c.options.length;x++)
					{
						var value = new String(c.options[x].value);
						if (value == apa_save_required[att])
						{
							c.selectedIndex = x;
							break;
						}
						else if (value == default_value)
						{
							backupSelection = x;
						}
					}

				// If the backup value wasn't found and there is a default, use the default
					if (c.options[c.selectedIndex].value != apa_save_required[att] && 
						backupSelection != null)
						c.selectedIndex = backupSelection;
				}
				break;
			case 'checkbox':
			case 'radio':
				c.disabled = (dontDisable) ? false : is_product_attribute_value_disabled(att,c.value,parsed_attributes);
				if (c.checked && was_disabled != c.disabled)
					has_changed = true;
				var labelid = 'label'+att+'_'+c.value;
				var label = document.getElementById(labelid);
				if (label)
					label.style.color = (c.disabled) ? 'gray' : 'black';
				break;
			}
//msg += att+'['+c.type+'/'+c.id+']: '+c.value+"\n";

		// Update the description if it exists
			if (!in_array(att,desc_updated))
			{
				var labeldesc = document.getElementById('label'+att+'desc');
				var labeldescbak = document.getElementById('label'+att+'descbak');
				if (labeldesc && labeldescbak && was_disabled != c.disabled)
				{
					labeldesc.style.color = (c.disabled) ? 'gray' : 'black';
					var tmp1Text = labeldesc.innerText;
					var tmp1HTML = labeldesc.innerHTML;
					var tmp2Text = labeldescbak.innerText;
					var tmp2HTML = labeldescbak.innerHTML;
					labeldesc.innerText = tmp2Text;
					labeldesc.innerHTML = tmp2HTML;
					labeldescbak.innerText = tmp1Text;
					labeldescbak.innerHTML = tmp1HTML;
				}
			}
		}
	}
//alert(request.responseText+'\n'+msg);

// If any controls changed, resubmit to see if other options change
	if (has_changed)
	{
	// Unlock to stop deadlock
		resubmit(callback);
		return;
	}

// If there's a callback specified, look for it and run it
	if (callback)
	{
	// Look for the function (defined outside of this file, of course)
		var callback_function = self[callback];
		if (callback_function)
			callback_function();
	}
}

function lookForResubmit(errors,callback)
{
// If it's a spec incompatibility error, disable a spec and resubmit
	var form_controls = get_form_controls(available_product_attributes_form);
	for (var i=0;i<errors.length;i++)
	{
		var e = errors[i];
		var attribute = e.getAttribute('attribute');
		if (!attribute) continue;
		var a = attribute.split(',');
		for (var x=0;x<a.length;x++)
		{
		// Find the attribute control(s)
			var att = 'a'+a[x];
			var ctls = form_controls[att];
			var found = false;
			if (ctls)
			{
				for (var i=0;i<ctls.length;i++)
				{
				// Check to see if this is a control to unset
					var c = ctls[i];
					switch (c.type)
					{
					case 'text':
					case 'hidden':
					case 'select':
					case 'select-one':
						if (c.value == '') continue;
						c.value = '';
						found = true;
						break;
					case 'checkbox':
					case 'radio':
						if (!c.checked) continue;
						c.checked = false;
						found = true;
						break;
					}
	
				// If a control was found, resubmit
					if (found)
					{
						resubmit(callback);
						return true;
					}
				}
			}
			return false;
		}
	}
	return false;
}

function resubmit(callback)
{
	if (callback != null && callback.value != '')
	{
		updateAvailableProductAttributesWithCallback(available_product_attributes_form,callback);
	}
	else
	{
		updateAvailableProductAttributes(available_product_attributes_form);
	}
}


function parse_available_attributes(attribute_list)
{
// Get the DOM into a more managable array
	var parsed = new Array();
	var len = attribute_list.length;
	for (var i=0;i<len;i++)
	{
		var attribute = attribute_list[i];
		var id = attribute.getAttribute('id');
		parsed[id] = attribute;
	}
	return parsed;
}

function is_product_attribute_disabled(att,parsed_attributes)
{
	return (typeof parsed_attributes[att] == 'undefined');
}

function is_product_attribute_value_disabled(att,v,parsed_attributes)
{
// Find the value
	var attribute = parsed_attributes[att];
	if (typeof parsed_attributes[att] == 'undefined')
		return true;
	var attribute_values = attribute.getElementsByTagName('AttributeValue');
	var len = attribute_values.length;
	for (var i=0;i<len;i++)
	{
		var attribute_value = attribute_values[i];
		if (v == attribute_value.getAttribute('id'))
			return false;
	}
	return true;
}

function update_attribute_menu(att,parsed_attributes,c)
{
// Preserve the old value
	var cur = (c.selectedIndex>-1) ? c.options[c.selectedIndex].value : '';
	var selected = -1;
	var has_changed = false;

// Find the attribute
	var attribute = parsed_attributes[att];
	if (typeof parsed_attributes[att] == 'undefined')
	{
	// Blank out the menu
		var i = 0;
		if (c.options.length > 0 && c.options[0].value == '')
			i++;
		c.options.length = i;
		return (cur != '');
	}

// Get the attribute values into a sorted array
	var has_blank = false;
	var sorted_av = {};
	var attribute_values = attribute.getElementsByTagName('AttributeValue');
	var len = attribute_values.length;
	for (var i=0;i<len;i++)
	{
		var attribute_value = attribute_values[i];
		var sort = attribute_value.getAttribute('sort');
		var val = attribute_value.getAttribute('id');
		if (val == null)
			val = '';
		var desc = attribute_value.firstChild.data;
		sorted_av[sort] = {};
		sorted_av[sort]['val'] = val;
		sorted_av[sort]['desc'] = desc;
		if (val == '')
			has_blank = true;
	}

// Preserve the first choice if it's a blank placeholder
	var i = 0;
	var default_to_blank = false;
	if (c.options.length > 0 && c.options[0].value == '')
	{
		i++;
	}
	else
	{
	// Populate the menu with the attribute values
		var r = attribute.getElementsByTagName('Required');
		if ((!r || r.length<1) && !has_blank)
		{
			c.options[i] = new Option('','');
			i++;
		}
		else
			selected = 0;
	}
	for (var sort in sorted_av)
	{
		var a = sorted_av[sort];
		var val = a['val'];
		var desc = a['desc'];
		c.options[i] = new Option(desc,val);
		if (val == cur)
			selected = i;
		i++;
	}
	c.options.length = i;
	if (selected == -1 && c.options.length > 0 && c.options[0].value == '')
		selected = 0;
	c.selected = c.selectedIndex = selected;
	return (c.value != cur);
}



/*******************************************************************************
 * isAvailableProductAttribute - find out if this attribute is enabled or disabled
 *******************************************************************************/
function isAvailableProductAttribute(att,attribute_list)
{
// Look for the attribute
	var len = attribute_list.length;
	if (len < 1)
		return true;
	for (var i=0;i<len;i++)
	{
		var attribute = attribute_list[i];
		if (att == attribute.getAttribute('id'))
		{
			return true;
		}
	}
	return false;
}

/*******************************************************************************
 * isAvailableProductAttributeValue - find out if this attribute is enabled or disabled
 *******************************************************************************/
function isAvailableProductAttributeValue(att,av,attribute_list)
{
// Look for the attribute
	var len = attribute_list.length;
	if (len < 1)
		return true;
	for (var i=0;i<len;i++)
	{
		var attribute = attribute_list[i];
		if (att == attribute.getAttribute('id'))
		{
		// Look for the attribute value
			if (!av)
				return true;
			var attribute_values = attribute.getElementsByTagName('AttributeValue');
			var len2 = attribute_values.length;
			for (var j=0;j<len2;j++)
			{
				var attribute_value = attribute_values[j];
				if (av == attribute_value.getAttribute('id'))
					return true;
			}
			return false;
		}
	}
	return false;
}

/*******************************************************************************
 * updateAttributeMenu - find out if this attribute is enabled or disabled
 *******************************************************************************/
function updateAttributeMenu(att,attribute_list,c)
{
// Preserve the old value
	var cur = (c.selectedIndex>-1) ? c.options[c.selectedIndex].value : '';
	var selected = -1;

// Find the attribute
	var len = attribute_list.length;
	for (var i=0;i<len;i++)
	{
		var attribute = attribute_list[i];
		if (att == attribute.getAttribute('id'))
		{
		// Get the attribute values into a sorted array
			var has_blank = false;
			var sorted_av = new Array();
			var attribute_values = attribute.getElementsByTagName('AttributeValue');
			var len2 = attribute_values.length;
			for (var j=0;j<len2;j++)
			{
				var attribute_value = attribute_values[j];
				var sort = attribute_value.getAttribute('sort');
				var val = attribute_value.getAttribute('id');
				if (val == null)
					val = '';
				var desc = attribute_value.firstChild.data;
				sorted_av[sort] = new Array();
				sorted_av[sort]['val'] = val;
				sorted_av[sort]['desc'] = desc;
				if (val == '')
					has_blank = true;
			}

		// Preserve the first choice if it's a blank placeholder
			var j = 0;
			if (c.options.length > 0 && c.options[0].value == '')
			{
				j++;
			}
			else
			{
			// Populate the menu with the attribute values
				var r = attribute.getElementsByTagName('Required');
				if ((!r || r.length<1) && !has_blank)
				{
					c.options[j] = new Option('','');
					j++;
				}
				else
					selected = 0;
			}
			for (var sort in sorted_av)
			{
				var a = sorted_av[sort];
				var val = a['val'];
				var desc = a['desc'];
				c.options[j] = new Option(desc,val);
				if (val == cur)
					selected = j;
				j++;
			}
			c.options.length = j;
			if (selected == -1 && c.options.length > 0 && c.options[0].value == '')
				selected = 0;
			c.selected = c.selectedIndex = selected;
		}
	}
}
