var InputValidator = Class.create();

Object.extend(InputValidator.prototype, {

	/*** subclass constructor ***/
	initialize: function(element, decimalPlaces, allowDecimal, allowNegative, allowCommas, formatAsDecimal) 
	{
		this.element     	= $(element); 

        // Allow decimalPlaces to be set to 0
		this.decimalPlaces 	= (decimalPlaces == undefined) ? 2 : decimalPlaces;
		this.allowNegative 	= (allowNegative == undefined) ? false : allowNegative;
		this.allowDecimal = (allowDecimal == undefined) ? true : allowDecimal;
		this.allowCommas = (allowCommas == undefined) ? true : allowCommas;
		this.formatAsDecimal = (formatAsDecimal == undefined) ? true : formatAsDecimal;
		
		if(this.formatAsDecimal)
		    this.element.onblur = this.formatNumber.bindAsEventListener(this);
		    
		this.element.onkeyup = this.extractNumber.bindAsEventListener(this);
		this.element.onkeypress = this.validateDecimal.bindAsEventListener(this);

		//Event.observe(this.element, "blur", this.extractNumber.bindAsEventListener(this));
		//Event.observe(this.element, "keyup", this.extractNumber.bindAsEventListener(this));
	   	//Event.observe(this.element, "keypress", this.validateDecimal.bindAsEventListener(this));		
	},

	formatNumber: function(event)
	{
	    var dec = new Decimal(this.element.value);
	    dec.setPlaces(this.decimalPlaces);
		this.element.value = dec.toFormatted();
	},
	
	extractNumber: function(event)
	{
		var temp = this.element.value;
		
		// avoid changing things if already formatted correctly
		var reg0Str = "[0-9]*"; // "\d{1,3}(,\d{3})*";

		if (this.decimalPlaces > 0) 
		{
			reg0Str += '\\.?[0-9]{0,' + this.decimalPlaces + '}';
		} 
		else if (this.decimalPlaces < 0) 
		{
			reg0Str += '\\.?[0-9]*';
		}
		reg0Str = this.allowNegative ? '^-?' + reg0Str : '^' + reg0Str;
		reg0Str = reg0Str + '$';
		var reg0 = new RegExp(reg0Str);
		
		if (reg0.test(temp)) return true;
	
		// first replace all non numbers
		var reg1Str = '[^0-9' + (this.decimalPlaces != 0 ? '.' : '') + (this.allowNegative ? '-' : '') + ']';
		var reg1 = new RegExp(reg1Str, 'g');
		temp = temp.replace(reg1, '');
	
		if (this.allowNegative) {
			// replace extra negative
			var hasNegative = temp.length > 0 && temp.charAt(0) == '-';
			var reg2 = /-/g;
			temp = temp.replace(reg2, '');
			if (hasNegative) temp = '-' + temp;
		}
		
		if (this.decimalPlaces != 0) {
			var reg3 = /\./g;
			var reg3Array = reg3.exec(temp);
			if (reg3Array != null) {
				// keep only first occurrence of .
				//  and the number of places specified by decimalPlaces or the entire string if decimalPlaces < 0
				var reg3Right = temp.substring(reg3Array.index + reg3Array[0].length);
				reg3Right = reg3Right.replace(reg3, '');
				reg3Right = this.decimalPlaces > 0 ? reg3Right.substring(0, this.decimalPlaces) : reg3Right;
				temp = temp.substring(0,reg3Array.index) + '.' + reg3Right;
			}
		}
		
		this.element.value = temp;
		/*
		var temp = this.element.value;

		var dec = new Decimal(temp);
		dec.setPlaces(2);
		dec.roundToPlaces = false;
		console.log((temp.right(1) == "."));
   		console.log((temp.right(2) == ".0"));
		if(temp.right(1) == ".")
		{
			this.element.value = dec.toFormatted() + ".";
		}
		else if(temp.right(2) == ".0")
		{
			dec.setPlaces(1);
			this.element.value = dec.toFormatted();
		}
		else
		{	
			this.element.value = dec.toFormatted();
		}
		//this.element.value = new Decimal(this.element.value).toFormatted();
		*/
	},
	
	validateDecimal: function(e)
	{
		var key;
		var isCtrl = false;
		var keychar;
		var reg;
			
		if(window.event) 
		{
			key = e.keyCode;
			isCtrl = window.event.ctrlKey
		}
		else if(e.which) 
		{
			key = e.which;
			isCtrl = e.ctrlKey;
		}
		
		if (isNaN(key)) return true;
		
		keychar = String.fromCharCode(key);
		
		// check for backspace or delete, or if Ctrl was pressed
		if (key == Event.KEY_BACKSPACE || isCtrl)
		{
			return true;
		}
	
		reg = /\d/;
		var isFirstN = this.allowNegative ? keychar == "-" && this.element.value.indexOf("-") == -1 : false;
		var isFirstD = this.allowDecimal ? keychar == "." && this.element.value.indexOf(".") == -1 : false;

		return isFirstN || isFirstD || reg.test(keychar);
	}
});

/*
    Only allows keypresses which fit the given regex.
 */
var KeyPressPatternValidator = Class.create();

Object.extend(KeyPressPatternValidator.prototype, {

	/*** subclass constructor ***/
	initialize: function(element, pattern) 
	{
		this.element     	= $(element);
		this.pattern        = pattern; 
		
		this.element.onkeypress = this.validatePattern.bindAsEventListener(this);
	},
	
	validatePattern: function(e)
	{
		var key;
		var isCtrl = false;
		var keychar;
		var reg;
			
		if(window.event) 
		{
			key = e.keyCode;
			isCtrl = window.event.ctrlKey
		}
		else if(e.which) 
		{
			key = e.which;
			isCtrl = e.ctrlKey;
		}
		
		if (isNaN(key)) return true;
		
		keychar = String.fromCharCode(key);
		
		// check for backspace or delete, or if Ctrl was pressed
		if (key == Event.KEY_BACKSPACE || isCtrl)
		{
			return true;
		}
	
	    return this.pattern.test(keychar);
	}
});

