var K_Validation = new Class({
	options: {
		language: 'dk',
		fieldSelectors: 'input, select, textarea',
		showToolTip: true,
		evaluateOnSubmit: true,
		evaluateFieldsRealTime: true,
		evaluateFieldsRewrite: true
	},

	initialize: function(form, options){

		this.setOptions(options);

		try {
			this.form = $(form);
			if(this.options.evaluateOnSubmit) {
				this.form.addEvent('submit', this.onSubmit.bind(this));
			}
			
			if (this.options.showToolTip) {
				this.addToolTip();
			}

			if (this.options.evaluateFieldsRewrite) {
				this.addRewrite();
			}			
			
			if (this.options.evaluateFieldsRealTime) {
				this.addWarning();
			}
			
			this.translate(this.options.language);
			
		} catch (e) {
			// console.log('Error: %s', e);
		}
	},

	getFields: function () {
		return this.fields = this.form.getElementsBySelector(this.options.fieldSelectors)
	},

	getDimension: function (el) {
		var el_dimensions = $(el).getCoordinates();

		var object_top		= el_dimensions.top - 6;
		var object_left 	= el_dimensions.left + el_dimensions.width + 10;
		var object_right	= el_dimensions.left - 10;

		return [object_left, object_top, object_right];
	},

	getMax: function (validators, validator) {
		if (validators.test('' + validator +'-(max-([0-9]+))')) {
			var match_array = validators.match('' + validator +'-(max-([0-9]+))');
			return match_array[2];
		} else if (validators.test('' + validator +'-min-[0-9]+-(max-([0-9]+))')) {
			var match_array = validators.match('' + validator +'-min-[0-9]+-(max-([0-9]+))');
			return match_array[2];
		} else {
			return 0;
		}
	},

	getMin: function (validators, validator) {
		if (validators.test('' + validator +'-(min-([0-9]+))')) {
			var match_array = validators.match('' + validator +'-(min-([0-9]+))');
			return match_array[2];
		} else if (validators.test('' + validator +'-max-[0-9]+-(min-([0-9]+))')) {
			var match_array = validators.match('' + validator +'-max-[0-9]+-(min-([0-9]+))');
			return match_array[2];
		} else {
			return 0;
		}
	},	

	getEqual: function (validators, validator) {
		if (validators.test('' + validator +'-(equal-([0-9]+))')) {
			var match_array = validators.match('' + validator +'-(equal-([0-9]+))');
			return match_array[2];
		} else {
			return 0;
		}
	},	
	
	onSubmit: function (event) {
		if(this.options.evaluateOnSubmit == false) {
			if (typeof(event) == 'undefined') {
				this.form.submit();
				return;
			}
		}
		
		var dirty = false;
		this.getFields().each(function(el) {
			var field_value = el.getValue();
			var validators = el.className;

			if (validators.test('validate-required') && !field_value) {
				dirty = true;
				this.showError(el, this.l_required);
			} else if (field_value) {

				var valid_number_reg_exp = /^\d+$/i;
				var valid_decimal_reg_exp = /^\d+(\.|,)?(\d+)?$/i;
				var valid_alpha_reg_exp = /^[a-zA-Z]+$/i;
				var valid_alphanum_reg_exp = /^\w+$/i;

				var valid_time_12_reg_exp = /^([0-9]|1[0-2]):[0-5][0-9]\s(am|pm)$/i;
				var valid_time_24_reg_exp = /^([0-1][0-9]|2[0-3]):([0-5][0-9])$/i;
				var valid_date_dk_reg_exp = /^([0-2][0-9]|3[0-1])\/(0[0-9]|1[0-2])\/[0-9]{4}$/i;
				var valid_date_us_reg_exp = /^(0[0-9]|1[0-2])\/([0-2][0-9]|3[0-1])\/[0-9]{4}$/i;
				var valid_date_db_reg_exp = /^[0-9]{4}-(0[0-9]|1[0-2])-([0-2][0-9]|3[0-1])$/i;

				var valid_email_reg_exp = /\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/i;
				var valid_url_reg_exp = /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i;
				var valid_hex_color_reg_exp = /^#[a-f0-9]{2}[a-f0-9]{2}[a-f0-9]{2}$/i;
				var valid_rgb_color_reg_exp = /^((0|1[0-9]{0,2}|2[0-9]{0,1}|2[0-4][0-9]|25[0-5]|[3-9][0-9]{0,1}),){2}((0|1[0-9]{0,2}|2[0-9]{0,1}|2[0-4][0-9]|25[0-5]|[3-9][0-9]{0,1}))$/i;
				var valid_ip_reg_exp = /^((0|1[0-9]{0,2}|2[0-9]{0,1}|2[0-4][0-9]|25[0-5]|[3-9][0-9]{0,1})\.){3}(0|1[0-9]{0,2}|2[0-9]{0,1}|2[0-4][0-9]|25[0-5]|[3-9][0-9]{0,1})$/i;

				// REGEXP
				// FILE EXTENSION
			
				var validate_field = true;

				var valid_condition_reg_exp = /validate-if-([a-z]+)/i;
				if (validators.test(valid_condition_reg_exp)) {
					var match_array = validators.match(valid_condition_reg_exp);
					
					validate_field = ($(match_array[1]).getValue()) ? true : false;
				}
				
				var valid_compare_reg_exp = /validate-compare-([a-z]+)/i;
				if (validators.test(valid_compare_reg_exp)) {
					var match_array = validators.match(valid_compare_reg_exp);
					
					if (field_value != $(match_array[1]).getValue()) {
						dirty = true;
						validate_field = false;
						this.showError(el, this.l_compare.replace('[field]', match_array[1]));
					}
				}				
				
				if (validate_field == true) {
				
					var equal_length = this.getEqual(validators, '[a-z0-9]+');
					var max_length	 = this.getMax(validators, '[a-z0-9]+');
					var min_length	 = this.getMin(validators, '[a-z0-9]+');
	
					if (equal_length > 0 && field_value.length != equal_length) {
						dirty = true;
						this.showError(el, this.l_equal.replace('[0-9]', equal_length));
	
					} else if (max_length > 0 && field_value.length > max_length) {
						dirty = true;
						this.showError(el, this.l_max.replace('[0-9]', max_length));
	
					} else if (min_length > 0 && field_value.length < min_length) {
						dirty = true;
						this.showError(el, this.l_min.replace('[0-9]', min_length));
	
					} else if (validators.test('validate-number') && !field_value.test(valid_number_reg_exp)) {
						dirty = true;
						this.showError(el, this.l_number);
	
					} else if (validators.test('validate-decimal') && !field_value.test(valid_decimal_reg_exp)) {
						dirty = true;
						this.showError(el, this.l_decimal);
	
					} else if (validators.test('validate-alpha\s') && !field_value.test(valid_alpha_reg_exp)) {
						dirty = true;
						this.showError(el, this.l_alpha);
	
					} else if (validators.test('validate-alphanum') && !field_value.test(valid_alphanum_reg_exp)) {
						dirty = true;
						this.showError(el, this.l_alphanum);
	
					} else if (validators.test('validate-time-12') && !field_value.test(valid_time_12_reg_exp)) {
						dirty = true;
						this.showError(el, this.l_time_12);
	
					} else if (validators.test('validate-time-24') && !field_value.test(valid_time_24_reg_exp)) {
						dirty = true;
						this.showError(el, this.l_time_24);
	
					} else if (validators.test('validate-date-dk') && !field_value.test(valid_date_dk_reg_exp)) {
						dirty = true;
						this.showError(el, this.l_date_dk);
	
					} else if (validators.test('validate-date-us') && !field_value.test(valid_date_us_reg_exp)) {
						dirty = true;
						this.showError(el, this.l_date_us);
	
					} else if (validators.test('validate-date-db') && !field_value.test(valid_date_db_reg_exp)) {
						dirty = true;
						this.showError(el, this.l_date_db);
	
					} else if (validators.test('validate-email') && !field_value.test(valid_email_reg_exp)) {
						dirty = true;
						this.showError(el, this.l_email);
	
					} else if (validators.test('validate-url') && !field_value.test(valid_url_reg_exp)) {
						dirty = true;
						this.showError(el, this.l_url);
	
					} else if (validators.test('validate-hex-color') && !field_value.test(valid_hex_color_reg_exp)) {
						dirty = true;
						this.showError(el, this.l_hex_color);
	
					} else if (validators.test('validate-rgb-color') && !field_value.test(valid_rgb_color_reg_exp)) {
						dirty = true;
						this.showError(el, this.l_rgb_color);
	
					} else if (validators.test('validate-ip') && !field_value.test(valid_ip_reg_exp)) {
						dirty = true;
						this.showError(el, this.l_ip);
					}
				}
			}
		}.bind(this));

		if (dirty == false) {
			if (typeof(event) == 'undefined') {
				this.form.submit();
			}
		} else {
			if (typeof(event) != 'undefined') {
				new Event(event).stop();	
			}
		}
	},

	/*
	Adding Tool Tip
	*/
	addToolTip: function () {

		this.getFields().each(function(el) {

			if (el.getProperty('title')) {
				var msg = el.getProperty('title');

				el.addEvent('focus', function () {
					this.showToolTip(el, msg);
				}.bind(this));
			}

			if (el.getProperty('rel')) {
				var msg = el.getProperty('rel');

				el.addEvent('focus', function () {
					this.showToolTip(el, msg);
				}.bind(this));
			}
			
			if (el.getProperty('title')) {
				el.setProperty('rel', el.getProperty('title'));
				el.removeProperty('title');
			}
			
		}.bind(this));
	},

	/*
	Adding Rewrite
	*/
	addRewrite: function () {

		this.getFields().each(function(el) {
			var validators = el.className

			/*
			Rewriting URL
			*/
			if (validators.test('validate-url')) {
				var valid_http_reg_exp = /^([f|h|t|p|s]{3,5})?(.*?)([A-Z0-9][A-Z0-9_-]*)(.*)/i;

				el.addEvent('change', function (event) {
					var field_value = el.getValue().clean();

					if (field_value) {
						var match_array = field_value.match(valid_http_reg_exp);
						el.value  = 'http://' + match_array[3] + match_array[4];
					}
				}.bind(this));
			}

			/*
			Rewriting HEX COLOR
			*/
			if (validators.test('validate-hex-color')) {
				var valid_hex_color_reg_exp = /^(#)?([a-z0-9])([a-z0-9])([a-z0-9])([a-z0-9])?([a-z0-9])?([a-z0-9])?(.*)$/i;
				var valid_hex_color_guess_reg_exp = /^(#)?([a-z0-9]{1,2})(\.|\:|,|-|;|\/)([a-z0-9]{1,2})(\.|\:|,|-|;|\/)([a-z0-9]{1,2})(.*)$/i;
				var valid_rgb_reg_exp = /^([0-9]{1,3})(\.|\:|,|-|;|\/)([0-9]{1,3})(\.|\:|,|-|;|\/)([0-9]{1,3})(.*)$/i
				var valid_rgb_guess_reg_exp = /[0-9]{9}/i

				el.addEvent('change', function (event) {
					var field_value = el.getValue().clean();
					
					if ((field_value.test('(.*)(#)(.*)') && field_value.test(valid_hex_color_guess_reg_exp)) || (field_value.test(valid_hex_color_guess_reg_exp) && field_value.test('(.*)[a-z](.*)'))) {
						var match_array = field_value.match(valid_hex_color_guess_reg_exp);
						field_value_new = '#';

						r_string_1 = match_array[2].substring(0, 1);
						r_string_2 = (match_array[2].substring(1, 2)) ? match_array[2].substring(1, 2) : match_array[2].substring(0, 1);

						g_string_1 = match_array[4].substring(0, 1);
						g_string_2 = (match_array[4].substring(1, 2)) ? match_array[4].substring(1, 2) : match_array[4].substring(0, 1);

						b_string_1 = match_array[6].substring(0, 1);
						b_string_2 = (match_array[6].substring(1, 2)) ? match_array[6].substring(1, 2) : match_array[6].substring(0, 1);

						[r_string_1, r_string_2, g_string_1, g_string_2, b_string_1, b_string_2].each(function (character){
							field_value_new += (character.test('[a-f0-9]')) ? character : 'f';
						});
					} else if (field_value.test(valid_rgb_reg_exp)) {
						var match_array = field_value.match(valid_rgb_reg_exp);

						rgb_value = "rgb("+ ((match_array[1].toInt() > 255) ? 255 : match_array[1]) +","+ ((match_array[3].toInt() > 255) ? 255 : match_array[3]) +","+ ((match_array[5].toInt() > 255) ? 255 : match_array[5]) +")";
						field_value_new = rgb_value.rgbToHex();
					} else if (field_value.test(valid_hex_color_reg_exp) && !field_value.test(valid_rgb_guess_reg_exp)) {
						var match_array = field_value.match(valid_hex_color_reg_exp);

						field_value_new = '#';
						if (match_array[1] == '#' && field_value.length == 4) {
							[match_array[2], match_array[3], match_array[4]].each(function (character){
								field_value_new += (character.test('[a-f0-9]')) ? character+character : 'ff';
							});
						} else if (field_value.length == 3) {
							[match_array[2], match_array[3], match_array[4]].each(function (character){
								field_value_new += (character.test('[a-f0-9]')) ? character+character : 'ff';
							});
						} else {
							[match_array[2], match_array[3], match_array[4], $pick(match_array[5], 'f'), $pick(match_array[6], 'f'), $pick(match_array[7], 'f')].each(function (character){
								field_value_new += (character.test('[a-f0-9]')) ? character : 'f';
							});
						}
					} else if (field_value.test(valid_rgb_guess_reg_exp)) {
						rgb_value = "rgb("+ ((field_value.substring(0, 3).toInt() > 255) ? 255 : field_value.substring(0, 3)) +","+ ((field_value.substring(3, 6).toInt() > 255) ? 255 : field_value.substring(3, 6)) +","+ ((field_value.substring(6, 9).toInt() > 255) ? 255 : field_value.substring(6, 9)) +")";
						field_value_new = rgb_value.rgbToHex();
					} else {
						field_value_new = '';
					}

					el.value = field_value_new.toUpperCase();
				}.bind(this));
			}

			/*
			Rewrite RGB COLOR
			*/
			if (validators.test('validate-rgb-color')) {
				var guess_hex_color_reg_exp = /^(#)?([a-z0-9]{1,2})([a-z0-9]{1,2})([a-z0-9]{1,2})$/i;
				var valid_hex_color_reg_exp = /^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i;

				var guess_rgb_reg_exp = /^(0|1[0-9]{0,2}|2[0-9]{0,1}|2[0-4][0-9]|25[0-5]|[3-9][0-9]{0,1})(\.|\:|,|-|;|\/)(0|1[0-9]{0,2}|2[0-9]{0,1}|2[0-4][0-9]|25[0-5]|[3-9][0-9]{0,1})(\.|\:|,|-|;|\/)(0|1[0-9]{0,2}|2[0-9]{0,1}|2[0-4][0-9]|25[0-5]|[3-9][0-9]{0,1})$/i

				el.addEvent('change', function (event) {
					var field_value = el.getValue().clean();
					var field_value_new = '';
					
					if (field_value.test(guess_rgb_reg_exp)) {
						var match_array = field_value.match(guess_rgb_reg_exp);
						field_value_new	= match_array[1] + ',' + match_array[3] + ',' + match_array[5];
					} else if (field_value.test(valid_hex_color_reg_exp)) {
						var match_array = field_value.match(valid_hex_color_reg_exp);
						var hex_value = '#' + match_array[1] + match_array[2] + match_array[3];
						field_value_new = hex_value.hexToRgb(true);
					} else if (field_value.test('(.*)(#|[a-z])(.*)')) {
						
						var match_array = field_value.match(guess_hex_color_reg_exp);
						var hex_value = '#';

						r_string_1 = match_array[2].substring(0, 1);
						r_string_2 = (match_array[2].substring(1, 2)) ? match_array[2].substring(1, 2) : match_array[2].substring(0, 1);

						g_string_1 = match_array[3].substring(0, 1);
						g_string_2 = (match_array[3].substring(1, 2)) ? match_array[3].substring(1, 2) : match_array[3].substring(0, 1);

						b_string_1 = match_array[4].substring(0, 1);
						b_string_2 = (match_array[4].substring(1, 2)) ? match_array[4].substring(1, 2) : match_array[4].substring(0, 1);

						[r_string_1, r_string_2, g_string_1, g_string_2, b_string_1, b_string_2].each(function (character){
							hex_value += (character.test('[a-f0-9]')) ? character : 'f';
						});
						
						field_value_new = hex_value.hexToRgb(true);
					} else {
						
						var field_value_tmp = '';
						field_value.split('').each(function (character) {
							field_value_tmp += (character.test('[0-9]')) ? character : '';
						});
						
						if (field_value_tmp.length == 9) {
							var r = (field_value_tmp.substring(0, 3) > 255) ? 255 : field_value_tmp.substring(0, 3);
							var g = (field_value_tmp.substring(3, 6) > 255) ? 255 : field_value_tmp.substring(3, 6);
							var b = (field_value_tmp.substring(6, 9) > 255) ? 255 : field_value_tmp.substring(6, 9);
							
							field_value_new	= r + ',' + g + ',' + b;
						} else if (field_value_tmp.length == 8) {
							var r = (field_value_tmp.substring(0, 3) > 255) ? 255 : field_value_tmp.substring(0, 3);
							var g = (field_value_tmp.substring(3, 6) > 255) ? 255 : field_value_tmp.substring(3, 6);
							
							field_value_new	= r + ',' + g + ',' + field_value_tmp.substring(6, 8);
						} else if (field_value_tmp.length == 7) {
							var r = (field_value_tmp.substring(0, 3) > 255) ? 255 : field_value_tmp.substring(0, 3);
							field_value_new	= r + ',' + field_value_tmp.substring(3, 5) + ',' + field_value_tmp.substring(5, 7);
						} else if (field_value_tmp.length == 6) {
							field_value_new	= field_value_tmp.substring(0, 2) + ',' + field_value_tmp.substring(2, 4) + ',' + field_value_tmp.substring(4, 6);
						} else if (field_value_tmp.length == 5) {
							field_value_new	= field_value_tmp.substring(0, 2) + ',' + field_value_tmp.substring(2, 4) + ',' + field_value_tmp.substring(4, 5);
						} else if (field_value_tmp.length == 4) {
							field_value_new	= field_value_tmp.substring(0, 2) + ',' + field_value_tmp.substring(2, 3) + ',' + field_value_tmp.substring(3, 4);
						} else if (field_value_tmp.length == 3) {
							field_value_new	= field_value_tmp.substring(0, 1) + ',' + field_value_tmp.substring(1, 2) + ',' + field_value_tmp.substring(2, 3);
						}
					}
					
					el.value = field_value_new;
				}.bind(this));
			}

			/*
			Rewrite TIME-12
			*/	
			if (validators.test('validate-time-12')) {
				
				el.addEvent('change', function (event) {
					field_value = el.getValue().clean();

					if (field_value.toInt() > 0)
					{
						var reg_exp = /^(.*?)(am|pm)$/i
						if (field_value.test(reg_exp)) {
							var match_array = field_value.match(reg_exp);
							var found_post_fix = true;
							var post_fix = match_array[2];
						} else {
							var post_fix = 'am';
							var found_post_fix = false;
						}
						
						var reg_exp = /^([0-9]+)(\.|\:|,|-|;|\/)([0-9]+)(.*)$/i
						if (field_value.test(reg_exp)) {
							var match_array = field_value.match(reg_exp);
	
							var hour = match_array[1].substring(0, 2).toInt();
							var minute = match_array[3].substring(0, 2).toInt();
						} else {
							field_value = field_value.toInt() + '';
	
							if (field_value.length >= 4) {
								var hour = field_value.substring(0, 2).toInt();
								var minute =  field_value.substring(2, 4).toInt();
							} else if (field_value.length == 3) {
								if (field_value.substring(0, 1) == 0) {
									var hour = field_value.substring(0, 2).toInt();
									var minute =  field_value.substring(2, 3).toInt();
								} else {
									var hour = field_value.substring(0, 1).toInt();
									var minute =  field_value.substring(1, 3).toInt();
								}
							} else if (field_value.length == 2 && !found_post_fix) {
								var hour = field_value.substring(0, 1).toInt();
								var minute = field_value.substring(1, 2).toInt();									
							}  else {
								var hour = field_value;
								var minute = 0;
							}
						}

						if (minute > 59) {
							hour = hour + 1;
							minute = minute - 60;
						}

						while (hour > 12) {
							hour = hour - 12;
							post_fix = 'pm';
						}
						
						if (hour == 0) {
							minute = (minute > 9) ? minute : '0' + minute;
							el.value = '12:' + minute + ' am';
						} else {
							minute = (minute > 9) ? minute : '0' + minute;
							el.value = hour + ':' + minute + ' ' + post_fix;
						}
					} else {
						el.value = '';
					}

				}.bind(this));
			}

			/*
			Rewrite TIME-24
			*/	
			if (validators.test('validate-time-24')) {

				el.addEvent('change', function (event) {
					field_value = el.getValue().clean();

					if (field_value.toInt() > 0)
					{
						var reg_exp = /^([0-9]+)(\.|\:|,|-|;|\/)([0-9]+)(.*)$/i
						if (field_value.test(reg_exp)) {
							var match_array = field_value.match(reg_exp);
	
							var hour = match_array[1].substring(0, 2).toInt();
							var minute = match_array[3].substring(0, 2).toInt();
						} else {
							field_value = field_value.toInt() + '';
	
							if (field_value.length >= 4) {
								var hour = field_value.substring(0, 2).toInt();
								var minute =  field_value.substring(2, 4).toInt();
							} else if (field_value.length == 3) {
								if (field_value.substring(0, 1) == 0) {
									var hour = field_value.substring(0, 2).toInt();
									var minute =  field_value.substring(2, 3).toInt();
								} else {
									var hour = field_value.substring(0, 1).toInt();
									var minute =  field_value.substring(1, 3).toInt();
								}
							} else if (field_value.length == 2) {
								var hour = field_value.substring(0, 1).toInt();
								var minute = field_value.substring(1, 2).toInt();
							}  else {
								var hour = field_value;
								var minute = 0;
							}
						}
	
						if (minute > 59) {
							hour = hour + 1;
							minute = minute - 60;
						}
						while (hour > 23) {
							hour = hour - 24;
						}
						
						minute = (minute > 9) ? minute : '0' + minute;
						hour = (hour > 9) ? hour : '0' + hour;
						
						el.value = hour + ':' + minute;
						
					} else {
						el.value = '';
					}
					
				}.bind(this));
			}

			/*
			Rewrite DATE-DK
			*/	
			if (validators.test('validate-date-dk')) {

				el.addEvent('change', function (event) {

					var dirty = false;
					field_value = el.getValue().clean();
					var valid_date_db_guess_reg_exp = /^([0-9]{4})(\.|\:|,|-|;|\/)([0-9]{1,2})(\.|\:|,|-|;|\/)([0-9]{1,2})$/i;
					var valid_date_dk_guess_reg_exp = /^([0-9]{1,2})(\.|\:|,|-|;|\/)([0-9]{1,2})(\.|\:|,|-|;|\/)([0-9]{1,4})$/i;

					if (field_value.test(valid_date_db_guess_reg_exp)) {
						var match_array = field_value.match(valid_date_db_guess_reg_exp);
						
						var day = match_array[5];
						var month = match_array[3];
						var year = match_array[1];					
					
					} else if (field_value.test(valid_date_dk_guess_reg_exp)) {
						var match_array = field_value.match(valid_date_dk_guess_reg_exp);
						
						var day = match_array[1];
						var month = match_array[3];
						var year = match_array[5];

					} else if (field_value.toInt() > 0) {

						if ([6, 8].contains(field_value.length)) {

							var day = field_value.substring(0, 2);
							var month = field_value.substring(2, 4);
							var year = field_value.substring(4, 8);

						} else {
							dirty = true;
						}
					} else {
						dirty = true;
					}

					if (dirty == true) {
						el.value = '';	
					} else {
						
						//[day, month] = (month > 12) ? [month, day] : [day, month];
						
						if (year.length == 1) {
							year = '200' + year;
						} else if (year.length == 2) {
							year = (year < 20) ? '20' + year : '19' + year;
						} else if (year.length == 3) {
							year = year + '0';
						}
						
						year = (year > 2069) ? 2069 : year;
						date_new = new Date(year, (month-1), day, 00, 00, 00);
						
						day = date_new.getDate();
						month = date_new.getMonth()+1;
						year = date_new.getFullYear();
						
						day = (day < 10) ? '0' + day : day;
						month = (month < 10) ? '0' + month : month;
						
						el.value = day + '/' + month + '/' + year;
					}
				}.bind(this));
			}
			
			/*
			Rewrite DATE-US
			*/	
			if (validators.test('validate-date-us')) {

				el.addEvent('change', function (event) {

					var dirty = false;
					field_value = el.getValue().clean();
					var valid_date_db_guess_reg_exp = /^([0-9]{4})(\.|\:|,|-|;|\/)([0-9]{1,2})(\.|\:|,|-|;|\/)([0-9]{1,2})$/i;
					var valid_date_dk_guess_reg_exp = /^([0-9]{1,2})(\.|\:|,|-|;|\/)([0-9]{1,2})(\.|\:|,|-|;|\/)([0-9]{1,4})$/i;

					if (field_value.test(valid_date_db_guess_reg_exp)) {
						var match_array = field_value.match(valid_date_db_guess_reg_exp);
						
						var day = match_array[5];
						var month = match_array[3];
						var year = match_array[1];					
					
					} else if (field_value.test(valid_date_dk_guess_reg_exp)) {
						var match_array = field_value.match(valid_date_dk_guess_reg_exp);
						
						var day = match_array[3];
						var month = match_array[1];
						var year = match_array[5];

					} else if (field_value.toInt() > 0) {

						if ([6, 8].contains(field_value.length)) {

							var day = field_value.substring(2, 4);
							var month = field_value.substring(0, 2);
							var year = field_value.substring(4, 8);

						} else {
							dirty = true;
						}
					} else {
						dirty = true;
					}

					if (dirty == true) {
						el.value = '';	
					} else {
						
						//[day, month] = (month > 12) ? [month, day] : [day, month];
						
						if (year.length == 1) {
							year = '200' + year;
						} else if (year.length == 2) {
							year = (year < 20) ? '20' + year : '19' + year;
						} else if (year.length == 3) {
							year = year + '0';
						}
						
						year = (year > 2069) ? 2069 : year;
						date_new = new Date(year, (month-1), day, 00, 00, 00);
						
						day = date_new.getDate();
						month = date_new.getMonth()+1;
						year = date_new.getFullYear();
						
						day = (day < 10) ? '0' + day : day;
						month = (month < 10) ? '0' + month : month;
						
						el.value = month + '/' + day + '/' + year;
					}
				}.bind(this));
			}
			
			/*
			Rewrite DATE-DB
			*/	
			if (validators.test('validate-date-db')) {

				el.addEvent('change', function (event) {

					var dirty = false;
					field_value = el.getValue().clean();
					
					var guess_date_db_reg_exp = /^([0-9]{1,4})(\.|\:|,|-|;|\/)([0-9]{1,2})(\.|\:|,|-|;|\/)([0-9]{1,2})$/i;
					var guess_date_reg_exp = /^([0-9]{1,2})(\.|\:|,|-|;|\/)([0-9]{1,2})(\.|\:|,|-|;|\/)([0-9]{1,4})$/i;

					if (field_value.test(guess_date_db_reg_exp)) {
						var match_array = field_value.match(guess_date_db_reg_exp);
						
						var day = match_array[5];
						var month = match_array[3];
						var year = match_array[1];
					
					} else if (field_value.test(guess_date_reg_exp)) {
						var match_array = field_value.match(guess_date_reg_exp);
						
						var day = match_array[1];
						var month = match_array[3];
						var year = match_array[5];

					} else if (field_value.toInt() > 0) {

						if ([8].contains(field_value.length)) {

							var day = field_value.substring(6, 8);
							var month = field_value.substring(4, 6);
							var year = field_value.substring(0, 4);

						} else if ([6].contains(field_value.length)) {

							var day = field_value.substring(4, 6);
							var month = field_value.substring(2, 4);
							var year = field_value.substring(0, 2);

						} else {
							dirty = true;
						}
					} else {
						dirty = true;
					}

					if (dirty == true) {
						el.value = '';	
					} else {
						
						// [day, month] = (month > 12) ? [month, day] : [day, month];
						
						if (year.length == 1) {
							year = '200' + year;
						} else if (year.length == 2) {
							year = (year < 20) ? '20' + year : '19' + year;
						} else if (year.length == 3) {
							year = year + '0';
						}
						
						year = (year > 2069) ? 2069 : year;
						date_new = new Date(year, (month-1), day, 00, 00, 00);
						
						day = date_new.getDate();
						month = date_new.getMonth()+1;
						year = date_new.getFullYear();
						
						day = (day < 10) ? '0' + day : day;
						month = (month < 10) ? '0' + month : month;
						
						el.value = year + '-' + month + '-' + day;
					}
				}.bind(this));
			}
			
			/*
			Rewrite MAX
			*/	
			if (validators.test('[a-z0-9]+-max-[0-9]+')) {

				el.addEvent('change', function (event) {
 					field_value = el.getValue().clean();
					var max_length = this.getMax(validators, '[a-z0-9]+');
 					
 					if (max_length > 0 && field_value.length > max_length) {
 						el.value = field_value.substring(0, max_length);
 					}

				}.bind(this));
			}			
		}.bind(this));
	},	

	/*
	Adding Warnings
	*/	
	addWarning: function () {

		this.getFields().each(function(el) {
			var validators = el.className
	
			/*
			Validation NUMBER
			*/	
			if (validators.test('validate-number')) {
				var max_length = this.getMax(validators, 'validate-number');
				var valid_num_reg_exp = /\d/i;
				
				el.addEvent('keydown', function (event) {
					var event = new Event(event);
					
					if (!event.key.test(valid_num_reg_exp) && !['backspace', 'left', 'right', 'delete', 'esc', 'tab', 'home', 'end'].contains(event.key) && ![35, 36].contains(event.code)) {
						event.stop();
						this.showWarning(el, this.l_number);
					} else if (max_length > 0 && el.getValue().length >= max_length && !['backspace', 'left', 'right', 'delete', 'esc', 'tab', 'home', 'end'].contains(event.key) && ![35, 36].contains(event.code)) {
						event.stop();
						this.showWarning(el, this.l_max.replace('[0-9]', max_length));
						el.value = el.getValue().substring(0, max_length);
					}
				}.bind(this));
			}

			/*
			Validation DECIMAL
			*/	
			if (validators.test('validate-decimal')) {
				var max_length = this.getMax(validators, 'validate-decimal');
				var valid_decimal_reg_exp = /([0-9])/i;

				el.addEvent('keydown', function (event) {
					var event = new Event(event);
					
					if (!event.key.test(valid_decimal_reg_exp) && !['backspace', 'left', 'right', 'delete', 'esc', 'tab', 'home', 'end'].contains(event.key) && ![35, 36, 188, 190].contains(event.code)) {
						event.stop();
						this.showWarning(el, this.l_decimal);
					} else if (max_length > 0 && el.getValue().length >= max_length && !['backspace', 'left', 'right', 'delete', 'esc', 'tab', 'home', 'end'].contains(event.key) && ![35, 36].contains(event.code)) {
						event.stop();
						this.showWarning(el, this.l_max.replace('[0-9]', max_length));
						el.value = el.getValue().substring(0, max_length);
					}
				}.bind(this));
			}			

			/*
			Validation ALPHA
			*/	
			if (validators.test('validate-alpha\s')) {
				var max_length = this.getMax(validators, 'validate-alpha');
				var valid_num_reg_exp = /[0-9]/i;
				
				el.addEvent('keydown', function (event) {
					var event = new Event(event);

					if (!event.key.test(valid_num_reg_exp) && !['backspace', 'left', 'right', 'delete', 'esc', 'tab', 'home', 'end'].contains(event.key) && ![35, 36].contains(event.code)) {
						event.stop();
						this.showWarning(el, this.l_alpha);
					} else if (max_length > 0 && el.getValue().length >= max_length && !['backspace', 'left', 'right', 'delete', 'esc', 'tab', 'home', 'end'].contains(event.key) && ![35, 36].contains(event.code)) {
						event.stop();
						this.showWarning(el, this.l_max.replace('[0-9]', max_length));
						el.value = el.getValue().substring(0, max_length);
					}
				}.bind(this));
			}

			/*
			Validation ALPHANUM
			*/
			if (validators.test('validate-alphanum')) {
				var max_length = this.getMax(validators, 'validate-alphanum');
				var valid_num_reg_exp = /\w/i;
				
				el.addEvent('keydown', function (event) {
					var event = new Event(event);

					if (!event.key.test(valid_num_reg_exp) && !['backspace', 'left', 'right', 'delete', 'esc', 'tab', 'home', 'end'].contains(event.key) && ![35, 36].contains(event.code)) {
						event.stop();
						this.showWarning(el, this.l_alphanum);
					} else if (max_length > 0 && el.getValue().length >= max_length && !['backspace', 'left', 'right', 'delete', 'esc', 'tab', 'home', 'end'].contains(event.key) && ![35, 36].contains(event.code)) {
						event.stop();
						this.showWarning(el, this.l_max.replace('[0-9]', max_length));
						el.value = el.getValue().substring(0, max_length);
					}
				}.bind(this));
			}

		}.bind(this));
	},

	showToolTip: function (el, msg) {
		var reverse = 1;
		var field_element = $(el);
		var error_object = $(field_element.getProperty('name') + '_Error');

		if (error_object) {
			error_object.remove();
		}

		if ((window.innerWidth/2)-this.getDimension(field_element)[0] < 0) {
			var tip_object = new Element('div').setProperty('id', field_element.name + '_Tip').setStyles('top: '+ this.getDimension(field_element)[1] +'px;').addClass('k_validation_tip_reverse').setHTML('<div>'+ msg +'</div><span></span>').injectInside($E('body'));
			var tip_object_dimension = tip_object.getCoordinates();
			var tip_object_left = this.getDimension(field_element)[2] - tip_object_dimension.width;
			tip_object.setStyle('left', tip_object_left +'px');
			
			var tip_object_effect = new Fx.Styles(tip_object, {duration: 400, transition:Fx.Transitions.linear});
			tip_object_effect.start({
				opacity: [.0, 1],
				left: [(tip_object_left - 20), tip_object_left]
			});

		} else {
			var tip_object = new Element('div').setProperty('id', field_element.name + '_Tip').setStyles('left: '+ (this.getDimension(field_element)[0] + 20) +'px; top: '+ this.getDimension(field_element)[1] +'px;').addClass('k_validation_tip').setHTML('<span></span>'+ msg +'').injectInside($E('body'));
			var tip_object_effect = new Fx.Styles(tip_object, {duration: 400, transition:Fx.Transitions.linear});
			tip_object_effect.start({
				opacity: [.0, 1],
				left: [(this.getDimension(field_element)[0] + 20), this.getDimension(field_element)[0]]
			});
		}

		field_element.removeEvents('blur');
		field_element.addEvent('blur', function (event) {
			tip_object.effect('opacity', {duration: 400, transition:Fx.Transitions.linear, onComplete: function (el) {
				el.remove();
			}}).start(1, .0);
		});
	},
	
	showWarning: function (el, msg) {

		var field_element = $(el);
		var msg = (field_element.getProperty('alt')) ? field_element.getProperty('alt') : msg;
		
		var tip_object = $(field_element.getProperty('name') + '_Tip');
		var warning_object = $(field_element.getProperty('name') + '_Warning');
		var error_object = $(field_element.getProperty('name') + '_Error');

		if (error_object) {
			error_object.remove();
		}

		if (!warning_object) {
			if (tip_object) {
				tip_object.setStyle('display', 'none');
				if ((window.innerWidth/2)-this.getDimension(field_element)[0] < 0) {
					var warning_object = new Element('div').setProperty('id', field_element.name + '_Warning').setStyles('top: '+ this.getDimension(field_element)[1] +'px;').addClass('k_validation_warning_reverse').setHTML('<div>'+ msg +'</div><span></span>').injectInside($E('body'));
					var warning_object_dimension = warning_object.getCoordinates();
					var warning_object_left = this.getDimension(field_element)[2] - warning_object_dimension.width;
					warning_object.setStyle('left', warning_object_left +'px');
				} else {
					var warning_object = new Element('div').setProperty('id', field_element.name + '_Warning').setStyles('left: '+ this.getDimension(field_element)[0] +'px; top: '+ this.getDimension(field_element)[1] +'px;').addClass('k_validation_warning').setHTML('<span></span>'+ msg +'').injectInside($E('body'));
				}

				var warning_object_effect = new Fx.Style(warning_object, 'opacity', {duration: 1000, transition:Fx.Transitions.linear, onComplete: function (el) {
					el.remove();
					tip_object.setStyles({
						opacity: 0,
						display: 'block'
					});
					tip_object.effect('opacity', {duration: 500, transition:Fx.Transitions.linear}).start(.0, 1);
				}});

				warning_object_effect.start.delay(2000, warning_object_effect, [1, .0]);
			} else {
				if ((window.innerWidth/2)-this.getDimension(field_element)[0] < 0) {
					var warning_object = new Element('div').setProperty('id', field_element.name + '_Warning').setStyles('top: '+ this.getDimension(field_element)[1] +'px;').addClass('k_validation_warning_reverse').setHTML('<div>'+ msg +'</div><span></span>').injectInside($E('body'));
					var warning_object_dimension = warning_object.getCoordinates();
					var warning_object_left = this.getDimension(field_element)[2] - warning_object_dimension.width;
					warning_object.setStyle('left', warning_object_left +'px');
				} else {
					var warning_object = new Element('div').setProperty('id', field_element.name + '_Warning').setStyles('left: '+ this.getDimension(field_element)[0] +'px; top: '+ this.getDimension(field_element)[1] +'px;').addClass('k_validation_warning').setHTML('<span></span>'+ msg +'').injectInside($E('body'));
				}

				var warning_object_effect = new Fx.Style(warning_object, 'opacity', {duration: 1000, transition:Fx.Transitions.linear, onComplete: function (el) {el.remove()}});
				warning_object_effect.start.delay(2000, warning_object_effect, [1, .0]);
			}
		}
	},
	
	showError: function (el, msg) {

		var field_element = $(el);
		var msg = (field_element.getProperty('alt')) ? field_element.getProperty('alt') : msg;		
		
		var tip_object = $(field_element.getProperty('name') + '_Tip');
		var warning_object = $(field_element.getProperty('name') + '_Warning');
		var error_object = $(field_element.getProperty('name') + '_Error');

		if (tip_object) {
			tip_object.setStyle('display', 'none');
		}

		if (warning_object) {
			warning_object.setStyle('display', 'none');
		}

		if (!error_object) {

			if ((window.innerWidth/2)-this.getDimension(field_element)[0] < 0) {
				var error_object = new Element('div').setProperty('id', field_element.name + '_Error').setStyles('top: '+ this.getDimension(field_element)[1] +'px;').addClass('k_validation_error_reverse').setHTML('<div>'+ msg +'</div><span></span>').injectInside($E('body'));
				var error_object_dimension = error_object.getCoordinates();
				var error_object_left = this.getDimension(field_element)[2] - error_object_dimension.width;
				error_object.setStyle('left', error_object_left +'px');
				
				var error_object_effect = new Fx.Styles(error_object, {duration: 400, transition:Fx.Transitions.linear});
				error_object_effect.start({
					opacity: [.0, 1],
					left: [(error_object_left - 20), error_object_left]
				});
			} else {
				var error_object = new Element('div').setProperty('id', field_element.name + '_Error').setStyles('left: '+ (this.getDimension(el)[0] + 20) +'px; top: '+ this.getDimension(el)[1] +'px;').addClass('k_validation_error').setHTML('<span></span>'+ msg +'').injectInside($E('body'));
				var error_object_effect = new Fx.Styles(error_object, {duration: 400, transition:Fx.Transitions.linear});
				error_object_effect.start({
					opacity: [.0, 1],
					left: [(this.getDimension(el)[0] + 20), this.getDimension(el)[0]]
				});
			}

			var error_object_effect_disappear = new Fx.Style(error_object, 'opacity', {duration: 400, transition:Fx.Transitions.linear, onComplete: function (el) {
				el.remove();
			}});

			error_object_effect_disappear.start.delay(4000, error_object_effect_disappear, [1, .0]);
		}
	}
});

K_Validation.implement(new Options, new K_Validation_Language);