/*
jch 4/9/04  javascript functions to support dataset criteria selection page
*/

//extracts "group" attribute from XML element
function getGroupIndex(v) {
	var pattern = new RegExp(" group='([\0-9]+)'");			
	pattern.test(v);
	return RegExp.$1;
}

//returns ID from XML element
function getID(v) {
	var pattern= new RegExp(" id='([\0-9]+)'");
	pattern.test(v);
	return RegExp.$1;
}

function isGroupDelimiter(v) {
//returns true if sepcified value v is a group delimiter
//i.e., if it begins with "<OR"
	var retval = v.indexOf("<OR");
	return (retval==0);
}

function getCritTag(t){
//returns opening tag of criterion based on selected value
	var retval;
	switch (t) {
		case "str":
			retval="<Strain"; 
			break;
		case "inv":
			retval="<Investigator";
			break;
		case "asy":
			retval="<Assay";
			break;
		case "exp":
			retval="<Experiment";
			break;
		case "grp":
			retval="<OR";
			break;
		case "efv":
			retval="<Condition";
	}
	return retval;
}
	
var groupIndex = 0;
var selectedGroupIndex = 0; // group currently selected by user 	
	
function getElement(ElementId)
{
    var returnElement;
     
    var formDataSet = document.forms['aspnetForm'];
    if (!formDataSet)
        formDataSet = document.aspnetForm;
        
    var formElements = formDataSet.elements;
	    
    for(var i=0; i< formElements.length; i++)
    {
        if(formElements[i].id.indexOf(ElementId) != -1)
        {
            returnElement = formElements[i];
            break;
        }
    }
    return returnElement;
}

function critElement()
{
    return getElement(cCriteriaID);
}
	
function currentGroupIndex()
{
	return groupIndex;
}
	
function nextGroupIndex()
{
	groupIndex++;
	return groupIndex;
}

function getValueElement (c)
{
    //returns a reference to the form element that holds the value specified by the criteria type
	var retval;
	switch (getSelectValue(c)) {
		case "str":
			retval = getElement("ddlStrains");
			break;
		case "asy":
			retval = getElement("ddlAssays");
			break;
		case "exp":
			retval = getElement("ddlExperiments");
			break;
		case "inv":
			retval = getElement("ddlInvestigators");
			break;
		case "efv":
			retval = getElement("ddlExpFactors");
			break;
	}		
	return retval;	
}

function removeCriteriaItem()
{
	var e = critElement();
	if (e.selectedIndex >= 0)
	{ 
		var o = e.options[e.selectedIndex];
		if (o != null)
		{	
			//if it's a group, remove the whole group
			if (isGroupDelimiter(o.value))
			{
				var groupID = getGroupIndex(o.value);
				//remove everything that matches the group id 
				for (var i=(e.options.length-1); i>=0; i--)
				{ 
					if (getGroupIndex(e.options[i].value)==groupID)
						e.options[i] = null; 
				}
			} 
			else 
			{
				//otherwise, just remove the item
				e.options[e.selectedIndex] = null;
			}
		} 
		e.selectedIndex = -1;
	}
}
	
function addCritGroup()
{
	//add new list item that indicates start of new group (whose value is of the form "group='n'")
	var e =critElement();
	var gi = nextGroupIndex();
	appendOption(e,getCritTag("grp") + " group='" + gi + "' />","============= OR =============");
	selectedGroupIndex=gi;//set the selected group to the newly added group
	e.selectedIndex=(e.options.length)-1;
}
	
function insertCrit(grpidx,idx)
{ 
	//grpidx = group id to use with criteria
	//idx = index where we'll be inserting data
	var elmDdlType = document.getElementsByName("ddlType");
	dscValueElement = getValueElement(elmDdlType[0]);
	e=critElement();
	
	var dispVal; //displayed value for criteria
	var storeVal; //stored value for criteria
	var critType; //criteria type
	
	critType = getSelectValue(elmDdlType[0]);
	//append text to the listbox; stored value will be an xml string
	//open the tag and add the group ID
	storeVal = getCritTag(critType) + " group='" + grpidx + "'";
	//get the operator (include/exclude)
	storeVal += " oper='" + getSelectValue(getElement("ddlOperator")) + "'";
	//get the id of the strain/assay/investigator/etc.
	storeVal += " id='" + getSelectValue(dscValueElement) + "'"; 
	//get the name of the thing
	storeVal += " name='" + encode(getSelectText(dscValueElement)) + "'";
	//build display value
	dispVal = getSelectText(getElement("ddlOperator")) + " " + getSelectText(elmDdlType[0]); //operator + type 
	dispVal += " " + getSelectText(dscValueElement); //value of criteria

	switch (critType) {
		case "str":  //add sex option for strains
			dispVal += " (" + getSelectText(elmDdlType[0]) + ")";
			storeVal += " sex='" + getSelectValue(getElement("ddlSex")) + "'";
			break;
		case "asy": //add value options for assays
			var fromValue;
			var toValue;
			fromValue = getElement("txtAssayValueFrom").value;
			toValue = getElement("txtAssayValueTo").value;

			//make sure values are numbers
			if (isNaN(fromValue) || isNaN(toValue))
			{
				window.alert("Range values must be numeric!");
				return;						
			}
			storeVal += " value1='" + fromValue + "'";
			storeVal += " value1op='" + getSelectValue(getElement("ddlAssayFromOperator")) + "'";
			storeVal += " value2='" + toValue + "'";
			storeVal += " value2op='" + getSelectValue(getElement("ddlAssayToOperator")) + "'";
			dispVal += (fromValue == "") ? " (" : " (" + getSelectText(getElement("ddlAssayFromOperator")) + fromValue;
			dispVal += (toValue == "") ? ")" : ", " + getSelectText(getElement("ddlAssayToOperator")) + toValue + ")";
			break;
		case "efv": //add value options for exp factors
			//only bother adding value if user picked something other than "Any"
			if (getSelectValue(getElement("ddlExpFactorValues"))!='x')
			{ 
				storeVal += " value1='" + getSelectValue(getElement("ddlExpFactorValues")) + "'";
				storeVal += " value1name='" + getSelectText(getElement("ddlExpFactorValues")) + "'";
				storeVal += " value1op='" + getSelectValue(getElement("ddlEfvOperator")) + "'";
				dispVal += getSelectText(getElement("ddlEfvOperator")) + getElement("ddlExpFactorValues"); 
			}
	}
	storeVal += " />";
	if (valueExists(e,storeVal))
	{
		window.alert("You have already specified that criteria.  Please select another option.");
	}
    else
    {
	    //are we inserting this after the last item in the list?
		insertOption(e,storeVal,dispVal,idx);
	}
}
	
function populateEFVOperators(efid)
{
	var e=getElement("ddlEfvOperator");
	var arOp;
	//set operator list based on choice of exp factor (categorical or continuous)				
	if (arCatEF[efid]) 
	{
		arOp=arOpCategorical;
	}
	else
	{
		arOp=arOpContinuous;
	}
		//if the number of current options differs from the number of needed options, modify the options

	if (e.options.length!=arOp.length)
	{
		removeAllOptions(e);
		for (var i=0;i<arOp.length;i++)
		{
			appendOption(e,arOp[i][0],arOp[i][1]);
		}				
	}	
}
	
function populateEFV(efid) 
{
	//populates experimental factor values for specified experimental factor id
	var e=getElement("ddlExpFactorValues");
	var ar = arEFV[efid];
	//make sure values exist
	if (ar==null) 
	{
	    //if not, just add "Any" option and bail
		ar = new Array(new Array('x','[Any]')); 
	} 
		
	removeAllOptions(e);
	for (var i=0; i<ar.length; i++) 
	{
		appendOption(e,ar[i][0],ar[i][1]);
	}
	populateEFVOperators(efid);
}

function toggleCrit(c) 
{ 
    //category
	//calls function to show/hide div for selected criteria type
	//divs have ids that are the select values in ddlType	
	var arDivs = ["str","asy","exp","inv","efv"];
	
	for (var i=0;i<arDivs.length;i++)
	{
		if (arDivs[i]==c) 
		{
			toggleDiv(arDivs[i],1);
		}
		else 
		{
			toggleDiv(arDivs[i],0);
		}
	}
	//populate experimental factor values
	if (c=="efv")
	{
		populateEFV(getSelectValue(getElement("ddlExpFactors")));
	}
}
	
//do i still need this?
function setSelectedGroupIndex()
{
	var e=critElement();
	selectedGroupIndex=getGroupIndex(getSelectValue(e));
}

function insertCritAbove() 
{
    //inserts criteria above selected
	var gi;
	var e=critElement();
	if (e.selectedIndex>0)
	{
		if (isGroupDelimiter(getSelectValue(e))) 
		{
			//if this is a group delimiter, grab the group id of the item above it				
			gi=getGroupIndex(e.options[e.selectedIndex-1].value);
		}
		else
		{
			//otherwise grab the group id of the selecteed item
			gi=getGroupIndex(getSelectValue(e));
		}
	}
	else
	{ 
	    //nothing selected, so insert this at the top of the list
		gi=0;
	}
	insertCrit(gi,e.selectedIndex);
}

function insertCritBelow()
{
	//inserts criteria below selected item.  
	//get the group index from the selected item
	var gi;
	var e=critElement();
	//if no options, start at 0
	if (e.options.length==0) 
	{
	  gi=0;
	} 
	else 
	{
		//if something's selected, get the group index of the selected thing
		if (e.selectedIndex >= 0) 
		{
			gi=getGroupIndex(getSelectValue(e));
		} 
		else 
		{
			//but if nothing's selected, get the group index of the last item in the list
			gi=getGroupIndex(e.options[e.options.length-1].value);
		}
	}
	insertCrit(gi,e.selectedIndex+1);
}
	
function doSubmit()
{
	//selecting all elements doesn't seem to work in IE6
	//so building a string and passing it to a hidden value
	
	var e=critElement();
	var to=getElement("txtCriteria");
	to.value="";

	//make sure user has selected at least one criterion
	if (e.options.length>0) 
	{
		to.value="<PQC ageUnit='" + getSelectValue(getElement("ddlAgeUnit")) + "'>"; 
		for (var i=0 ; i<e.options.length; i++) 
		{
			to.value += e.options[i].value;
		} 
		to.value+="</PQC>";
	}
	
	//showXML();
}
	
//shows criteria XML
function showXML()
{
	window.alert(getElement("txtCriteria").value);
}

function addNewCrit() 
{
	var e=critElement();
	//if no options, group=0, put it at top of list
	if (e.options.length==0) 
	{
		groupIndex=0;
		insertCrit(0,-1);
	} 
	else 
	{
		//otherwise, group=groupid of last item in list
		e.selectedIndex = (e.options.length-1);
		insertCritBelow();
	}
}
	
function removeAllCrit() 
{
	e=critElement();
	if (e.options.length>0) 
	{
		if (window.confirm("Are you sure you want to remove all criteria?")) 
		{
			removeAllOptions(critElement());
		}
	}
}
