text: ﻿//  This file is part of the jQuery formatCurrency Plugin.
  //
  //    The jQuery formatCurrency Plugin is free software: you can redistribute it
  //    and/or modify it under the terms of the GNU General Public License as published 
  //    by the Free Software Foundation, either version 3 of the License, or
  //    (at your option) any later version.
  
  //    The jQuery formatCurrency Plugin is distributed in the hope that it will
  //    be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 
  //    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  //    GNU General Public License for more details.
  //
  //    You should have received a copy of the GNU General Public License along with 
  //    the jQuery formatCurrency Plugin.  If not, see <http://www.gnu.org/licenses/>.
  
  (function($) {
  
  	$.formatCurrency = {};
  
  	$.formatCurrency.regions = [];
  
  	// default Region is en
  	$.formatCurrency.regions[''] = {
  		symbol: 'Rp.',
  		positiveFormat: '%s%n',
  		negativeFormat: '(%s%n)',
  		decimalSymbol: '.',
  		digitGroupSymbol: ',',
  		groupDigits: true
  	};
  
  	$.fn.formatCurrency = function(destination, settings) {
  
  		if (arguments.length == 1 && typeof destination !== "string") {
  			settings = destination;
  			destination = false;
  		}
  
  		// initialize defaults
  		var defaults = {
  			name: "formatCurrency",
  			colorize: false,
  			region: '',
  			global: true,
  			roundToDecimalPlace: 2, // roundToDecimalPlace: -1; for no rounding; 0 to round to the dollar; 1 for one digit cents; 2 for two digit cents; 3 for three digit cents; ...
  			eventOnDecimalsEntered: false
  		};
  		// initialize default region
  		defaults = $.extend(defaults, $.formatCurrency.regions['']);
  		// override defaults with settings passed in
  		settings = $.extend(defaults, settings);
  
  		// check for region setting
  		if (settings.region.length > 0) {
  			settings = $.extend(settings, getRegionOrCulture(settings.region));
  		}
  		settings.regex = generateRegex(settings);
  
  		return this.each(function() {
  			$this = $(this);
  
  			// get number
  			var num = '0';
  			num = $this[$this.is('input, select, textarea') ? 'val' : 'html']();
  
  			//identify '(123)' as a negative number
  			if (num.search('\\(') >= 0) {
  				num = '-' + num;
  			}
  
  			if (num === '' || (num === '-' && settings.roundToDecimalPlace === -1)) {
  				return;
  			}
  
  			// if the number is valid use it, otherwise clean it
  			if (isNaN(num)) {
  				// clean number
  				num = num.replace(settings.regex, '');
  				
  				if (num === '' || (num === '-' && settings.roundToDecimalPlace === -1)) {
  					return;
  				}
  				
  				if (settings.decimalSymbol != '.') {
  					num = num.replace(settings.decimalSymbol, '.');  // reset to US decimal for arithmetic
  				}
  				if (isNaN(num)) {
  					num = '0';
  				}
  			}
  			
  			// evalutate number input
  			var numParts = String(num).split('.');
  			var isPositive = (num == Math.abs(num));
  			var hasDecimals = (numParts.length > 1);
  			var decimals = (hasDecimals ? numParts[1].toString() : '0');
  			var originalDecimals = decimals;
  			
  			// format number
  			num = Math.abs(numParts[0]);
  			num = isNaN(num) ? 0 : num;
  			if (settings.roundToDecimalPlace >= 0) {
  				decimals = parseFloat('1.' + decimals); // prepend "0."; (IE does NOT round 0.50.toFixed(0) up, but (1+0.50).toFixed(0)-1
  				decimals = decimals.toFixed(settings.roundToDecimalPlace); // round
  				if (decimals.substring(0, 1) == '2') {
  					num = Number(num) + 1;
  				}
  				decimals = decimals.substring(2); // remove "0."
  			}
  			num = String(num);
  
  			if (settings.groupDigits) {
  				for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++) {
  					num = num.substring(0, num.length - (4 * i + 3)) + settings.digitGroupSymbol + num.substring(num.length - (4 * i + 3));
  				}
  			}
  
  			if ((hasDecimals && settings.roundToDecimalPlace == -1) || settings.roundToDecimalPlace > 0) {
  				num += settings.decimalSymbol + decimals;
  			}
  
  			// format symbol/negative
  			var format = isPositive ? settings.positiveFormat : settings.negativeFormat;
  			var money = format.replace(/%s/g, settings.symbol);
  			money = money.replace(/%n/g, num);
  
  			// setup destination
  			var $destination = $([]);
  			if (!destination) {
  				$destination = $this;
  			} else {
  				$destination = $(destination);
  			}
  			// set destination
  			$destination[$destination.is('input, select, textarea') ? 'val' : 'html'](money);
  
  			if (
  				hasDecimals && 
  				settings.eventOnDecimalsEntered && 
  				originalDecimals.length > settings.roundToDecimalPlace
  			) {
  				$destination.trigger('decimalsEntered', originalDecimals);
  			}
  
  			// colorize
  			if (settings.colorize) {
  				$destination.css('color', isPositive ? 'black' : 'red');
  			}
  		});
  	};
  
  	// Remove all non numbers from text
  	$.fn.toNumber = function(settings) {
  		var defaults = $.extend({
  			name: "toNumber",
  			region: '',
  			global: true
  		}, $.formatCurrency.regions['']);
  
  		settings = jQuery.extend(defaults, settings);
  		if (settings.region.length > 0) {
  			settings = $.extend(settings, getRegionOrCulture(settings.region));
  		}
  		settings.regex = generateRegex(settings);
  
  		return this.each(function() {
  			var method = $(this).is('input, select, textarea') ? 'val' : 'html';
  			$(this)[method]($(this)[method]().replace('(', '(-').replace(settings.regex, ''));
  		});
  	};
  
  	// returns the value from the first element as a number
  	$.fn.asNumber = function(settings) {
  		var defaults = $.extend({
  			name: "asNumber",
  			region: '',
  			parse: true,
  			parseType: 'Float',
  			global: true
  		}, $.formatCurrency.regions['']);
  		settings = jQuery.extend(defaults, settings);
  		if (settings.region.length > 0) {
  			settings = $.extend(settings, getRegionOrCulture(settings.region));
  		}
  		settings.regex = generateRegex(settings);
  		settings.parseType = validateParseType(settings.parseType);
  
  		var method = $(this).is('input, select, textarea') ? 'val' : 'html';
  		var num = $(this)[method]();
  		num = num ? num : "";
  		num = num.replace('(', '(-');
  		num = num.replace(settings.regex, '');
  		if (!settings.parse) {
  			return num;
  		}
  
  		if (num.length == 0) {
  			num = '0';
  		}
  
  		if (settings.decimalSymbol != '.') {
  			num = num.replace(settings.decimalSymbol, '.');  // reset to US decimal for arthmetic
  		}
  
  		return window['parse' + settings.parseType](num);
  	};
  
  	function getRegionOrCulture(region) {
  		var regionInfo = $.formatCurrency.regions[region];
  		if (regionInfo) {
  			return regionInfo;
  		}
  		else {
  			if (/(\w+)-(\w+)/g.test(region)) {
  				var culture = region.replace(/(\w+)-(\w+)/g, "$1");
  				return $.formatCurrency.regions[culture];
  			}
  		}
  		// fallback to extend(null) (i.e. nothing)
  		return null;
  	}
  
  	function validateParseType(parseType) {
  		switch (parseType.toLowerCase()) {
  			case 'int':
  				return 'Int';
  			case 'float':
  				return 'Float';
  			default:
  				throw 'invalid parseType';
  		}
  	}
  	
  	function generateRegex(settings) {
  		if (settings.symbol === '') {
  			return new RegExp("[^\\d" + settings.decimalSymbol + "-]", "g");
  		}
  		else {
  			var symbol = settings.symbol.replace('$', '\\$').replace('.', '\\.');		
  			return new RegExp(symbol + "|[^\\d" + settings.decimalSymbol + "-]", "g");
  		}	
  	}
  
  })(jQuery);