/*

* @package  CheckInput

* @author    evgenij

*

* @version 2.0

*/

/*

* Add event by object

*

* @param <object> element - object for witch created event

* @param <string> eventType - type of event (without prefix 'on')

* @param <function> fn - function witch was process event

*/

function addEvent(obj, eventType, fn) {

	if (obj.addEventListener) {

		obj.addEventListener(eventType, fn, false);

		return true;

	} else if (obj.attachEvent) {

		var r = obj.attachEvent('on' + eventType, fn);

		return r;

	} else {

		obj['on' + eventType] = fn;

	}

}

/*********************************** BEGIN of definitions of CheckElement **************************

**********/

/*

* Constructor of CheckElement

*

* @param <object> oForm - parent form object

* @param <array> oInput - array of element properties

		['id', <string>] - define element by id

		['name', <string>] - define element by name

		['validator', <string1>, <string2>] - define validate function <strin1> with error message <string2

>

		['modificator', <string1>, <string2>] - define modify function <strin2> on <string1> action

		[<string1>, <string2>] - set element property <string1> to <string2> (like 'error_block')

*/

function CheckElement(oForm, oInput) {

	this.id = '';

	this.name = '';

	this.obj = '';

	this.state = true;

	this.form = oForm;



	this.__ValidateFunctions      = [];

	this.__ValidateMassage        = [];

	this.__validateIndex          = 0;

	this.__OnKeyupModifyFunctions = [];

	this.__onKeyupIndex           = 0;

	this.__OnBlurModifyFunctions  = [];

	this.__onBlurIndex            = 0;

	this.__PropertyNames          = [];

	this.__PropertyValues         = [];

	this.__propertyIndex          = 0;

	this.initialize(oForm, oInput);

	this.defaultSettings();

}

/*

* Set element property

*

* @param <string> propertyName - property name

* @param <string> propertyValeu - property value

*/

CheckElement.prototype.setProperty = function(propertyName, propertyValue) {

	if (false == this.getProperty(propertyName)) {

		this.__PropertyNames[this.__propertyIndex]  = propertyName;

		this.__PropertyValues[this.__propertyIndex] = propertyValue;

		this.__propertyIndex++;

	} else {

		for (var i in this.__PropertyNames) {

			if (propertyName == this.__PropertyNames[i]) {

				this.__PropertyValues[i] = propertyValue;

			}

		}

	}

}

/*

* Get element property

*

* @param <string> propertyName - property name

*

* @return <string> propertyValue or `false`, if element haven't such property

*/

CheckElement.prototype.getProperty = function(propertyName) {

	for (var i in this.__PropertyNames) {

		if (propertyName == this.__PropertyNames[i]) {

			return this.__PropertyValues[i];

		}

	}

	return false;

}

/*

* Make initialization of elements

*/

CheckElement.prototype.initialize = function(oForm, oInput) {

	oInput = oInput || [];

	for (var i in oInput) {

		if ('object' == typeof oInput[i]) {

			switch (oInput[i][0]) {

				case 'id':

					this.id = oInput[i][1];

					this.obj = (document.getElementById(this.id)) ? document.getElementById(this.id) : this.obj;

					break;

				case 'name':

					this.name = oInput[i][1];

					this.obj = (oForm.elements[this.name]) ? oForm.elements[this.name] : this.obj;

					break;

				case 'validator':

					this.__ValidateFunctions[this.__validateIndex] = oInput[i][1];

					this.__ValidateMassage[this.__validateIndex]   = oInput[i][2];

					this.__validateIndex++

					break;

				case 'modificator':

					switch (oInput[i][1]) {

						case 'keyup':

							this.__OnKeyupModifyFunctions[this.__onKeyupIndex] = oInput[i][2];

							this.__onKeyupIndex++

							break;

						case 'blur':

							this.__OnBlurModifyFunctions[this.__onBlurIndex] = oInput[i][2];

							this.__onBlurIndex++

							break;

					}

					break;

				default:

					this.setProperty(oInput[i][0], oInput[i][1]);

					break;

			}

		}

	}

}

/*

* make default settings (for error_block, )

*/

CheckElement.prototype.defaultSettings = function() {

	if (false == this.getProperty('error_block')) {

		this.setProperty('error_block', 'er_'+this.name);

	}

	if (false == this.getProperty('error_hint')) {

		this.setProperty('error_hint', 'er_hint_'+this.name);

	}

	if (false == this.getProperty('ok_hint')) {

		this.setProperty('ok_hint', 'ok_hint_'+this.name);

	}

}

/*

* Check is Element initialized correctly

*

* @return true/false

*/

CheckElement.prototype.isCorrect = function() {

	return ('object' == typeof this.obj);

}

/*

* Simulate onKeyup event on current element

*/

CheckElement.prototype.onKeyupModify = function() {

	var beforeModifyValue = this.obj.value;

	var objectValue = this.obj.value;

	for (var i in this.__OnKeyupModifyFunctions) {

		eval('objectValue = '+this.__OnKeyupModifyFunctions[i]+'(objectValue);');

	}

	if (beforeModifyValue != objectValue) {

		this.obj.value = objectValue;

	}

	if (this.state == false) {

		this.Validate();

	}

}

/*

* Simulate onBlur event on current element

*/

CheckElement.prototype.onBlurModify = function() {

	var beforeModifyValue = this.obj.value;

	var objectValue = this.obj.value;

	for (var i in this.__OnBlurModifyFunctions) {

		eval('objectValue = '+this.__OnBlurModifyFunctions[i]+'(objectValue);');

	}

	if (beforeModifyValue != objectValue) {

		this.obj.value = objectValue;

	}

	this.Validate();

}

CheckElement.prototype.renew = function() {



	this.obj = this.form.elements[this.name];



}

CheckElement.prototype.getName = function() {



	return this.name;



}

/*

* Provide validation of current element

*/

CheckElement.prototype.Validate = function() {

	this.renew();



	var objectValue = this.obj.value;

	for (var i in this.__ValidateFunctions) {

		eval('var result = '+this.__ValidateFunctions[i]+'(objectValue);');

		if (!result) {

			this.validationFailure(i);

			this.state = false;

			return false;

		}

	}

	this.validationSuccess();

	return true;

}

/*

* On validation failure action

*/

CheckElement.prototype.validationFailure = function(validateIndex) {

	var show_mode = this.getProperty('show_mode') ? 1 : 0;

	if (obj_id = this.getProperty('error_block')) {

		if (obj = document.getElementById(obj_id)) {

			obj.innerHTML     = this.__ValidateMassage[validateIndex];

			obj.style.display = show_mode ? 'visible' : 'block';

		}

	}

	if (obj_id = this.getProperty('error_hint')) {

		if (obj = document.getElementById(obj_id)) {

			obj.style.display = show_mode ? 'visible' : 'block';

		}

	}

	if (obj_id = this.getProperty('ok_hint')) {

		if (obj = document.getElementById(obj_id)) {

			obj.style.display = show_mode ? 'hidden' : 'none';

		}

	}

}

/*

* On validation success action

*/

CheckElement.prototype.validationSuccess = function() {

	var show_mode = this.getProperty('show_mode') ? 1 : 0;

	if (obj_id = this.getProperty('error_block')) {

		if (obj = document.getElementById(obj_id)) {

			obj.innerHTML     = "";

			obj.style.display = show_mode ? 'hidden' : 'none';

		}

	}

	if (obj_id = this.getProperty('error_hint')) {

		if (obj = document.getElementById(obj_id)) {

			obj.style.display = show_mode ? 'hidden' : 'none';

		}

	}

	if (obj_id = this.getProperty('ok_hint')) {

		if (obj = document.getElementById(obj_id)) {

			obj.style.display = show_mode ? 'visible' : 'block';

		}

	}



}

/*********************************** END of definitions of CheckElement ****************************

********/

/*********************************** BEGIN of definitions of CheckInput ****************************

********/

/*

* Constructor of CheckInput

*

* @param <array> oForm - array of [formName, after_submit_function_name, before_submit_fuction_name]

* @param <array> oInput - array of arrays wich used for creating CheckElement

*/

function CheckInput(oForm, oInput) {

	this.form            = '';

	this.beforeSubmitFunction        = '';

	this.afterSubmitFunction         = '';

	this.onValidationFailureFunction = '';

	this.onValidationSuccessFunction = '';

	this.__Elements = [];

	this.__index = 0;

	this.initialize(oForm, oInput);

	var oThis = this;

	this._onBlur   = function (e) { oThis.onBlur(e);   };

	this._onKeyup  = function (e) { oThis.onKeyup(e);  };

	this._onSubmit = function (e) { oThis.onSubmit(e); };

	for (i in this.__Elements) {

		Element = this.__Elements[i];

		addEvent(Element.obj, "blur",  this._onBlur);

		addEvent(Element.obj, "keyup", this._onKeyup);

	}

	addEvent(this.form, 'submit', this._onSubmit);

}

/*

* Make initialization

*/

CheckInput.prototype.initialize = function(oForm, oInput) {

	for (var i in oForm) {

		if ('object' == typeof oForm[i]) {

			switch (oForm[i][0]) {

				case 'name':

					eval("this.form=document."+oForm[i][1]+";");

					break;

				case 'before_submit_function':

					this.beforeSubmitFunction = oForm[i][1];

					break;

				case 'after_submit_function':

					this.afterSubmitFunction = oForm[i][1];

					break;

				case 'on_validation_failure':

					this.onValidationFailureFunction = oForm[i][1];

					break;

				case 'on_validation_success':

					this.onValidationSuccessFunction = oForm[i][1];

					break;

			}

		}

	}

	oInput = oInput || [];

	for (var i in oInput) {

		if ('object' == typeof oInput[i]) {

			NewElement = new CheckElement(this.form, oInput[i]);

			if ( NewElement.isCorrect() ) {

				this.__Elements[this.__index++] = NewElement;

			}

		}

	}

}

/*

* onSubmit process function

* Run 'before_submit_function', run checkForm: if success - submit form, run 'after_submit_function'

; else - stop submiting

*/

CheckInput.prototype.onSubmit =  function(e) {

	eval(this.beforeSubmitFunction+"();");

	if (!this.validate()) {

		if (e.preventDefault) {

			e.preventDefault();

		} else {

			e.returnValue=false;

		}



	} else {

		eval(this.afterSubmitFunction+"();");

	}

}

CheckInput.prototype.renewElement = function(el) {



	for (var i in this.__Elements) {



		if (el == this.__Elements[i].getName()) {



			this.__Elements[i].renew();



			addEvent(this.__Elements[i].obj, "blur",  this._onBlur);

			addEvent(this.__Elements[i].obj, "keyup", this._onKeyup);



		}



	}



}

/*

* Check form before submit

*

* @return - true or false

*/

CheckInput.prototype.validate = function() {

	var isValidForm = true;



	for (var i in this.__Elements) {

		if ( !this.__Elements[i].Validate() ) {

			isValidForm = false;

		}

	}

	if ( !isValidForm ){

		eval(this.onValidationFailureFunction+'()');

		return false;

	}

	eval(this.onValidationSuccessFunction+'()');

	return true;

}

/*

* get Element

*

* @param <object> el - object

*

* @return <object> - CheckElement object or false, if not found

*/

CheckInput.prototype.getElement = function(el) {

	for (var i in this.__Elements) {

		if ( this.__Elements[i].obj == el) {

			return this.__Elements[i];

		}

	}

	return false;

}

/*

* onBlur process function

*/

CheckInput.prototype.onBlur = function(e) {

	var el = e.target || e.srcElement;

	var Element = this.getElement(el);

	if (false != Element) {

		Element.onBlurModify();

	}

}

/*

* onKeyup process function

*/

CheckInput.prototype.onKeyup = function(e) {

	var el = e.target || e.srcElement;

	var Element = this.getElement(el);

	if (false != Element) {

		Element.onKeyupModify();

	}

}

/*********************************** End of definitions of CheckInput ******************************

******/

function is_not_empty(s) {



	s = s.toString();

	for(i = 0; i < s.length; i++) {

		if(s.charAt(i) != ' ') {

			return true;

		}

	}

	return false;

}

function check_url(s) {

	var reg = new RegExp("[^a-zA-Z_0-9/\]+");

	if (s=='' || reg.test(s)) {

		return false;

	} else {

		return true;

	}

}

function check_urlFull(s) {

	var reg = new RegExp("[^a-zA-Z_0-9/\.\+\%&?=]+");

	if (s=='' || reg.test(s)) {

		return false;

	} else {

		return true;

	}

}

function  custom_cc_num(s){

	if (payFormManager.getCreditCardType() == 'discover') { //display CVV2 field



		document.getElementById("cvv2_text").style.fontWeight = 'bolder';

		document.getElementById("address").style.fontWeight = 'bolder';

		document.getElementById("city").style.fontWeight = 'bolder';

		payFormManager.setRequiredCvv();



	} else if (payFormManager.getCreditCardType() == 'amex') {



		document.getElementById("cvv2_text").style.fontWeight = 'bolder';

		//document.getElementById("address").style.fontWeight = 'bolder';

		//document.getElementById("city").style.fontWeight = 'bolder';

		payFormManager.setRequiredCvv();

	} else {

                document.getElementById("cvv2_text").style.fontWeight = 'normal';

		//document.getElementById("address").style.fontWeight = 'normal';

                //document.getElementById("city").style.fontWeight = 'normal';

		payFormManager.setNotRequiredCvv();

	}

	return s;

}

function cc_num_not_jcb(s) {

	if (payFormManager.getCreditCardType() == 'jcb') {

		return false;

	} else {

		return true;

	}

}

function cc_num_not_discover(s) {

        if (payFormManager.getCreditCardType() == 'discover') {

                return false;

        } else {

                return true;

        }

}

function cc_num_not_master(s) {

        if (payFormManager.getCreditCardType() == 'mastercard') {

                return false;

        } else {

                return true;

        }

}

function cc_num_not_amex(s) {

        if (payFormManager.getCreditCardType() == 'amex') {

                return false;

        } else {

                return true;

        }

}

function removeChars(s) {

	filteredValues = "1234567890";     // Characters stripped out

	var i;

	var returnString = "";

	for (i = 0; i < s.length; i++) {

		var c = s.charAt(i);

		if (filteredValues.indexOf(c) != -1) {

				returnString += c;

		}

	}

	return returnString;

}

function removeNonLatinChars(s) {

	filteredValues = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM,.- \"'/\\()#@1234567890+";



        var i;

        var returnString = "";

        for (i = 0; i < s.length; i++) {

                var c = s.charAt(i);

                if (filteredValues.indexOf(c) != -1) {

                                returnString += c;

                }

        }

        return returnString;

}

function check_email(s) {

	if (/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-zA-Z]{2,6}(?:\.[a-zA-Z]{2})?)$/.test(s

)) {

		return true;

	}

	return false;

}

function cc_exp_m_changed(s) {

	is_cc_exp_m_changed = true;

	return true;

}

function cc_exp_y_changed(s) {

	is_cc_exp_y_changed = true;

	return true;

}

function check_exp_date(s) {

	if (!is_cc_exp_m_changed || !is_cc_exp_y_changed) {

		return true;

	}

	exp_month=document.myForm.cc_exp_m.value.toString();

	exp_year=document.myForm.cc_exp_y.value.toString();

	document.myForm.exp_date.value = exp_year*12 + exp_month;

	if (Number(cur_date) > Number(document.myForm.exp_date.value)) {

		return false;

	} else {

		return true;

	}

}

function check_cvv2(s) {

	if(!payFormManager.isCvvRequired()) return true;

	if ((s == "") || (s.length < 3) || (s.length > 4)) return false;

	return true;

}

function check_cvv2_mastercard_visa_discover(s) {

	if((payFormManager.getCreditCardType() != 'visa') && (payFormManager.getCreditCardType() != 'mastercard'

) && (payFormManager.getCreditCardType() != 'discover')) return true;

	if((s != "") && (s.length != 3)) {

		return false;



	} else {

		return true;



	}

}

function check_cvv2_amex(s) {

        if(payFormManager.getCreditCardType() != 'amex') return true;

	if((s != "") && (s.length != 4)) {

		return false;

	} else {

		return true;

	}

}

function not_empty_for_discover(s) {

	if(payFormManager.getCreditCardType() != 'discover') return true;

	for(i = 0; i < s.length; i++) {

		if(s.charAt(i) != ' ') return true;

	}

	return false;

}

function not_empty_for_amex(s) {

        if(payFormManager.getCreditCardType() != 'amex') return true;

        for(i = 0; i < s.length; i++) {

                if(s.charAt(i) != ' ') return true;

        }

        return false;

}

function NotLessThan5Chars(s) {



	if (5 > s.length) {

		return false;

	}

	return true;

}

function NotLessThan10Chars(s) {

        if (10 > s.length) {

                return false;

        }

        return true;

}

function NotLessThan2Chars(s) {

        if (2 > s.length) {

                return false;

        }

        return true;

}

function check_basic(s) {

	return true;

}

function Mod10(ccNumb) {  // v2.0

	var len = ccNumb.length;  // The length of the submitted cc number

	var iCCN = parseInt(ccNumb);  // integer of ccNumb

	var sCCN = ccNumb.toString();  // string of ccNumb

	sCCN = sCCN.replace (/^\s+|\s+$/g,'');  // strip spaces

	var iTotal = 0;  // integer total set at zero

	var bNum = true;  // by default assume it is a number

	var bResult = false;  // by default assume it is NOT a valid cc

	var temp;  // temp variable for parsing string

	var calc;  // used for calculation of each digit



	if (len < 13) {

		return false;

	}

	for(var i=len;i > 0;i--) {  // LOOP throught the digits of the card

		calc = parseInt(iCCN) % 10;  // right most digit

		calc = parseInt(calc);  // assure it is an integer

		iTotal += calc;  // running total of the card number as we loop - Do Nothing to first digit

		i--;  // decrement the count - move to the next digit in the card

		iCCN = iCCN / 10;  // subtracts right most digit from ccNumb

		calc = parseInt(iCCN) % 10 ;  // NEXT right most digit

		calc = calc *2;  // multiply the digit by two

		// Instead of some screwy method of converting 16 to a string and then parsing 1 and 6 and then adding them to make 7,

		// I use a simple switch statement to change the value of calc2 to 7 if 16 is the multiple.

		switch(calc) {

			case 10: calc = 1; break;       //5*2=10 & 1+0 = 1

			case 12: calc = 3; break;       //6*2=12 & 1+2 = 3

			case 14: calc = 5; break;       //7*2=14 & 1+4 = 5

			case 16: calc = 7; break;       //8*2=16 & 1+6 = 7

			case 18: calc = 9; break;       //9*2=18 & 1+8 = 9

			default: calc = calc;           //4*2= 8 &   8 = 8  -same for all lower numbers

		}

		iCCN = iCCN / 10;  // subtracts right most digit from ccNum

		iTotal += calc;  // running total of the card number as we loop

	}  // END OF LOOP

	if ((iTotal%10)==0) {  // check to see if the sum Mod 10 is zero

		return true;  // This IS (or could be) a valid credit card number.

	} else {

		return false;  // This could NOT be a valid credit card number

	}

}

function cc_num_check(s) {

	var valid_card_types = new Array('visa','mastercard','amex','discover','jcb');



	for (var i in valid_card_types) {

		if (payFormManager.getCreditCardType() == valid_card_types[i]) {

			return true;

		}

	}



	return false;

}

 function trim_string(s) {

	s = s.replace(/^\.*\s*\.*\s*|\.*\s*\.*\s*$/g,"");

	return s;

}

function before_form_submit_function() {

}

function after_form_submit_function() {

}

function on_form_validation_failure() {
	alert('Please correct your details in the field(s)');
}

function on_form_validation_success() {

}
