﻿
(function ($) {
  $.fn.number_format = function (opts) {
    // Merges default options with parameter opts
    var options = $.extend({precision:     2,
                            point:       '.',
                            thousands:     ',',
                            initial:        '',
                            allow_negative: false}, opts);


    return $(this).each(function () {
      // Set the default value unless the input has any value
      if(get_numeric($(this).val()) == 0 || get_numeric($(this).val()) == '')
        $(this).val(options.initial);

      // Set event handlers
      $(this)

      // Formats the value
      .keyup(function() {
        var signal = ($(this).val().indexOf('-') == 0 && options.allow_negative) ? '-' : '';
        var new_value = get_numeric($(this).val());
            //new_value = signal + format_value(new_value);
        $(this).val(new_value);
      })
      
      // Trigger keyup event to format the value again, if necessary
      .blur(function() {
        var new_value = get_numericstrict($(this).val());
            new_value = format_value(new_value);
        $(this).val(new_value);
      })

      // Change focus behaviour to select the value
      .focus(function() {
        $(this).select();
      });
    });



    // Returns the numeric part of "val", preserving the signal
    function get_numeric(val) {
        if (val.toString() == options.initial) return options.initial;
      var value = val.toString().replace(/[^\d|,|\.]*/g, '');
      return value;
    }

    function get_numericstrict(val) {
    if (val.toString() == options.initial) return options.initial;
        var value = val.toString().replace(/[^\d|\.]*/g, '');
      return value;
    }

    // Formats "val"
    function format_value(val) {
      var value = val.toString();
      var new_value = '';
      var offset = value[0] == '-' ? 1 : 0;
      var integer_part = '';
      var decimal_part = '';
      var formatted_number = '';
      
      if (val == 0 || value.length == 0 || value == options.initial)
      return options.initial;

        // If the number of digits is lesser than the precision, no need to format
        if(value.indexOf('.') > -1) {
            integer_part = value.split('.')[0];
            decimal_part = value.split('.')[1];
            if (decimal_part.length > 2) {
                decimal_part = decimal_part.substring(0, 2);
            }
            if (decimal_part.length == 0) {
                decimal_part = '00';
            }
            if (decimal_part.length == 1) {
                decimal_part = decimal_part + '0';
            }
        } else {
            integer_part = value;
            decimal_part = '00';
        }
          
        formatted_number = format_integer_part(integer_part) + options.point + decimal_part;

      return formatted_number;
    }



    // Formats the integer part of the number
    function format_integer_part(val) {
      var counter = 0;
      var formatted = '';
      var separator = '';
      //var offset = val[0] == '-' ? 1 : 0;

      // Adds the thousands separator in every 3 digits
      if (val.length > 3) {
          for(var i = (val.length - 1); i >= 0; i--) {
            separator = (counter > 0 && counter % 3 == 0) ? options.thousands : '';
            formatted = val.substring(i, i+1) + separator + formatted;
            counter++;
          }
      } else {
        formatted = val;
      }
      return formatted;
    }
  };
})(jQuery);
