function fetch_field(form_name, field_name){
	var el_name = "document.forms['" + form_name + "']" + ".elements['" + field_name + "']";
	return eval(el_name);
}

function fetch_field_value(form_name, field_name){
	var field = fetch_field(form_name, field_name);
	var field_val = "";
	if (field == undefined) return field_val;
	if (field.type == "text" || field.type == "textarea" || field.type == "hidden"){
		field_val = field.value;
	} else if (field.type == "select" || field.type == "select-one"){
		field_val = field[field.selectedIndex].value;
	} else if (field.type == "checkbox"){
		// set to checkbox value only if checked, otherwise blank
		if (field.checked) field_val = field.value;
	} else if (field.type == "radio"){
		// pick the selected radio button
		for (var i=0; i<field.length; i++){
			if (field[i].checked){
				field_val = field[i].value;
			}
		}
	}
	return field_val;
}

function set_field_val(form_name, field_name, field_val){
	var field = fetch_field(form_name, field_name);
	if (field != undefined) field.value = field_val;
}

function get_selected_by_val(sel_field, val){
	if (!(sel_field && sel_field.options)) return 0;
	for (var i=0; i<sel_field.options.length; i++){
		if (sel_field.options[i].value == val) return i;
	}
	return 0;
}

function get_selected_by_label(sel_field, val){
	if (!(sel_field && sel_field.options)) return 0;
	for (var i=0; i<sel_field.options.length; i++){
		if (sel_field.options[i].label == val) return i;
	}
	return 0;
}

// set a value and submit a form (useful for changing a form's action)
function set_and_submit(form_name, field_name, field_val){
	set_field_val(form_name, field_name, field_val);
	if (!(document.forms[form_name])) return false;
  if (document.forms[form_name].onsubmit){
    if (document.forms[form_name].onsubmit()){
      document.forms[form_name].submit();
    }
  } else {
    document.forms[form_name].submit();
  }
  return false;
}

// initialize a swapper control (two multi-select boxes whose contents can be moved back and forth)
// params are the name of the form, the name of the left box, the name of the right box, and an array of items to be used as options
// array[0] should be the option label, array[1] should be the option value, array[2] indicates in which box to appear (0 == left, 1 == right), and
// array[3] indicates whether the item was originally in the left or right box (0 == left, 1 == right), so that we can change its style to indicate it has been moved 
function swapper_init(form_name, lname, rname, items){
	var lfield = fetch_field(form_name, lname);
	var rfield = fetch_field(form_name, rname);
	if (lfield == undefined || rfield == undefined) return;
	lcount = 0;
	rcount = 0;
	lfield.options.length = 0;
	rfield.options.length = 0;
	for (var i=0; i<items.length; i++){
		if (items[i][2]){
			//rfield.options.length = rcount+1;
			rfield.options[rcount] = new Option(items[i][0], items[i][1], false, false);
			if (items[i][2] != items[i][3]){
				rfield.options[rcount].style.color = 'green';
				rfield.options[rcount].style.fontWeight = 'bold';
			} else {
				rfield.options[rcount].style.color = 'black';
				rfield.options[rcount].style.fontWeight = 'normal';
			}
			rcount++;
		} else {
			//lfield.options.length = lcount+1;
			lfield.options[lcount] = new Option(items[i][0], items[i][1], false, false);
			if (items[i][2] != items[i][3]){
				lfield.options[lcount].style.color = 'green';
				lfield.options[lcount].style.fontWeight = 'bold';
			} else {
				lfield.options[lcount].style.color = 'black';
				lfield.options[lcount].style.fontWeight = 'normal';
			}
			lcount++;
		}
	}
}

// move all selected elements from one field to the other
function swap_selected(form_name, lname, rname, move_dir, items, items_index){
	var lfield = fetch_field(form_name, lname);
	var rfield = fetch_field(form_name, rname); 

	if (lfield == undefined || rfield == undefined) return;
	if (move_dir == "lr"){
		src = 0;
		dest = 1;
		loop_field = lfield;
	} else if (move_dir == "rl"){
		src = 1;
		dest = 0;	
		loop_field = rfield;
	}

	// indicate which array the selected elements should belong to
	for (var i=0; i<loop_field.options.length; i++){
		var item_id = loop_field.options[i].value;
		var label_index = items_index['id_' + item_id];
		if (loop_field.options[i].selected){
			items[label_index][2] = dest;
		} else {
			items[label_index][2] = src;
		}
	}

	// in order to maintain the original ordering, rebuild the options of both fields
	swapper_init(form_name, lname, rname, items);
}	

// move all elements from one field to the other
function swap_all(form_name, lname, rname, move_dir, items, items_index){
	var lfield = fetch_field(form_name, lname);
	var rfield = fetch_field(form_name, rname);

	if (lfield == undefined || rfield == undefined) return;

	if (move_dir == "lr"){
		src = 0;
		dest = 1;
		loop_field = lfield;
	} else if (move_dir == "rl"){
		src = 1;
		dest = 0;
		loop_field = rfield;
	}

	for (var i=0; i<loop_field.options.length; i++){
		var item_id = loop_field.options[i].value;
		var label_index = items_index['id_' + item_id];
		items[label_index][2] = dest;
	}

	// in order to maintain the original ordering, rebuild the options of both fields
	swapper_init(form_name, lname, rname, items);
}

// select all elements in a select-multiple
function select_all(form_name, field_name){
	var my_field = fetch_field(form_name, field_name);
	if (my_field == undefined || !my_field.type) return;
	if (my_field.type == "select-multiple" || (my_field.type == "select" && myfield.multiple)){
		for (var i=0; i<my_field.length; i++){
			my_field.options[i].selected = true;
		}
	}
}

// enables or disables an batch of controls
// fields_enable is a bool indicating whether they're enabled/disabled, true being enabled
// fields is an array of control ids. If an ID is a container, then all of its children
// are enabled/disabled
// callback is a function you can call to handle any extra enabling/disabling
function swap_all_enabled(form_name, fields_enable, fields, callback){
	for(var i=0; i<fields.length; i++) {
		var field = fetch_field(form_name, fields[i]);
		if (field != null && field != undefined) {
			field.disabled = (!fields_enable);
		}
	}
	
	// Call our callback
	(callback || function() { })(fields_enable,fields);	
}


// Modify the array prototype to allow the inArray function
function inArray (array, value) {
	var i;
	for (i=0; i < array.length; i++) {
		if (array[i] === value) {
			return true;
		}
	}
	return false;
}

function disable_field(field, val, on_class, off_class){
	if (!field) return false;
	field.disabled = val;
	if (!off_class) off_class = on_class;
	if (val && off_class){
		field.className = off_class;
	} else if (!val && on_class){
		field.className = on_class;
	}
	return true;
}

// enable all input elements on a form, so that their values can be submitted and properly set
function enable_all(form_name){
	if (!document.forms[form_name]) return;
	for (var i=0; i<document.forms[form_name].elements.length; i++){
		var el = document.forms[form_name].elements[i];
		if (el.type == "checkbox" || el.type == "radio" || el.type == "text" || el.type == "textarea" || el.type == "select-one" || el.type == "select-multiple"){
			if (el.disabled) el.disabled = false;
		}
	}
}

// xor
function xor(val1, val2){
	return ((val1 && !val2) || (!val1 && val2));
}
