// scripts/ezMain.js
// ezdonor main javascript lib

// returns the value of a select box
function getSelectValue(element_id) {
	var select_element = document.getElementById(element_id);
	var selected_value = select_element.options[select_element.selectedIndex].value;
	// use 'text' if there is no 'value'
	// (IE will return '' if no value param was used in the option element)
	if (selected_value == '') {
		selected_value = select_element.options[select_element.selectedIndex].text;
	}
	return selected_value;
}

// displays the element with the given id
// returns true if the element exists, false otherwise
function showElement(element_id) {
	var display_element = document.getElementById(element_id);
	if (display_element) { 
		display_element.style.display = '';
		return true;
	}
	return false; // no such object
}

// hides the element with the given id
// returns true if the element exists, false otherwise
function hideElement(element_id) {
	var display_element = document.getElementById(element_id); // the showable/hideable element
	if (display_element) { 
		display_element.style.display = 'none'; // does not work on IE7 select box
		return true;
	}
	return false; // no such object
}

// enables the element with the given id
// returns true if the element exists, false otherwise
function enableElement(element_id) {
	var input_element = document.getElementById(element_id);
	if (input_element) {
		input_element.disabled = false;
		return true;
	}
	return false; // no such object
}

// disables the element with the given id
// returns true if the element exists, false otherwise
function disableElement(element_id) {
	var input_element = document.getElementById(element_id);
	if (input_element) {
		input_element.disabled = true;
		return true;
	}
	return false; // no such object
}

// selects the element with the given id (a checkbox or radio button)
// returns true if the element exists, false otherwise
// if the button is not checked and fire_on_click is true, will fire the onClick message associated with the button
function selectElement(element_id, fire_on_click) {
	var selection_element = document.getElementById(element_id);
	if (selection_element && ((selection_element.type == 'checkbox') || (selection_element.type == 'radio'))) { 
		if ((fire_on_click) && (!selection_element.checked)) {
//			selection_element.click(); // safari does not have this method, so do the following
			if (selection_element.onclick) {
			   selection_element.checked = !selection_element.checked;
			   selection_element.onclick.call(selection_element);
			}
		}
		else {
			selection_element.checked = true;
		}
		return true;
	}
	return false; // no such object (or wrong type)
}

// deselects the element with the given id (a checkbox or radio button)
// returns true if the element exists, false otherwise
// if the button is checked and fire_on_click is true, will fire the onClick message associated with the button
function deselectElement(element_id, fire_on_click) {
	var selection_element = document.getElementById(element_id);
	if (selection_element && ((selection_element.type == 'checkbox') || (selection_element.type == 'radio'))) { 
		if ((fire_on_click) && (selection_element.checked)) {
//			selection_element.click(); // safari does not have this method, so do the following
			if (selection_element.onclick) {
			   selection_element.checked = !selection_element.checked;
			   selection_element.onclick.call(selection_element);
			}
		}
		else {
			selection_element.checked = false;
		}
		return true;
	}
	return false; // no such object (or wrong type)
}

// shows or hide the element with the given element id
// based on the given checkbox/radio button selection
// for checkboxes, a checked box is considered to mean 'show'
// for radio buttons, a checked button, if it does not have the provided no_value, is considered to mean 'show'
function optionallyShowHideElement(button, display_element_id, no_value) {
	if (button.checked && (button.value != no_value)) {
		showElement(display_element_id);
	}
	else {
		hideElement(display_element_id);
	}
}


// helper function to enable/disable groups
// calls enableGroup() if enable parameter is true
// calls disableGroup() if enable parameter is false
// can be called from checkbox inputs with: enableDisableGroup(this.checked, element_id)
function enableDisableGroup(enable, element_id) {
	if (enable) {
		enableGroup(element_id);
	}
	else {
		disableGroup(element_id);
	}
}

// enables all input elements within a grouping element (e.g. div or tagle)
// displays group if it is hidden
// any stored values in these inputs will be submitted along with the form
function enableGroup(element_id) {
  // show the group
  showElement(element_id);

  var group = document.getElementById(element_id);
  //  alert('enabling group: ' + element_id);

  // disable inputs
  try {
	var inputs = group.getElementsByTagName('input');
    for (var i=0; i<inputs.length; i++) {
	  inputs[i].disabled=false;
    }
  }
  // catch error if tag is not defined (i.e. no inputs)
  catch (err) {
	  // do nothing
  }
  // enable select boxes
  try {
    var selects = group.getElementsByTagName('select');
	for (var i=0; i<selects.length; i++) {
	  var element = selects[i];
	  element.disabled=false;
	}
  }
  // catch error if tag is not defined (i.e. no selects)
  catch (err) {
	  // do nothing
  }
  // enable text areas
  try {
    var textareas = group.getElementsByTagName('textarea');
    for (var i=0; i<textareas.length; i++) {
	  var element = textareas[i];
	  element.disabled=false;
    }
  }
  // catch error if tag is not defined (i.e. no textareas)
  catch (err) {
	  // do nothing
  }

}

// disables all input elements within a grouping element (e.g. div or table)
// hides the group if it is visible
// any stored values in these inputs will not be submitted with the form
function disableGroup(element_id) {
  // hide the group
  hideElement(element_id);

  var group = document.getElementById(element_id);
  //  alert('disabling group: ' + element_id);

  // disable inputs
  try {
    var inputs = group.getElementsByTagName('input');
    for (var i=0; i<inputs.length; i++) {
	  inputs[i].disabled=true;
    }
  }
  // catch error if tag is not defined (i.e. no inputs)
  catch (err) {
	  // do nothing
  }
  // disable select boxes
  try {
	var selects = group.getElementsByTagName('select');
	for (var i=0; i<selects.length; i++) {
	  var element = selects[i];
	  element.disabled=true;
	}
  }
  // catch error if tag is not defined (i.e. no selects)
  catch (err) {
	  // do nothing
  }
  // disable text areas
  try {
    var textareas = group.getElementsByTagName('textarea');
    for (var i=0; i<textareas.length; i++) {
  	  var element = textareas[i];
	  element.disabled=true;
    }
  }
  // catch error if tag is not defined (i.e. no textareas)
  catch (err) {
	  // do nothing
  }
}

// changes sections
// validates current section (if validate is true), hides current section, shows new section
function changeSection(this_section, new_section, validate) {
  // validate this section
  if ((!validate) || (validateSection(this_section))) {
	if (new_section == '') {
	  return true; // submit the form if this is the last section
	}
	// otherwise
	hideElement(this_section); // hide this section
	showElement(new_section);  // show the next section
  }
  return false; // do not submit the page if not successfully validated
}


// this function is called when a ticket block menu changes (e.g. when an item is selected)
// it can be overridden at the client account level in case an action should be taken
function menuChanged(element) {
	return true; // default action is null
}

// this function can be overridden at the client account level
function validateSection(section_id) {
	return true; // default is no validation
}

// validates the given hash of fields
// expects hash in the form { element_id : text_field_name, ... }
// returns true if all fields are valid (not empty), false otherwise
// displays error message with invalid field names
// validation can be disabled by setting validation_on to false
function validateFields(fields_to_validate, validation_on) {
	var errors = "Please provide the following information:\n\n";
	var success = true;
	for (var element_id in fields_to_validate) {
		var element = document.getElementById(element_id);
		// handle select boxes separately
		if (element.type == 'select') {
			//TODO: review this
			if (getValue(element_id) == null) {
				errors += fields_to_validate[element_id] + "\n";
				success = false;
			}
		}
		// TODO: handle radio/checkboxes here
		// handle textboxes
		else if (!fieldNotEmpty(element)) {
			errors += fields_to_validate[element_id] + "\n";
			success = false;
		}
	}
	if ((validation_on) && (!success)) {
		alert(errors);
		return false;
	}
	return true;
}


// validates the given hash of US phone fields (usually only one)
// expects hash in the form { element_id : text_field_name, ... }
// returns true if all fields are valid (not empty), false otherwise
// displays error message with invalid field names
// validation can be disabled by setting validation_on to false
function validateUSCAPhones(phones_to_validate, validation_on) {
	var errors = "Please provide a valid ten-digit phone number (e.g. 312-555-1212) in: \n";
	var success = true;
	for (var element_id in phones_to_validate) {
		if (!validUSCAPhoneNumber(document.getElementById(element_id))) {
			errors += phones_to_validate[element_id] + "\n";
			success = false;
		}
	}

	if ((validation_on) && (!success)) {
		alert(errors);
		return false;
	}
	return true;
}

// validates the given hash of US zip code fields (rarely more than one)
// expects hash in the form { element_id : text_field_name, ... }
// returns true if all fields are valid (not empty), false otherwise
// displays error message with invalid field names
// validation can be disabled by setting validation_on to false
function validateUSCAZips(zips_to_validate, validation_on) {
	var errors = "Please provide a valid 5- or 9-digit zip code in: \n";
	var success = true;
	for (var element_id in zips_to_validate) {
		if (!validUSZip(document.getElementById(element_id))) {
			errors += zips_to_validate[element_id] + "\n";
			success = false;
		}
	}

	if ((validation_on) && (!success)) {
		alert(errors);
		return false;
	}
	return true;
}

// validates the given hash of email fields (usually only one)
// expects hash in the form { element_id : text_field_name, ... }
// returns true if all fields are valid email addresses, false otherwise
// displays error message with invalid field names
// validation can be disabled by setting validation_on to false
function validateEmails(emails_to_validate, validation_on) {
	var errors = "Please provide a valid email address (e.g. mailbox@maildomain.com) in: \n";
	var success = true;
	for (var element_id in emails_to_validate) {
		if (!validEmail(document.getElementById(element_id))) {
			errors += emails_to_validate[element_id] + "\n";
			success = false;
		}
	}

	if ((validation_on) && (!success)) {
		alert(errors);
		return false;
	}
	return true;
}

// returns true if any ticket has been selected, returns false otherwise
// used to validate ticket selections
// ticket input elements must have the name "tickets^..." or "ticket_grouping^..."
function ticketsSelected() {
	// inputs
    var inputs = document.Form.getElementsByTagName('input');
	var pattern = /^ticket(s|_grouping)\^/;
    for (var i=0; i<inputs.length; i++) {
		if (inputs[i].name.match(pattern)) {
//alert(inputs[i].name);
			if (inputs[i].checked && !inputs[i].disabled) {
				return true; // only need one selected ticket
			}
		}
    }
	// select boxes
    var selects = document.Form.getElementsByTagName('select');
	for (i=0; i<selects.length; i++) {
		if (selects[i].name.match(pattern)) {
		   if (selects[i].selectedIndex != '') {
//alert(selects[i].name + ' ' + selects[i].selectedIndex + ' ' + selects[i].value);
			  return true;
		   }
		}
	}
	return false; // no tickets selected
}

// sets the required x_exp_date field for authorize.net
function setANFields() {
	setANChecksum();
	setANExpirationDate();
}


// sets the checksum value required by ezdonor
function setANChecksum() {
    var n = document.getElementById('x_card_num');
	if (n) {
	   var c = n.value.substring(n.value.length-4);
	   add_input_field(document.Form, 'hidden', 'post_checksum', c);
	}
}


// sets the required x_exp_date field for authorize.net
function setANExpirationDate() {
    var exp_month_field = document.getElementById('x_exp_month');
	if (exp_month_field) {
	   var month = getSelectValue('x_exp_month');
	   var year = getSelectValue('x_exp_year');
	   var exp_date = month + year.substring(2);
	   add_input_field(document.Form, 'hidden', 'x_exp_date', exp_date);
	}
}

// compensates for the IE failure to post an image button type's name
// (which breaks code that branches on the submit button's name)
function handle_ie_image_button(form_object, button_name, button_value) {
	add_input_field(form_object, 'hidden', button_name, button_value);
}

// adds a new form element with the given attributes to the given form
function add_input_field(form_object, field_type, field_name, field_value){
  if(form_object) {
    var input = document.createElement('INPUT');
    if(document.all) {
      input.type = field_type;
	  input.name = field_name;
	  input.value = field_value;
	} 
	else if(document.getElementById) {
	  input.setAttribute('type', field_type);
	  input.setAttribute('name', field_name);
	  input.setAttribute('value', field_value);
	}
	form_object.appendChild(input);
  }
}

// handler for selection of recurring gift frequency
// accepts number of payments per year
// updates the selection box for number of payments to limit payments to 5 years
function changeRecurringGiftFrequency(old_frequency, new_frequency) {
	var max_years = 5;
	var max_payments = new_frequency * max_years;
    var select_box = document.getElementById('gift_frequency^payments');

	// set new number of payments to the equivalent time period from the old selections
	var old_payments = getSelectValue('gift_frequency^payments');
	if (old_frequency == null) { old_frequency = old_payments; } // default to one year
	var new_payments = Math.round(new_frequency * old_payments / old_frequency);
	//alert('old freq: ' + old_frequency + ' new freq: ' + new_frequency + ' old pays: ' + old_payments + ' new pays: ' + new_payments);

	// check limits
	if (new_payments < 2) { 
	   new_payments = 2;
	}
	else if (new_payments > max_payments) {
	   new_payments = max_payments;
	}
	var index = new_payments - 2;
	select_box[index].selected = true;

	// enabled/disable selections appropriately
	for (i=0; i<select_box.length; i++) {
		if (i < max_payments-1) {
		   select_box[i].disabled = false;
		}
		else {
		   select_box[i].disabled = true;
		}
	}
}

// enables recurring gift selection boxes if the 'recurring' radio button is clicked
// disables them if the 'one-time' button is clicked (default)
function enableDisableRecurringGifts(selection) {
    var select_box1 = document.getElementById('gift_frequency^frequency');
    var select_box2 = document.getElementById('gift_frequency^payments');
	if (selection == 'recurring') {
	   select_box1.disabled = false;
	   select_box2.disabled = false;
	}
	else {
	   select_box1.disabled = true;
	   select_box2.disabled = true;
	}
}


// TODO: move reusable validate_payment_form.js methods here
// fieldNotEmpty(field) ...


