/**
  * form.js
  * 
  * Provides various form functions, including decorators.
  *
  */

/** Constants **/

// Name of field that is set when a form value changes
var FIELD_DIRTY = "dirty";

// Cancel button
var FIELD_CANCEL = "cancel";

// Save button
var FIELD_SAVE = "save";

// Frequency for Form Observer
var FORM_OBS_FREQ = 10;

/**
  * Add behavior to confirm before leaving a "dirty" form 
  * (one that has been modified)
  * @param theForm The form 
  */
function decorateConfirmIfDirty(theForm) {

	// form must have a "dirty" element

	Logger.debug("Decorating: confirm if dirty. Form: " + theForm.id);
	if ( $(FIELD_DIRTY) ) {
		var obs = new Form.Observer(theForm, FORM_OBS_FREQ, formChanged);
		$(FIELD_DIRTY).value = "false";
		
		// add unload observe, in case user leaves pages with changes
		// FIXME this is problematic when the using "Save" button - it 
		// still prompts
		// Event.observe(window, "beforeunload", confirmLeavePage, true);
		
		// add the onclick event to the cancel button
		if ($(FIELD_CANCEL)) {
			Logger.debug("Found cancel button");
			$(FIELD_CANCEL).onclick = confirmCancel;
			Logger.debug("Set onclick " + FIELD_CANCEL);
		}
		else {
			Logger.error("Could not find button with id " + FIELD_CANCEL);
		}
	}
	else {
		Logger.warn("Could not apply decorator: field not found " + FIELD_DIRTY);
	}
}

/**
  * Focus on the first field in the form
  *
  */
function decorateFocusFirst(theForm) {
	Logger.debug("Decorating: focus first field. Form: " + theForm.inspect());
	Form.focusFirstElement(theForm);
}

function formChanged() {
	var dirty = $(FIELD_DIRTY);
	Logger.debug(FIELD_DIRTY + " = " + dirty.value);
	if (dirty.value != "true") {
		$(FIELD_DIRTY).value = "true";
		Logger.debug("Form changed; set dirty to true");
	}
}

function confirmLeavePage(evt) {
	
	var dirty = $F("dirty");

	if (dirty && dirty == "true") {
		evt.returnValue = "If you leave this page, your changes will be lost. Please confirm.";
	}
}	

function confirmCancel() {
	var dirty = $F("dirty");

	if (dirty && dirty == "true") {
		var cancel =  confirm("Cancel and lose changes?");
		if (cancel) {
			$(FIELD_DIRTY).value = "false";
		}
		return cancel;
	}
	else {
		return true;
	}
}

function confirmAction(actionText) {
	
	return confirm(actionText);
	
}

/**
 * decorateDisableSaveOnClick
 */
function decorateDisableSaveOnClick() {
 	Logger.debug(">> decorateDisableSaveOnClick");
 	
 	var save = $(FIELD_SAVE);
 	if (save) {
 		Event.observe(save, "click", disableSave);
 	}
 	Logger.debug("<< decorateDisableSaveOnClick");
}

/**
 * disableSave
 */
function disableSave() {
 	Logger.debug(">> disableSave");
 	$(FIELD_SAVE).disable();
 	Logger.debug("<< disableSave");
 	return true;
}

function buildLabelValueList(select, lvList, defaultValue) {
	Logger.debug(">> buildLabelValueList");

        var hasDefault = (defaultValue && defaultValue != "");

	select.options.length = 0;
	for(i=0; i < lvList.length; i++) {
            if (hasDefault && defaultValue == lvList[i].value ) {
		select.options[i] = new Option(lvList[i].label, lvList[i].value, true);
            }
            else {
                select.options[i] = new Option(lvList[i].label, lvList[i].value);
            }
	}

        Logger.debug("<< buildLabelValueList");
}

/**
 * @param frm The form to select all checkboxes on
 */
function selectAll(frm) {
	var cbs = Form.getInputs(frm, "checkbox");
	cbs.each(function(cb){
		cb.checked = true;
	});
}

/**
 * @param frm The form to un-select all checkboxes on
 */
function selectNone(frm) {
	var cbs = Form.getInputs(frm, "checkbox");
	cbs.each(function(cb){
		cb.checked = false;
	});
}
