// Copyright 2003-2004, Rod Mancisidor.
// All rights reserved.
// Use of this software prohibited except by written permission from the author.

// ...Interested --------------------------------------------------------------

function _interested(facet) {
	// we are interested in this facet, chances are it is already selected
	// (if we are in the expert page), indicate we are interested in it.
	// also, make sure the helpMe field is set to true
	var importance = getElem(facet + 'Importance');
	importance.checked = true;
	var helper = getElem(facet + 'Expert_helpMe');
	if (helper) {
		helper.value = '1';
	}
	_includeItem(facet, 'FieldAdvExcludedFacets');
}

function _notInterested(facet) {
	// We are not interested in this facet.
	// also, make sure the helpMe field is set to false
	var importance = getElem(facet + 'Importance');
	if (importance && importance.checked) {
		importance.checked = false;
		if (importance.onclick) importance.onclick(importance);
	}
	var helper = getElem(facet + 'Expert_helpMe');
	if (helper) {
		helper.value = '0';
	}
}

function _removeInterest(id) {
	// if there is a novice field
	if (_getElems(id + 'Novice').length > 0) {
		// reset the novice field and make it disappear
		_resetField(id + 'Novice');
		var helpMe = getElem(id + 'Expert_helpMe');
		if (helpMe && helpMe.value == '1') {
			clickHelpMeDecide(null, id + 'Expert');
			getElem(id + 'Expert_helpMe').value = '0';
		}
	}
}

// _isExpertPage --------------------------------------------------------------

function _isExpertPage() {
	// is this the expert questions page?
	return getElem('fromPage').value == 'Expert';
}

// helper functions for novice fields -----------------------------------------

function _handleNoOpinionNoviceRadio(self, facetName) {
	// determine whether we have an opinion and perform general logic to
	// state whether we are interested.
	var noOpinion = self.value == '';
	if (! noOpinion) {
		_interested(facetName);
	} else {
		_notInterested(facetName);
		if (_isExpertPage()) self.checked = false;
	}
	return noOpinion;
}

function _handleNoOpinionNoviceCheckbox(self, facetName) {
	// determine whether we have an opinion and perform general logic to
	// state whether we are interested.
	var noOpinion = self.value == '' && self.checked;
	var opinion = false;
	if (noOpinion) {
		_notInterested(facetName);
		_resetField(self.name);
		if (! _isExpertPage()) self.checked = true;
	} else {
		var i, checkboxes = _getElems(self.name);
		for (i=0; i<checkboxes.length-1; ++i) {
			if (checkboxes[i].checked) {
				opinion = true;
				break;
			}
		}
		if (opinion) {
			_interested(facetName);
			checkboxes[checkboxes.length-1].checked = false;
		}
	}
	return noOpinion || ! opinion;
}

function _handleNoOpinionNoviceCheckboxMultiFacet(self) {
	// determine whether we have an opinion and perform general logic
	// to reset other options if needed
	var noOpinion = self.value == '' && self.checked;
	var opinion = false;
	if (noOpinion) {
		_resetField(self.name);
		if (! _isExpertPage()) self.checked = true;
	} else {
		var i, checkboxes = _getElems(self.name);
		for (i=0; i<checkboxes.length-1; ++i) {
			if (checkboxes[i].checked) {
				opinion = true;
				break;
			}
		}
		if (opinion) {
			checkboxes[checkboxes.length-1].checked = false;
		}
	}
	return noOpinion || ! opinion;
}

// general advisor functions invoked by event handlers ------------------------

function clickProdDetails(advId, id) {
	_setFieldToSubmit('FieldAdvProdDetail', id);
	submitForm('PageAdvDetails' + advId);
}

function clickInterested(self) {
	// an Importance field has been clicked in the expert page, we need to show
	// or hide the hidden expert question as needed
	var name = self.name;
	name = name.substring(0, name.indexOf('Importance'));
	_showBlockIf(self.name + '_nested', self);
	// if I am not interested and there is a novice field
	if (! self.checked && _getElems(name + 'Novice').length > 0) {
		// reset the novice field and make it disappear
		_resetField(name + 'Novice');
		var helpMe = getElem(name + 'Expert_helpMe');
		if (helpMe && helpMe.value == '1') {
			clickHelpMeDecide(getElem(name + 'Expert_helpMe_1'),
							  name + 'Expert');
		}
	}
}

function changeInterested(self) {
	// If we change the interested field in the Suggestions page, we need
	// to include or exclude the facet as appropriate and submit
	var name = self.name;
	name = name.substring(0, name.indexOf('Importance'));
	// if we are setting importance to 0.0, clean the novice field
	if (self.selectedIndex == 0) {
		_removeInterest(name);
	}
	// submit the form
	submitForm();
}

function changeExpertAnswer(self) {
	// when we change an expert field, we need to:
	//  1) hide the helper field if it is currently visible
	//  2) reset the election that may have been made on the helper field
	//  3) make sure the interested field is set to true
	var name = self.name;
	var rootName = name.substring(0, name.indexOf('Expert'));
	name = rootName + 'Expert';
	var helpMeId = name + '_helpMe';
	var helperId = name + '_helper';
	var impId    = rootName + 'Importance';
	if (_getElems(helpMeId).length == 1) {
		_resetHiddenBooleanField(helpMeId);
		_showProperBooleanImage(helpMeId);
		_showBlockIf(helperId, helpMeId);
		getElem(impId).checked = true;
	}
	var childId  = rootName + 'Novice';
	if (_getElems(childId).length) {
		_resetField(childId);
	}
}

function changeExpertShort(self) {
	// this is used in the suggestions page, it does the same as
	// changeExpertAnswer, but also submits the form
	changeExpertAnswer(self);
	submitForm();
}

function changeExpertShortInterval(self) {
	// same as changeExpertShort, but first check that the both input fields
	// in the interval contain something
	var name = self.name;
	name = name.substring(0, name.length - 6);
	if (getElem(name+'_lower').value && getElem(name+'_upper').value) {
		changeExpertShort(self);
	}
}

function changeExpertShortList(self) {
	// same as changeExpertShort, but first check that all input fields
	// in the list contain something
	var name = self.name;
	name = name.substring(0, name.length - 1);
	var elem;
	for (i=0; ; ++i) {
		elem = getElem(name + i);
		if (! elem) break;
		if (elem.value == '') return;
	}
	changeExpertShort(self);
}

function clickHelpMeDecide(self, name) {
	// the help me decide link has been clicked, we need to toggle the image
	// of the help me field and toggle the visibility of the helper field
	var scroll = _saveScroll();
	var rootName = name.substring(0, name.indexOf('Expert'));
	name = rootName + 'Expert';
	var helpMeId = name + '_helpMe';
	var helperId = name + '_helper';
	toggleBooleanElem(self);
	_showBlockIf(helperId, helpMeId);
	_restoreScroll(scroll);
}

// handlers for expert fields

function updateNumberWithChoice(self) {
	// a selection in a KindNumberWithChoices field has been made, we need to
	// a) update the text field to reflect the change
	// b) toggle the visibility of the text and choice fields if the selection
	//    was 'other'
	// c) return true if and only if the choice was not 'other'
	// self can be either an <input type="radio"> or <select> element that was
	// changed
	// get the selected value
	var value = _getFieldValue(self);
	// name is the root name of this field (the <select> and <input> components
	// have '_ch' appended to the root name
	var name = self.name;
	name = name.substring(0, name.lastIndexOf('_ch'));
	// get the corresponding text element
	var text = getElem(name);
	// update the text element and the visibility
	var valueIsNotOther = value != 'other';
	if (valueIsNotOther) {
		text.value=value;
	} else {
		text.value='';
		document.getElementById(name+'_choice').style.display='none';
		document.getElementById(name+'_number').style.display='inline';
		text.focus();
	}
	return valueIsNotOther;
}

function updateIntervalWithChoice(self) {
	// a selection in a KindIntervalWithChoices field has been made, we need to
	// a) update the text fields to reflect the change
	// b) toggle the visibility of the text and choice fields if the selection
	//    was 'other'
	// c) return true if and only if the choice was not 'other'
	// self can be either an <input type="radio"> or <select> element that was
	// changed
	// get the selected value
	var value = _getFieldValue(self);
	// name is the root name of this field (the <select> and <input> components
	// have '_ch' appended to the root name
	var name = self.name;
	name = name.substring(0, name.lastIndexOf('_ch')) + '_';
	// get the corresponding text elements
	var textLower = getElem(name + 'lower');
	var textUpper = getElem(name + 'upper');
	// update the text element and the visibility
	var valueIsOther    = value == 'other';
	var valueIsOptimize = value == 'optimal';
	if (valueIsOptimize) {
		textLower.value=value;
		textUpper.value=value;
	} else if (! valueIsOther) {
		value = value.split('-');
		textLower.value=value[0];
		textUpper.value=value[1];
	} else {
		textLower.value='';
		textUpper.value='';
		document.getElementById(name+'choice').style.display='none';
		document.getElementById(name+'number').style.display='inline';
		textLower.focus();
	}
	return ! valueIsOther;
}

function updateListWithChoice(self) {
	// a selection in a KindListWithChoices field has been made, we need to
	// a) update the text fields to reflect the change
	// b) toggle the visibility of the text and choice fields if the selection
	//    was 'other'
	// c) return true if and only if the choice was not 'other'
	// self can be either an <input type="radio"> or <select> element that was
	// changed
	// get the selected value
	var value = _getFieldValue(self);
	// name is the root name of this field (the <select> and <input> components
	// have '_ch' appended to the root name
	var name = self.name;
	name = name.substring(0, name.lastIndexOf('_ch')) + '_';
	// update the text element and the visibility
	var valueIsOther    = value == 'other';
	var valueIsOptimize = value == 'optimal';
	var i, elem;
	if (valueIsOptimize) {
		for (i=0; ; ++i) {
			elem = getElem(name + i);
			if (! elem) break;
			elem.value = value;
		}
	} else if (! valueIsOther) {
		value = value.split('x');
		for (i=0; i<value.length; ++i) {
			elem = getElem(name + i);
			elem.value = value[i];
		}
	} else {
		for (i=0; ; ++i) {
			elem = getElem(name + i);
			if (! elem) break;
			elem.value = '';
		}
		document.getElementById(name+'choice').style.display='none';
		document.getElementById(name+'number').style.display='inline';
		getElem(name + '0').focus();
	}
	return ! valueIsOther;
}

function _updateNumOrIntWithChAndSubmit(self, updateFnc, fieldType) {
	// same as updateNumberWithChoice, but if the user selected something
	// other than other, then also reset the novice field and submit the form
	if (updateFnc(self)) {
		var name = self.name;
		name = name.substring(0, name.lastIndexOf('_ch'));
		if (fieldType == 1) { // is interval
			name += '_lower';
		} else if (fieldType == 2) { // is list
			name += '_0';
		}
		// reset the novice field and submit
		changeExpertShort(getElem(name));
	}
}

function updateNumWithChAndSubmit(self) {
	// same as updateNumberWithChoice, but if the user selected something
	// other than other, then also reset the novice field and submit the form
	_updateNumOrIntWithChAndSubmit(self, updateNumberWithChoice, 0);
}

function updateIntWithChAndSubmit(self) {
	// same as updateIntervalWithChoice, but if the user selected something
	// other than other, then also reset the novice field and submit the form
	_updateNumOrIntWithChAndSubmit(self, updateIntervalWithChoice, 1);
}

function updateListWithChAndSubmit(self) {
	// same as updateIntervalWithChoice, but if the user selected something
	// other than other, then also reset the novice field and submit the form
	_updateNumOrIntWithChAndSubmit(self, updateListWithChoice, 2);
}

// utility function to include products or facets

function _includeItem(id, field, forSubmit) {
	if (arguments.length < 3) forSubmit = false;
	var elem = getElem(field);
	var value = elem.value;
	var vals = value.split(',');
	var result = '';
	var i;
	for (i=0; i<vals.length; ++i) {
		if (id != vals[i]) {
			if (! result) {
				result = vals[i];
			} else {
				result = result + ',' + vals[i];
			}
		}
	}
	if ( ! forSubmit) {
		elem.value = result;
	} else {
		_setFieldToSubmit(field, result);
	}
}

// controls to include and exclude products and facets

function clickIncludeProd(id) {
	_includeItem(id, 'FieldAdvExcludedProds', true);
	submitForm();
}

function clickExcludeProd(id) {
	warningField = getElem('FieldAdvWarnExcludedProds');
	if (warningField.checked) {
		alert(_getMsg('prodExcludeUndo'));
		warningField.checked = false;
	}
	var value = getElem('FieldAdvExcludedProds').value;
	_setFieldToSubmit('FieldAdvExcludedProds', value ? value + ',' + id : id);
	return submitForm();
}

// functions for PageAuxFacetImp page

function impFacets(ids) {
	// submits a request setting the importance of facets that have been checked
	if (arguments.length == 0) {
		window.opener.impFacets(_getFieldValues('impFacets'));
	} else {
		if (ids.length > 0) {
			var i, id;
			for (i=0; i<ids.length; ++i) {
				id = ids[i];
				_setFieldToSubmit(id + 'Importance', '0.375');
				_includeItem(id, 'FieldAdvExcludedFacets', true);
			}
			focus();
			submitForm();
		}
	}
}

// functions for PageAuxFacetShow page

function showFacets(ids, checks) {
	// submits a request to show or hide facets based on showFacets
	if (arguments.length == 0) {
		var i, elem, elems = _getElems('showFacets');
		var values = [];
		var checks = [];
		for (i=0; i<elems.length; ++i) {
			elem = elems[i];
			values[i] = elem.value;
			checks[i] = elem.checked;
		}
		window.opener.showFacets(values, checks);
	} else {
		var excluded = [];
		var i, id, checked, importance, impField, form;
		form = _getForm();
		for (i=0; i<ids.length; ++i) {
			id = ids[i];
			checked = checks[i];
			// _getFieldValue is too slow for IE5 Mac and Safari
			// importance = _getFieldValue(getElem(id + 'Importance'));
			impField = form[id + 'Importance'];
			importance = impField.options[impField.selectedIndex].value;
			if (! checked) {
				excluded[excluded.length] = id;
				if (importance != '0.0') {
					_setFieldToSubmit(id + 'Importance', '0.0');
					_removeInterest(id);
				}
			}
		}
		_setFieldToSubmit('FieldAdvExcludedFacets', excluded.join(','));
		focus();
		submitForm();
	}
}

function selectShowFacets(bool) {
	var i, fields = _getElems('showFacets');
	for (i=0; i<fields.length; ++i) {
		fields[i].checked = bool;
	}
}

// helper functions for importance column of suggestions table ----------------

function _getImportance(elem) {
	// maps a numeric importance to its label
	var imp = elem.options[elem.selectedIndex].value;
	switch (imp) {
	case '0.0'     : return 'None';
	case '0.140625': return 'Low';
	case '0.375'   : return 'Medium';
	case '1.0'     : return 'High';
	}
}

function showImpInfo(evt) {
	evt        = evt || event;
	var elem   = evt.target || evt.srcElement;
	var imp    = _getImportance(elem);
	// set elem up to the div and the th, then to the th to the right
	elem       = elem.parentNode.parentNode.nextSibling;
	var pos    = _getElemPosition(elem);
	var dims   = _getElemDims(elem);
	var style  = getElem('divImpTitle' + imp).style;
	style.left = (pos[0] + dims[0]) + 'px';
	style.top  = (pos[1] + dims[1]) + 'px';
	style.visibility = 'visible';
	window.status = _getMsg('impTitle' + imp);
}

function hideImpInfo(evt) {
	evt        = evt || event;
	var elem   = evt.target || evt.srcElement;
	var imp    = _getImportance(elem);
	getElem('divImpTitle' + imp).style.visibility = 'hidden';
	window.status = '';
}

// helper functions for youWant column of suggestions table -------------------

function showControlClickInfo(evt) {
	evt        = evt || event;
	var elem   = evt.target || evt.srcElement;
	var tag    = elem.tagName;
	if (tag != 'SELECT' && tag != 'OPTION') return;
	var pos    = _getElemPosition(elem);
	var dims   = _getElemDims(elem);
	var style  = getElem('controlClickInfoElem').style;
	style.left = (pos[0] + dims[0]) + 'px';
	style.top  = (pos[1] + dims[1]) + 'px';
	style.visibility = 'visible';
	window.status = _getMsg('controlClickInfo');
}

function hideControlClickInfo(evt) {
	evt        = evt || event;
	var elem   = evt.target || evt.srcElement;
	var tag    = elem.tagName
	if (tag != 'SELECT' && tag != 'OPTION') return;
	getElem('controlClickInfoElem').style.visibility = 'hidden';
	window.status = '';
}

// onload handler -------------------------------------------------------------

function _advOnLoadHandler() {
	// onload handler for adv package
	var fromPage = getElem('fromPage');
	fromPage = fromPage? fromPage.value: '';
	// if this is the Suggestions page, then
	if (fromPage.indexOf('PageAdvSuggestions') != -1) {
		// set up handlers for impDropDowns select elements
		performAction(document.getElementById('suggestions'),
					  hasClass('impDropDown'),
					  function(elem) {
						  elem.onmouseover = showImpInfo;
						  elem.onmouseout  = hideImpInfo;
					  });
		// set up handlers for expertSet th elements
		performAction(document.getElementById('suggestions'),
					  hasClass('expertSet'),
					  function(elem) {
						  elem.onmouseover = showControlClickInfo;
						  elem.onmouseout  = hideControlClickInfo;
					  });
	}
}

addOnLoadHandler(_advOnLoadHandler);
