/**
Element based validation
Since it support function queing, and it need to be executed before the real submit,
it must be placed after XHR rule

Warning:
If you want to use this rule on more than one input,
put a fake input with gvExcelLike class after the first one
   <input type="hidden" class="gvExcelLike">
because somehow, the second input will not be applied by behaviour

On Behaviour.apply(), before the loop of "list" array,
the second input still exist in "list" array.
But, after the first loop when the first input being applied,
the second input disappear and skipped by the loop.
And the weird thing is, the rest input still being applied and work fine.

This is annoying bug but i still don't know how to fix it.
So far, the only way to prevent the second input from being disappeared is,
by removing function queing feature of onblur, onkeypress, and onsubmit event.
But, since its not a good way to bug fix, i skip it.
If you can fix it, or discover any information about this bug, please let me know.

@author Gabri NS (gabri.ns@gmail.com; gn_shally@yahoo.com)
@version 0.0.1
@copyright 2009
*/

var gValidation20090108 =
{
   '.gvExcelLike' : function (Obj)
   {
      if (Obj.tagName.toLowerCase() != 'input') return;
      else Obj.oldValue = 'undefined';
      
      var pushOldFunction = function(Obj, func)
      {
         for (i = 1; i > 0; i++) if (Obj[func+i] == undefined) break;
         Obj[func+i] = Obj[func];
         return func+i;
      }
      
      var formatNumber = function (num, mode)
      {
         decimal_place = 2;
         multiplier = Math.pow(10, decimal_place);
         point = ','; pointRegex = /,/g;
         thousand = '.'; thousandRegex = /\./g
         
         if (mode > 0)
         {
            num = num.toString().replace(thousandRegex, '');
            if (mode == 2) return num; // just delete thousand mark
            num = num.toString().replace(pointRegex, '.');
            if (mode == 1) return num; // go back to english format
         }
         
         num = parseFloat(num);
         if (isNaN(num)) return 0;
         if (num.toString().indexOf('e') != -1) return 'Out of range';
         num = (Math.round(num * multiplier)) / multiplier;
         
         str = num.toString().split('.');
         reminder = str[1] ? str[1].substr(0, 2) : '';
         while (reminder.length < decimal_place) reminder += '0';
         quotient = str[0];
         
         x = quotient.length % 3;
         newQuotient = quotient.substr(0, x);
         
         for (i = x; i < quotient.length; i += 3)
            newQuotient += thousand + quotient.substr(i, 3);
         if (newQuotient[0] == thousand) newQuotient = newQuotient.slice(1);
         
         return newQuotient + point + reminder;
      }
      
      if (typeof Obj.onfocus == 'function') var onFocusOld = pushOldFunction(Obj, 'onfocus');
      else var onFocusOld = false;
      Obj.onfocus = function()
      {
         this.value = formatNumber(this.value, 2);
         if (onFocusOld) return this[onFocusOld]();
      }
      
      if (typeof Obj.onblur == 'function') var onBlurOld = pushOldFunction(Obj, 'onblur');
      else var onBlurOld = false;
      Obj.onblur = function()
      {
         this.value = formatNumber(this.value, 3);
         if (onBlurOld) return this[onBlurOld]();
      }
      
      if (typeof Obj.onkeypress == 'function') var onKeyPressOld = pushOldFunction(Obj, 'onkeypress');
      else var onKeyPressOld = false;
      Obj.onkeypress = function()
      {
         if (this.oldValue == 'undefined') this.oldValue = formatNumber(this.value);
         if (onKeyPressOld) return this[onKeyPressOld]();
      }
      
      if (typeof Obj.onkeyup == 'function') var onKeyUpOld = pushOldFunction(Obj, 'onkeyup');
      else var onKeyUpOld = false;
      Obj.onkeyup = function()
      {
         oldValue = formatNumber(this.oldValue, 2);
         this.oldValue = 'undefined';
         
         num = formatNumber(this.value, 1);
         if (num != parseFloat(num))
            this.value = oldValue;
         
         if (onKeyUpOld) return this[onKeyUpOld]();
      }
      
      if (typeof Obj.form.onsubmit == 'function') var onSubmitOld = pushOldFunction(Obj.form, 'onsubmit');
      else var onSubmitOld = function () {};
      Obj.form.onsubmit = function ()
      {
         if (Obj.name) this[Obj.name].value = formatNumber(this[Obj.name].value, 1);
         if (onSubmitOld) return this[onSubmitOld]();
      }
      
      Obj.value = formatNumber(Obj.value);
      Obj.gvExcelLikeFormat = formatNumber;
   }
}

Behaviour.register(gValidation20090108);