//asas
PokeYoke = Class.create();
PokeYoke.prototype = {

  	initialize: function(rules) {
  	this.pkykValidationRules = rules;
		this.pkyk = new Object();
		// apply blur event listeners to all fields in the validation rules
		if(pkykConf.checkOnBlur) {
			for (var i in this.pkykValidationRules) {
				var pkykField = null;
				var pkykFields = document.getElementsByName(i);
				for(var z=0; z < pkykFields.length; z++) {
					switch(pkykFields[z].tagName)
					{
					   case "INPUT":
					   case "SELECT":
					   case "TEXTAREA":
					   case "RADIO":
					   case "CHECKBOX":
					       pkykField = pkykFields[z];
					       break;
					}
				}
				if(pkykField)
				{
				    this.registerFieldBlur( pkykField );
				}
				else
				{
				    //alert('You have rules that do not relate to a form field in the current document.');
				}
			}
		}
		// apply submit event listener to forms
		if(pkykConf.checkOnSubmit){
				this.registerFormSubmit(document.forms[pkykForm]);
		}
  	},

	registerFieldBlur: function( pkykField ) {
		Event.observe( pkykField , 'blur', this.checkFieldOnBlur.bind(this), false);
	},

	registerFormSubmit: function( pkykForm ) {

		Event.observe( pkykForm , 'submit', this.checkFormOnSubmit.bind(this), false);
	},

  	checkFieldOnBlur: function(evt) {
		this.validateField(Event.element(evt));
  	},

	checkFormOnSubmit: function(evt) {


		var pkykFormElements = document.forms[pkykForm];
		for (var i = 0; i < pkykFormElements.length; i++)
		{

			// Registration form validation
			if(pkykFormElements.name == 'registration')
			{
				if(pkykFormElements[i].name == 'phone' || pkykFormElements[i].name == 'mobile')
				{
					if(!validateRegister(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
				}
			}

			// Edit user info
			if(pkykFormElements.name == 'register')
			{
				if(pkykFormElements[i].name == 'phone' || pkykFormElements[i].name == 'mobile')
				{
					if(!validateRegister(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
				}
			}

			// Post car form validation -- client & admin side
			if(pkykFormElements.name == 'post_car')
			{
				if(pkykFormElements[i].name == 'vehicle_type' ||  pkykFormElements[i].name == 'first_reg_month' || pkykFormElements[i].name == 'first_reg_year'  ||  pkykFormElements[i].name == 'price_ask' || pkykFormElements[i].name == 'bestsold' || pkykFormElements[i].name == 'power' || pkykFormElements[i].name == 'co2_emission' || pkykFormElements[i].name == 'top_speed' || pkykFormElements[i].name == 'acceleration' || pkykFormElements[i].name == 'consumption1' || pkykFormElements[i].name == 'consumption2' || pkykFormElements[i].name == 'consumption3' || pkykFormElements[i].name == 'engine_size' || pkykFormElements[i].name == 'mileage' || pkykFormElements[i].name == 'id_drive_type' || pkykFormElements[i].name == 'fuel_type' || pkykFormElements[i].name == 'mot_new' || pkykFormElements[i].name == 'mot_month' || pkykFormElements[i].name == 'mot_year' || pkykFormElements[i].name == 'id_domicile' || pkykFormElements[i].name == 'id_town')
				{
					if(!validatePostCar(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
				}
			}

			// Post bike form validation -- client & admin side
			if(pkykFormElements.name == 'post_bike')
			{
				if(pkykFormElements[i].name == 'price_ask' || pkykFormElements[i].name == 'bestsold' ||  pkykFormElements[i].name == 'id_domicile' || pkykFormElements[i].name == 'id_town')
				{
					if(!validatePostBike(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
				}
			}

			// Post purchase bike form validation -- client & admin side
			if(pkykFormElements.name == 'post_purchase_bike')
			{
				if(pkykFormElements[i].name == 'price_ask')
				{
					if(!validatePostPurchaseBike(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
				}
			}

				// Post house form validation -- client & admin side
			if(pkykFormElements.name == 'post_house')
			{
				if(pkykFormElements[i].name == 'composition' || pkykFormElements[i].name == 'rooms' || pkykFormElements[i].name == 'build_year' || pkykFormElements[i].name == 'introduction'|| pkykFormElements[i].name == 'area' || pkykFormElements[i].name == 'id_domicile'|| pkykFormElements[i].name == 'id_town'|| pkykFormElements[i].name == 'part_of_town' || pkykFormElements[i].name == 'street_address'|| pkykFormElements[i].name == 'postal_code' || pkykFormElements[i].name == 'post_office'|| pkykFormElements[i].name == 'floors' || pkykFormElements[i].name == 'price'|| pkykFormElements[i].name == 'debts_sales_price' || pkykFormElements[i].name == 'maintenance'|| pkykFormElements[i].name == 'rent_warranty' || pkykFormElements[i].name == 'water_payment'|| pkykFormElements[i].name == 'id_build_ground' || pkykFormElements[i].name == 'ground_area'|| pkykFormElements[i].name == 'id_condition' || pkykFormElements[i].name == 'heating'|| pkykFormElements[i].name == 'renovation' || pkykFormElements[i].name == 'building_material'|| pkykFormElements[i].name == 'availability_info' || pkykFormElements[i].name == 'kitchen_acc'|| pkykFormElements[i].name == 'bathroom_acc' || pkykFormElements[i].name == 'floor'|| pkykFormElements[i].name == 'share_number' || pkykFormElements[i].name == 'share_numbers'|| pkykFormElements[i].name == 'care_equivalent' || pkykFormElements[i].name == 'fin_equivalent'|| pkykFormElements[i].name == 'no_of_apt' || pkykFormElements[i].name == 'build_right'|| pkykFormElements[i].name == 'ground_build_right')
				{
					if(!validatePostHouse(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
				}
			}

			// Send link form validation
			if(pkykFormElements.name == 'sendlink')
			{
				if(pkykFormElements[i].name == 'friend_email')
				{
					if(!validateSendLink(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
				}
			}

			// Send link form validation in service_index
			if(pkykFormElements.name == 'service_sendlink')
			{
				if(pkykFormElements[i].name == 'friend_email')
				{
					if(!validateServiceSendLink(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
				}
			}

			// Feedback form validation
			if(pkykFormElements.name == 'feedback')
			{
				if(pkykFormElements[i].name == 'first_name' || pkykFormElements[i].name == "email" || pkykFormElements[i].name == "mobile")
				{
					if(!validateFeedback(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
				}
			}

			// Add dealer form validation
			if(pkykFormElements.name == 'addDealer')
			{
				if(pkykFormElements[i].name == 'phone' || pkykFormElements[i].name == "mobile" || pkykFormElements[i].name == "loginid" || pkykFormElements[i].name == "passwd" || pkykFormElements[i].name == "confirm_passwd")
				{
					if(!validateAddDealer(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
				}
			}

			// Frm_user form validation
			if(pkykFormElements.name == 'frm_user')
			{
				if(pkykFormElements[i].name == 'phone' || pkykFormElements[i].name == "mobile")
				{
					if(!validateUserForm(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
				}
			}

			// Post boat validation -- client & admin side
			if(pkykFormElements.name == 'post_boat')
			{
				if(pkykFormElements[i].name == "mfg_year" || pkykFormElements[i].name == "price_ask" || pkykFormElements[i].name == "bestsold" || pkykFormElements[i].name == "id_eng_make" || pkykFormElements[i].name == "boat_type" || pkykFormElements[i].name == "id_domicile" || pkykFormElements[i].name == "id_town" || pkykFormElements[i].name == "regno" || pkykFormElements[i].name == "total_owner")
				{
					if(!validatePostBoat(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
				}
			}


			// Post item form validation -- client & admin side
			if(pkykFormElements.name == 'post_item')
			{
				if(pkykFormElements[i].name == 'price' || pkykFormElements[i].name == 'id_item_section' || pkykFormElements[i].name == 'id_domicile' || pkykFormElements[i].name == 'id_town')
				{
					if(!validatePostItem(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
				}
			}

				// Post purchase item form validation -- client & admin side
			if(pkykFormElements.name == 'post_purchase_item')
			{
				if(pkykFormElements[i].name == 'price' || pkykFormElements[i].name == 'id_item_section' || pkykFormElements[i].name == 'id_domicile' || pkykFormElements[i].name == 'id_town')
				{
					if(!validatePostPurchaseItem(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
				}
			}


			// Post boat validation -- client & admin side
			if(pkykFormElements.name == 'addServices')
			{

				if(pkykFormElements[i].name == "address" || pkykFormElements[i].name == "zip" || pkykFormElements[i].name == 'id_sub_cat[]' || pkykFormElements[i].name == 'date_upto')
				{

					if(pkykFormElements[i].name == 'id_sub_cat[]')
					{
						continue;
					}

					if(validateAddServices(pkykFormElements[i],this) == false)
					{
						Event.stop(evt);
						return false;
					}
					else if(pkykFormElements[i].name == "date_upto")
					{
						return true;
					}

				}
			}

			// Post banner validation
			if(pkykFormElements.name == 'banner')
			{
				if(pkykFormElements[i].name == 'img')
				{
					if(!validateBanner(pkykFormElements[i],this))
					{
						Event.stop(evt);
						return false;
					}
					else
					   return true;
				}
			}

			if(!this.validateField(pkykFormElements[i]))
			{
				Event.stop(evt);
				return false;
			}

		}


		if(pkykFormElements.length == 0)
		{
			Event.stop(evt);
			return false;
		}

	},


	validateField: function(target)
	{

		// reset values for each iteration
		var required = false;
		var elementError = false;
		var errorMsg = '';
		var targetName = target.name;
		var targetValue = this.trim( $F(target) );
		if(target.disabled)
		{
			// if the imput is disabled quit function
			return;
		}


		// if a validation rule exists
		if(this.pkykValidationRules[target.name])
		{

			if (pkykConf.debug)
			{
				target.focus();
				alert(target.name + ' is being validated');
				return true;
			}


			if(this.pkykValidationRules[target.name]['required'])
			{
				required = this.pkykValidationRules[target.name]['required'];
			}

			// If the field is required test for a at least one character
			if(required)
			{

				if (!targetValue.match(/.+/))
				{

					errorMsg = this.pkykValidationRules[target.name]['required_msg'];
					elementError = true;
					this.renderInlineError( target, errorMsg );
					target.focus();
					target.addClassName('error_box');
					return false;
				}
				else{
					target.removeClassName('error_box');
					errorMsg = '';
					elementError = false;
				}
			}

			var validators = this.pkykValidationRules[target.name]['validators'];


			if(validators != undefined && !elementError)
			{

				for (var validatorName in validators) {

					// try to create a validator object
					try {
						eval('validator = new '+validatorName+'()');
					} catch (e) {
						//alert('Unknown validatior :: '+validatorName);
						continue;
					}

					// Attache a standard initialization method
					validator.initialize = function(parameters) {
						try {
							for(var parameter in parameters) {
								this[parameter] = parameters[parameter];
							}
						} catch(e) {}
					}

					// Initialize parameters
					if(this.pkykValidationRules[target.name]['validators'][validatorName]['parameters'])
					{
						validator.initialize(this.pkykValidationRules[target.name]['validators'][validatorName]['parameters']);
					}

					// Validate
					errorMsg = validator.execute(targetValue);

					if(errorMsg) {
	    				elementError = true;
	    				this.renderInlineError( target, errorMsg );
	    				target.focus();
	    				$(target.name).addClassName('error_box');
						return false;
	    				continue;
					}
					else
					{
						$(target.name).removeClassName('error_box');
						this.removeErrors( target );
						return true;
					}

				}
			}
			else
			{
				this.removeErrors( target );
				target.removeClassName('error_box');
				return true;
			}

			if(elementError) {
				// set global error array with this key to the correct values
				this.pkyk[targetName] = {
					target: target,
					errorMsg: errorMsg
				};
				this.renderInlineError( target, errorMsg );
				$(target.name).addClassName('error_box');
				target.focus();
			} else {
	   			this.removeErrors( target );
	   			$(target.name).removeClassName('error_box');
			}
		}
		else
		{
			return true;
		}
  	},

	renderInlineError: function(target, msg)
	{
		// test config settings
		// This  has been removed to display error for both on submit and inline
		//if(pkykConf.displayBlurInlineErrors){
			var pkykErrorNode = $( pkykConf.inlineErrorId + target.name );
			if( pkykErrorNode ) {
				pkykErrorNode.innerHTML = pkykConf.errorPrefix + msg + pkykConf.errorSuffix;
				pkykErrorNode.show();
			} else {
				new Insertion.After( target, '<div id="'+ pkykConf.inlineErrorId + target.name + '" class="' + pkykConf.inlineErrorClass + '">' + msg + '</div>' );
			}
		//}
	},

	renderGlobalErrors: function( pkykForm )
	{
		if (pkykConf.displaySubmitGlobalErrors && Object.values(this.pkyk).length > 0)
		{
			if($('pkykGlobalErrors'))
			{
				$('pkykGlobalErrors').remove();
			}
			var pkykGlobalStr = '';
			var pkykGlobalErrorTitle = ( pkykConf.globalErrorTitle.length > 0 ) ? '<p class="'+pkykConf.globalErrorTitleClass+'">'+pkykConf.globalErrorTitle+'</p>' : '';

			if( Object.values(this.pkyk).length > 0 )
			{
				for (var i = 0; i < Object.values(this.pkyk).length; i++) {
					var pkykFieldname = Object.values(this.pkyk)[i].target.name;
					var pkykErrorStr = pkykConf.errorPrefix + Object.values(this.pkyk)[i].errorMsg + pkykConf.errorSuffix;
					pkykGlobalStr += '<li class="'+pkykConf.globalErrorClass+'" id="pkykGlobal_' + pkykFieldname + '">' + pkykErrorStr + '</li>';
				}

				new Insertion.Top( pkykForm, '<div id="pkykGlobalErrors">' + pkykGlobalErrorTitle + '<ul>' + pkykGlobalStr + '</ul></div>' );
			}

			if( pkykConf.globalErrorFocus && $( 'pkykGlobalErrors' ) )
			{
				var vListItems = $( 'pkykGlobalErrors' ).getElementsByTagName('li');
				for (var i = 0; i < vListItems.length; i++)
				{
					Event.observe( vListItems[i] , 'click', this.getFieldFocus.bind(this), false);
				}
			}
		}
	},

	removeErrors: function(target)
	{
		if( $( pkykConf.inlineErrorId + target.name ))
		{
			$( pkykConf.inlineErrorId + target.name ).innerHTML = '';
			$( pkykConf.inlineErrorId + target.name ).hide();
		}

		if( $( 'pkykGlobal_' + target.name ) )
		{
			var pkykGlobalListItem = $( 'pkykGlobal_' + target.name );
			Element.remove(pkykGlobalListItem);
		}

		if(this.pkyk[target.name])
		{
			delete this.pkyk[target.name];
		}

		if(Object.values(this.pkyk).length == 0 && $('pkykGlobalErrors'))
		{
			$('pkykGlobalErrors').remove();
		}
	},

	getFieldFocus: function(evt)
	{
		var target = Event.element( evt );
		var targetId = target.id;
		var targetField = $(targetId.replace(/pkykGlobal_/,''));
		if(targetField)
		{
			targetField.scrollTo();
			//targetField.focus();
			Field.focus(targetField);
		}
	},

	trim: function(value)
	{
		cleanValue = '';
		if(value)
		{
			cleanValue = value.gsub(/^\s+/, '');
			cleanValue = cleanValue.gsub(/\s+$/, '');
		}

		return cleanValue;
	},


}


/* Validators */

/**
 * sfStringValidator allows you to apply string-related constraints to a
 * parameter.
 *
 * Optional parameters:
 *
 * # insensitive  - [false]              - Whether or not the value check
 *                                                against the array of values is
 *                                                case-insensitive. Note:
 *                                                When using this option, values
 *                                                in the values array must be
 *                                                entered in lower-case.
 * # max          - [none]               - Maximum string length.
 * # max_error    - [Input is too long]  - An error message to use when
 *                                                input is too long.
 * # min          - [none]               - Minimum string length.
 * # min_error    - [Input is too short] - An error message to use when
 *                                                input is too short.
 * # values       - [none]               - An array of values the input
 *                                                is allowed to match.
 * # values_error - [Invalid selection]  - An error message to use when
 *                                                input does not match a value
 *                                                listed in the values array.
 */

/* Constructor */
var sfStringValidator=function() {
	this.insensitive = false;
	this.max = null;
	this.max_error = "Input is too long";
	this.min = null;
	this.min_error = "Input is too short";
	this.values = null;
	this.values_error = "Invalid selection";
}

/* Validation method */
sfStringValidator.prototype.execute=function(value) {
	if ((this.min != null) && (value.length < this.min)) {
		// too short
		return this.min_error;
	}

	if ((this.max != null) && (value.length > this.max)) {
		// too long
		return this.max_error;
	}

	if(this.values != null) {
		for(i = 0; i < this.values.length; i++) {
			if((this.insensitive?(this.values[i].toLowerCase()):(this.values[i])) == (this.insensitive?(value.toLowerCase()):(value))) {
				return false;
			}
		}

		return this.values_error;
	}

	return false;
}

/**
 * sfNumberValidator verifies a parameter is a number and allows you to apply
 * size constraints.
 *
 * Optional parameters:
 *
 * # max        - [none]                  - Maximum number size.
 * # max_error  - [Input is too large]    - An error message to use when
 *                                                 input is too large.
 * # min        - [none]                  - Minimum number size.
 * # min_error  - [Input is too small]    - An error message to use when
 *                                                 input is too small.
 * # nan_error  - [Input is not a number] - Default error message when
 *                                                 input is not a number.
 * # type       - [Any]                   - Type of number (Any, Float).
 * # type_error - [Wrong input] - An error message to use when
 *                                                 input is not a number.
 */

/* Constructor */
var sfNumberValidator=function() {
	this.max = null;
	this.max_error = "Input is too large";
	this.min = null;
	this.min_error = "Input is too small";
	this.nan_error = "Input is not a number";
	this.type = "any"; // 'any', 'decimal', 'float', 'int', 'integer'
	this.type_error = "Wrong input";
}

/* Validation method */
sfNumberValidator.prototype.execute=function(value) {
	if(isNaN(value)) {
		return this.nan_error;
	}

	iValue = parseInt(value, 10);
	fValue = parseFloat(value);

	if((this.type == 'int') || (this.type == 'integer')) {
		if(fValue != iValue) {
			return this.type_error;
		}
		pValue = iValue;
	} else {
		pValue = fValue;
	}

	if((this.min != null) && (pValue < this.min)) {
		return this.min_error;
	}

	if((this.max != null) && (pValue > this.max)) {
		return this.max_error;
	}

	return false;
}

/**
 * sfRegexValidator allows you to match a value against a regular expression
 * pattern.
 *
 * Required parameters:
 *
 * # pattern - [none] - A PCRE, preg_match() style regular expression
 *                             pattern.
 *
 * Optional parameters:
 *
 * # match       - [true]          - Indicates that the pattern must be
 *                                          matched or must not match.
 * # match_error - [Invalid input] - An error message to use when the
 *                                          input does not meet the regex
 *                                          specifications.
 */

/* Constructor */
var sfRegexValidator=function() {
	this.match = true;
	this.match_error = "Invalid input";
	this.pattern = null;
}

/* Validation method */
sfRegexValidator.prototype.execute=function(value) {
	if(this.pattern != null) {
		match = Boolean(this.match);
		pos = 0;
		unescaped = "";
		while(pos < this.pattern.length) {
			c = this.pattern.charAt(pos);
			if (c == "\\") {
				pos++;
			}
			try {
				unescaped += this.pattern.charAt(pos);
			} catch(e) {}
			pos++;
		}

		try {
			eval("regExp = "+unescaped);
			value = String(value);
			if((value.match(regExp) && match) || (!value.match(regExp) && !match)) {
				return false;
			} else {
				return this.match_error;
			}
		} catch(e) {
			return false;
		}
	} else {
		return false;
	}
}

/**
 * sfEmailValidator verifies a parameter contains a value that qualifies as an
 * email address.
 *
 * Optional parameters:
 *
 * # email_error - [Invalid input] - An error message to use when the
 *                                          input is not an email address
 */

/* Constructor */
var sfEmailValidator=function() {
	this.email_error = "Invalid input";
}

sfEmailValidator.prototype.execute=function(value) {
	regExp  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})$|^$/;
	if (regExp.test(value)) {
		return false;
	} else {
		return this.email_error;
	}
}


/**
 * sfCompareValidator checks the equality of two different request parameters.
 *
 * Required parameters:
 *     check:          field2
 *
 * Optional parameters:
 * # compare_error - [The values you entered do not match. Please try again.] -
 *                           An error message to use when the fields do not match
 */

/* Constructor */
var sfCompareValidator=function() {
	this.check = null;
	this.compare_error = "The values you entered do not match. Please try again";
}

sfCompareValidator.prototype.execute=function(value) {
	if(this.check != null) {
		check_field = document.getElementById(this.check);
		if(check_field != null) {
			check_value = check_field.value;
			if(check_value != value) {
				return this.compare_error;
			}
		}
	}

	return false;
}

/**
 * sfUrlValidator verifies a parameter contains a value that qualifies as an
 * url address.
 *
 * Optional parameters:
 *
 * # url_error - [Invalid input] - An error message to use when the
 * input is not an email address
 */


/* Constructor */

var sfUrlValidator=function() {
	this.url_error = 'Please enter a correctly formatted url';
}

sfUrlValidator.prototype.execute=function(value) {
	regExp  = /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)|^$/i;
	if (regExp.test(value)) {
		return false;
	} else {
		return this.url_error;
	}
}