var SqmForm = {
	sections: Array(),
	hidden_select_boxes: Array(),
	error_field_name: '',
	error: '',
	section_header_class: 'section_header',
	section_header_edit_class: 'section_header_edit',
	section_header_error_class: 'section_header_edit',
	section_header_done_class: 'section_header',
	section_header_mark_class: 'mark_doc',
	section_header_mark_edit_class: 'mark_edit',
	section_header_mark_error_class: 'mark_error',
	section_header_mark_done_class: 'mark_ok',
	error_not_displayed: false,
	is_error: false,
	number_sections: function () {
		var len = this.sections.length;
		for (var i=0 ; i<len ; i++) {
			var cnt = (i+1)+'. ';
			new Insertion.After(this.sections[i].name+'_section_header_mark', cnt);
		}
	},
	get_active_section: function () {
		var len = this.sections.length;
		for (var i=0 ; i<len ; i++) {
			
			if (Element.getStyle(this.sections[i].name+'_section', 'display') != 'none') {
				return this.sections[i].name;
			}

/*			
			alert(this.sections[i].name+'_section is visible: '+ );

			var header_mark = $(this.sections[i].name+'_section_header_mark');
			
			if (header_mark) {
				if (Element.hasClassName(header_mark, this.section_header_mark_edit_class)) {
					return this.sections[i].name;
				}
			}
*/		
		}
				
		return this.sections[0].name;
	},
	remove_section: function (in_var) {
		
		var section = this.get_section(in_var);
		var new_sections = new Array();
		var len = this.sections.length;
		var j = 0;
		for (var i=0 ; i<len ; i++) {
			if (this.sections[i].name == section) {
				Element.hide(this.sections[i].name+'_section_header'); 	// hide the header
				Element.hide(this.sections[i].name+'_section');			// and the section
			} else {
				new_sections[j] = this.sections[i];
				j++;				
			}
		}
		this.sections = new_sections;
		
	},
	get_section: function (in_var) {

		var section = in_var;
		if (in_var.match(/^\d+$/)) {
			section = this.sections[in_var].name;
		}

		return section;
		
	},
	get_section_object: function (in_var) {
		
		var section = this.get_section(in_var);
		var len = this.sections.length;
		
		for (var i=0 ; i<len ; i++) {
			if (this.sections[i].name == section) {
				return this.sections[i];
			}
		}
		
	},
	serialize_child_fields: function (el, field_types) {
		
		if (!$(el)) { alert('error finding section'); return false; }
		
		var pars = '';
		
		for (var i=0 ; i<field_types.length ; i++) {
		
			var fields = $(el).getElementsByTagName(field_types[i]);
			
			for (var i=0 ; i<fields.length ; i++) {

				v = Form.Element.serialize(fields[i]);

				if (v != undefined) {

					if (pars.length > 0) pars += '&';
					pars += v;

				}

			}
			
		}
		
		return pars;
		
	},
	submit_section: function (click_el) {

		if (click_el.id == '') { return false; }
		
		var in_var = click_el.id.replace(/_submit/,'');		
		var section_obj = this.get_section_object(in_var);
		var section = section_obj.name;

		if (!section_obj.validate()) {
			this.mark_section_error(section);
			return false; 
		}
	
		this.mark_section_done(section);
		return this.show_next_section(section);
		
	},
	switch_section: function (click_el) {

		if (!click_el) { return false; }
		if (click_el.id == '') { return false; }
		
		var in_var = click_el.id.replace(/_section_header/,'');
		var section = this.get_section(in_var);
		var active_section = this.get_active_section();
		var active_section_obj = this.get_section_object(active_section);

		this.mark_section_unchanged(active_section);
		this.clear_field_error();
			
		this.show_section(section);
		
	},
	show_section: function (in_var) {
		
		var section = this.get_section(in_var);			
		var section_obj = this.get_section_object(in_var);
		var header = $(section+'_section_header');
		var header_mark = $(section+'_section_header_mark');
		
		if (header_mark) {
			if (header)	header.className = this.section_header_edit_class;
			if (header_mark) header_mark.className = this.section_header_mark_edit_class;
		}
			
		if (Element.getStyle(section+'_section', 'display') == 'none') {
		
			this.hide_sections();
			new Effect.BlindDown(section+'_section', {duration: 0.5, afterFinish: SqmForm.show_undisplayed_errors });
			
		} else {
			
			SqmForm.show_undisplayed_errors();
			
		}
		
		if (section_obj.onshow) {
			section_obj.onshow();
		}
			
	},
	show_undisplayed_errors: function (obj) {
		if (SqmForm.error_not_displayed && SqmForm.is_error) {
			SqmForm.error_not_displayed = false;			
			SqmForm.mark_field_error(SqmForm.error_field_name, SqmForm.error);
		}		
	},
	show_next_section: function (in_var) {
		var section = this.get_section(in_var);
		
		var len = this.sections.length;
		for (var i=0 ; i<len ; i++) {
			if (this.sections[i].name == section) {
				this.show_section(this.sections[i+1].name);
				return this.sections[i+1].name;
				//return true;
			}
		}
				
	},
	hide_sections: function() {
		
		var len = this.sections.length;
		for (var i=0 ; i<len ; i++) {
			if (this.sections[i].nohide != '1') {
				Element.hide(this.sections[i].name+'_section')
			}
		}
		
	},
	mark_section_done: function(in_var) {
		
		var section = this.get_section(in_var);
		var header = $(section+'_section_header');
		var header_mark = $(section+'_section_header_mark');

		if (!header || !header_mark) return false;
		
		header.className = this.section_header_done_class;
		header_mark.className = this.section_header_mark_done_class;
		
	},
	mark_section_error: function(in_var) {
		
		var section = this.get_section(in_var);
		var header = $(section+'_section_header');
		var header_mark = $(section+'_section_header_mark');

		if (!header || !header_mark) return false;
		
		header.className = this.section_header_error_class;
		header_mark.className = this.section_header_mark_error_class;
		
	},
	mark_section_unchanged: function(in_var) {
		
		var section = this.get_section(in_var);
		var header = $(section+'_section_header');
		var header_mark = $(section+'_section_header_mark');
		
		if (!header) return false;
		if (!header_mark) return false;
		
		header.className = this.section_header_class;
		header_mark.className = this.section_header_mark_class;
			
	},
	submit_form: function (form) {
		var last_section;
		var len = this.sections.length;
		this.error_not_displayed = true;
			
		for (var i=0 ; i<len ; i++) {
			
			last_section = this.sections[i].name;

			if (!this.sections[i].validate()) {
				
				this.switch_section($(this.sections[i].name+'_section_header'));
				//this.mark_field_error(this.error_field_name, this.error);
				this.mark_section_error(this.sections[i].name);
				
				return false;
				
			} else {
				this.mark_section_done(this.sections[i].name);
			}
		}
		
		if ($(last_section+'_submit')) {
			Element.hide(last_section+'_submit');
		}
		
		form.submit();
		//alert('This will submit the form.');
		return false;
	},
	reset_errors: function () {
		this.error = '';
		this.error_field_name = '';
		this.is_error = false;
	},
	add_clear_error_onchange: function (field) {
		
		var field_obj = $(field);
		
		if (typeof field_obj.onchange != 'function') {
			field_obj.onchange = function () { SqmForm.clear_field_error(); };
		} else {
			if (typeof field_obj._onchange_original != 'function') {
				field_obj._onchange_original = field_obj.onchange;
			}
			field_obj.onchange = function () { SqmForm.clear_field_error(); this._onchange_original(this); };
		}
		
	},
	mark_field_error: function(field, error) {

		this.error = error;
		this.error_field_name = field;		
		this.is_error = true;

		if ( this.error_not_displayed == true ) {
			return false;
		}
		
		var field_input = field;
		
		// Element.setStyle('flash', { height: '1px' });
		
		// handle field variable with comma in it as array
		if (field.indexOf(',') >= 0) {
			
			var fields = field.split(',');
			var len = fields.length;
			
			for (var i=0 ; i<len ; i++) {
				
				field = fields[i];
				
				var field_obj = $(field);
				
				if (!$(field)) {
					this.error_not_displayed = true;
					return false;
				}

				// work with field to mark it with error indicators
				this.add_clear_error_onchange(field);
				
				Element.addClassName(field, 'field_error');
				
			}

			field = fields[0];
			
			$(field).focus();
			
		} else {
							
			// work with field to mark it with error indicators
			var field_obj = $(field);

			if (!$(field)) {
				this.error_not_displayed = true;
				return false;
			}
						
			field_obj.focus();
						
			this.add_clear_error_onchange(field);
						
			Element.addClassName(field, 'field_error');
			
		}
		
		error += '<div id="close_button"><a href="#" onclick="SqmForm.clear_field_error(); return false;">close</a></div>';
		
		// format flash message to display error
		Element.update('flash_message', error);

		var h = Element.getStyle('flash_message', 'height');
		var w = Element.getStyle('flash', 'width');

		Position.clone(field, 'flash');
		
		Element.setStyle('flash', { width: w });
	 	Element.setStyle('flash', { height: h });

		var posY = Element.getStyle('flash', 'top');
		posY = parseFloat(posY)+25;
		Element.setStyle('flash', { top: posY+'px' });

		Element.show('flash');
		Element.show('flash_message');

		this.hide_select_boxes();
		
		return false;
		
	},
	get_credit_card_field_length: function (cc_type) {
		var fields = new Array();
		
		switch(cc_type) {
			case '1': // Visa
			case '2': // Visa Connect
			case '3': // Visa Delta
				fields = new Array(4, 4, 4, 4);
				break;
			case '4': // Mastercard
				fields = new Array(4, 4, 4, 4);
				break;
			case '5': // American Express
				fields = new Array(4, 6, 5);
				break;
			// case '6': // Switch
			// 	fields = new Array(6, 12);
			// 	break;
			// case '7': // Maestro
			// case '8': // Solo
			// 	fields = new Array(4, 4, 4, 4);
			// 	break;
			case '6': // Switch
			case '7': // Maestro
			case '8': // Solo
				fields = new Array('22');
				break;
			default:			
				fields = new Array('16');
				break;
		}
		
		return fields;
	},
	select_credit_card: function (cc_type, el) {
	
		var field_string = '';
		var fields = this.get_credit_card_field_length(cc_type);
		var len = fields.length;
		var old_number = '';
		
		if ($('cc_field')) {
			var ins = $('cc_field').getElementsByTagName('input');
			for (var i=0 ; i<ins.length ; i++) {
				if (ins[i].name.match(/^cc/)) {
					old_number += ins[i].value;
				}
			}
		}
		
		var start_char = 0;
		
		for (var i=0 ; i<len ; i++) {
			
			if (field_string != '') { field_string += ' &nbsp;&nbsp; '; }
			
			var val = old_number.substr(start_char, fields[i]);
			
			field_string += '<input class="cc_number" type="text" name="cc'+(i+1)+'" value="'+val+'" id="cc'+(i+1)+'" size="'+parseInt(fields[i])+'" maxlength="'+parseInt(fields[i])+'" />';
			
			start_char += parseInt(fields[i]);
			
		}
		field_string += '<br />';
		
		if (cc_type == '6' || cc_type == '7' || cc_type == '8') {  // for switch show the issuer number and start date fields
			if ($('cc_issuer_number_field')) { Element.show('cc_issuer_number_field'); }
			if ($('cc_issue_date_field')) { Element.show('cc_issue_date_field'); }
		} else {
			if ($('cc_issuer_number_field')) { Element.hide('cc_issuer_number_field'); }
			if ($('cc_issue_date_field')) { Element.hide('cc_issue_date_field'); }
		}

		if (len == 0 || cc_type == '') {
			field_string = 'Please select a credit card type';
		}
		
		Element.update(el, field_string);
		
	},
	clear_field_error: function () {
		Element.hide('flash');
		
		if (this.error_field_name != '') {
			
			// handle element names with commas as arrays
			if (this.error_field_name.indexOf(',') >= 0) {
				var els = this.error_field_name.split(',');
				var len = els.length;
				for (var i=0 ; i<len ; i++) {
					Element.removeClassName(els[i], 'field_error');
				}
			} else {
				Element.removeClassName(this.error_field_name, 'field_error');				
			}
		}
		
		this.show_select_boxes();
		
	},
	check_field_error_init: function (in_var) {
		
		if (this.error != '') { return false; } // don't alert user to more than one error
		if (!$(in_var)) { return false; }
		if (Element.getStyle(in_var, 'display') == 'none') { return false; }
	
		return true;
	},
	check_if_empty: function (in_var, msg) {
		
		if (!this.check_field_error_init(in_var)) { return false; }
		
		if ($(in_var).value == '') {
			this.mark_field_error(in_var, msg);
			return false;
		}
		
		return true;
		
	},
	check_if_checked: function (in_var, msg) {
		
		if (!this.check_field_error_init(in_var)) { return false; }
		
		if (!$(in_var).checked) {
			this.mark_field_error(in_var, msg);
			return false;
		}
		
		return true;
		
	},	
	check_length: function (in_var, msg, conf) {

		if (!this.check_field_error_init(in_var)) { return false; }
		
		var value = $F(in_var);
		
		if (value.length < conf.min && conf.min) {
			this.mark_field_error(in_var, msg);
			return false;			
		}
		
		if (value.length > conf.max && conf.max) {
			this.mark_field_error(in_var, msg);
			return false;			
		}
		
		return true;
		
	},
	check_if_email: function (in_var, msg) {
	
		if (!this.check_field_error_init(in_var)) { return false; }
			
		var email_regex_str = "^(([0-9a-zA-Z]+)|([0-9a-zA-Z]+[_.0-9a-zA-Z-]*[0-9a-zA-Z]+))@([a-zA-Z0-9-]+[.])+([a-zA-Z]{1}|[a-zA-Z]{2}|[a-zA-Z]{3}|[a-zA-Z]{4}|[a-zA-Z]{5})$";
		var email_regex = new RegExp(email_regex_str);
		var email_value = $F(in_var);
		
		if (email_value.search(email_regex) == -1) {
			this.mark_field_error(in_var, msg);
			return false;
		} else {
			return true;
		}
			
	},
	check_if_equal: function (in_var, in_var_compare, msg) {
		if (!this.check_field_error_init(in_var)) { return false; }
		if (!this.check_field_error_init(in_var_compare)) { return false; }
		
		if ($(in_var).value != $(in_var_compare).value) {
			this.mark_field_error(in_var, msg);
			return false;
		}
		
		return true;
	},
	check_if_US_zipcode: function (in_var, msg) {

		if (!this.check_field_error_init(in_var)) { return false; }
		
		var zip1 = /^\d{5}$/;
		var zip2 = /^\d{5}\-\d{4}$/;
		$(in_var).value = $(in_var).value.replace(/ /g, '-');		// substitute spaces for dashes
		$(in_var).value = $(in_var).value.replace(/[A-z]/g, '');	// no letters in US zip codes
		
		if ($(in_var).value.match(zip1) == null && $(in_var).value.match(zip2) == null)	{
			this.mark_field_error(in_var, msg);
			return false;			
		}
		
		return true;
	},
	check_if_value_is: function (in_var, msg, conf) {
	
		if (!this.check_field_error_init(in_var)) { return false; }
		
		if ($F(in_var) == conf.value) {
			this.mark_field_error(in_var, msg);
			return false;			
		}
		
		return true;	
	},
	check_if_value_is_date: function (in_var, msg, conf) {
	
		if (!this.check_field_error_init(in_var)) { return false; }
		
		if (!this.is_date($(in_var).value)) {
			this.mark_field_error(in_var, msg);
			return false;			
		}
		
		return true;	
	},
	check_if_date_is_after: function (in_var, msg, conf) {

		if (!this.check_field_error_init(in_var)) { return false; }
		
		if (!conf.date) { return false; }
	
		// do this for European style dates
		var date_to_string;
		
		if (conf.to_date) {
			date_to_string = conf.to_date.replace(/^(\d+)\/(\d+)/, '$2/$1');
		} else {
			date_to_string = $(in_var).value.replace(/^(\d+)\/(\d+)/, '$2/$1');
		}
		
		var date_from_string = conf.date.replace(/^(\d+)\/(\d+)/, '$2/$1');;
		
		var date_to = new Date(date_to_string);
		var date_from = new Date(date_from_string);
		
		if (date_from.valueOf() > date_to.valueOf()) {
			this.mark_field_error(in_var, msg);
			return false;			
		}
		
		return true;	
		
	},
	is_date: function (DateValue) {
		var checkstr = "0123456789";
		var DateTemp = "";
		var seperator = "/";
		var day;
		var month;
		var year;
		var leap = 0;
		var err = 0;
		var i;

		/* Delete all chars except 0..9 */
	   for (i = 0; i < DateValue.length; i++) {
		  if (checkstr.indexOf(DateValue.substr(i,1)) >= 0) {
		     DateTemp = DateTemp + DateValue.substr(i,1);
		  }
	   }
	   DateValue = DateTemp;
	   /* Always change date to 8 digits - string*/
	   /* if year is entered as 2-digit / always assume 20xx */
	   //if (DateValue.length == 6) {
	   //   DateValue = DateValue.substr(0,4) + '20' + DateValue.substr(4,2); }
	   if (DateValue.length != 8) {
	      err = 19;}
	   /* year is wrong if year = 0000 */
	   year = DateValue.substr(4,4);
	   if (year == 0) {
	      err = 20;
	   }
	   /* Validation of month*/
	   month = DateValue.substr(2,2);
	   if ((month < 1) || (month > 12)) {
	      err = 21;
	   }
	   /* Validation of day*/
	   day = DateValue.substr(0,2);
	   if (day < 1) {
	     err = 22;
	   }
	   /* Validation leap-year / february / day */
	   if ((year % 4 == 0) || (year % 100 == 0) || (year % 400 == 0)) {
	      leap = 1;
	   }
	   if ((month == 2) && (leap == 1) && (day > 29)) {
	      err = 23;
	   }
	   if ((month == 2) && (leap != 1) && (day > 28)) {
	      err = 24;
	   }
	   /* Validation of other months */
	   if ((day > 31) && ((month == "01") || (month == "03") || (month == "05") || (month == "07") || (month == "08") || (month == "10") || (month == "12"))) {
	      err = 25;
	   }
	   if ((day > 30) && ((month == "04") || (month == "06") || (month == "09") || (month == "11"))) {
	      err = 26;
	   }

	   if (err == 0) return (true);
	   else return (false);
	},
	check_credit_card_number: function (in_var, msg, conf) {
		
		if (!this.check_field_error_init(in_var+'1')) { return false; }
		
		if (!conf.cc_type) { return false; }
		
		var cc_number = '';
		var fields = this.get_credit_card_field_length(conf.cc_type);
		var len = fields.length;
		var field_elements = '';
		
		for (var i=0; i<len ; i++) {
			if (!$(in_var+(i+1))) {  // the proper credit card boxes are not displayed
				this.select_credit_card(conf.cc_type, in_var+'_field');
				this.mark_field_error(field_elements, msg);
				return false;
			}
			cc_number += $F(in_var+(i+1));
			if (field_elements.length > 0) field_elements += ',';
			field_elements += in_var+(i+1);
		}
		
		if (!cc_number.match(/^[0-9]+$/)) {
			this.mark_field_error(field_elements, msg);
			return false;
		}
		
		if (!this.validate_credit_card_number(cc_number, conf.cc_type)) {
			this.mark_field_error(field_elements, msg);
			return false;
		}
		
		$(in_var).value = cc_number;
		
		return true;
	},
	validate_credit_card_number: function (cc_number, cc_type) {
				
		// check using cc_type and required digits
		var cardLen = cc_number.length;
		var firstdig = cc_number.substring(0,1);
		var seconddig = cc_number.substring(1,2);
		var first4digs = cc_number.substring(0,4);

		switch (cc_type) {		
			case '1': // Visa
			case '2': // Visa Connect
			case '3': // Visa Delta
				if ((cardLen != 16 && cardLen != 13) || firstdig != '4') {
					return false;
				}
				break;
			case '4': // Mastercard
				var validNums = "12345";
				if (cardLen != 16 || firstdig != '5' || validNums.indexOf(seconddig)==-1) {
					return false;
				}
				// return true; // Skip Luhn check
				break;
			case '5': // American Express
				var validNums = "47";
				if (cardLen != 15 || firstdig != '3' || validNums.indexOf(seconddig)==-1) {
					return false;
				}
				break;
			case '6': // Switch
			case '7': // Maestro
			case '8': // Solo
				return true; // Skip Luhn check
				break;
		}
				
		// check using Luhn algorithm
		var result = true;

		var sum = 0;
		var mul = 1;

		for (i = 0; i < cardLen; i++) {
		  var digit = cc_number.substring(cardLen-i-1,cardLen-i);
		  var tproduct = parseInt(digit ,10)*mul;
		  if (tproduct >= 10) sum += (tproduct % 10) + 1;
		  else sum += tproduct;
		  if (mul == 1) mul++;
		  else mul--;
		}
		
		if ((sum % 10) != 0) return false;

		return true;
		
	},
	hide_select_boxes: function () {
		this.show_select_boxes();
		this.hidden_select_boxes = new Array();
		
		var appVer = navigator.appVersion.toLowerCase();
		var iePos = appVer.indexOf('msie');
		if (iePos !=-1) {
			var is_minor = parseFloat(appVer.substring(iePos+5,appVer.indexOf(';',iePos)));
			var is_major = parseInt(is_minor);
		}
		if (navigator.appName.substring(0,9) == "Microsoft") { // Check if IE version is 6 or older
			if (is_major <= 6) {
				var x, y, w, h;
				var selx,sely,selw,selh,i;
				var sel=document.getElementsByTagName("SELECT");

				var flash = $('flash');
				x=Element.findPosX('flash');
				y=Element.findPosY('flash');
				w=flash.offsetWidth;
				h=flash.offsetHeight;
								
				for(i=0;i<sel.length;i++) {
					selx=0;
					sely=0;
					var selp;
					if(sel[i].offsetParent) {
							selp=sel[i];
							while(selp.offsetParent) {
								selp=selp.offsetParent;
								selx+=selp.offsetLeft;
								sely+=selp.offsetTop;
							}
					}
					selx+=sel[i].offsetLeft;
					sely+=sel[i].offsetTop;
					selw=sel[i].offsetWidth;
					selh=sel[i].offsetHeight;
					if(selx+selw>x && selx<x+w && sely+selh>y && sely<y+h) {
						Element.hide(sel[i]);
						this.hidden_select_boxes.push(sel[i]);
					}
				}
			}
		}
	},
	show_select_boxes: function () {
		
		for (var i=0 ; i<this.hidden_select_boxes.length ; i++) {
			
			Element.show(this.hidden_select_boxes[i]);
			
		}
		
	}
};