/**
 * Dealer.com Utilities Package - ddc.util.js
 * Useful JavaScript functions for strings, arrays, and URLs.
 *
 * Dependencies: jQuery
 *
 * @projectDescription Dealer.com utilities package
 * @namespace DDC.Util
 * @author Randall Morey
 * @version 0.3
 */
(function () {
	var window = this,
		$ = window.jQuery,
		DDC = (window.DDC = (window.DDC || {}));
	
	DDC.Util = DDC.Util || {};

	$.extend(DDC.Util, {
		/**
		 * Formats a number with commas for better readability.
		 * source: http://blog.stevenlevithan.com/archives/commafy-numbers
		 * @alias DDC.Util.commafy
		 * @param {*} Value to commafy.
		 * @return {String} Returns a commafied number.
		 */
		commafy: function (num) {
			if (!!+num) {
				// num is convertible to an number, so proceed
				num = (+num).toString();
				return num.replace(/(^|[^\w.])(\d{4,})/g, function ($0, $1, $2) {
					return $1 + $2.replace(/\d(?=(?:\d\d\d)+(?!\d))/g, '$&,');
				});
			} else {
				throw new Error('commafy() expected one argument, a value convertible to a number.');
			}
		},
		/**
		 * Capitalizes a string.
		 * @alias DDC.Util.capitalize
		 * @param {String} String to capitalize.
		 * @return {String} Returns a capitalized string.
		 */
		capitalize: function (str) {
		    return str.replace(/\w+/g, function (a) {
		        return a.charAt(0).toUpperCase() + a.substr(1).toLowerCase();
			});
		},
		/**
		 * Performs multiple String.replace() calls on a single string.
		 * Usage:
		 *	DDC.Util.massReplaces('hello world I love you', [
		 *		[/hello/, 'goodbye'],
		 *		[/I love/, 'foobars']
		 *	]);
		 * @alias DDC.Util.massReplaces
		 * @param {String} String to perform multiple replaces on.
		 * @param {Array} Array of arrays, each with a regular expression and a
		 * replacement string.
		 * @return {String} Returns a new string, after performing all
		 * replacements.
		 */
		massReplaces: function (str, replaceArray) {
			var newString = str,
				i;
			for (i = 0; i < replaceArray.length; i++) {
				newString = newString.replace(replaceArray[i][0],
					replaceArray[i][1]);
			}
			return newString;
		},
		/**
		 * Makes the contents of a given array "unique" in that it has no
		 * equal entries.
		 * Usage:
		 * >>> DDC.Util.unique([1, 2, 3, 3, [5, 5, 0]]);
		 *     [1, 2, 3, [5, 5, 0]]
		 * >>> DDC.Util.unique(true, [1, 2, 3, 3, [5, 5, 0]]);
		 *     [1, 2, 3, [5, 0]]
		 * @alias DDC.Util.unique
		 * @param {array} originalArray The array to make unique.
		 * @return {array} Returns the unique array.
		 */
		unique: function (originalArray) {
	        var newArray = [],
				deep = false,
				i,
				j;
			if (typeof arguments[0] === 'boolean') {
				deep = arguments[0];
				originalArray = arguments[1];
			}
			outerLoop:
			for (i = 0; i < originalArray.length; i++) {
				if ((!(originalArray[i] instanceof Array) &&
				(deep === true)) || (deep === false)) {
					for (j = 0; j < newArray.length; j++) {
						if (newArray[j] === originalArray[i]) {
							continue outerLoop;
						}
					}
				} else {
					newArray[newArray.length] = DDC.Util.unique(deep,
					originalArray[i]);
					continue outerLoop;
				}
				newArray[newArray.length] = originalArray[i];
			}
	        return newArray;
		},
		/**
		 * Converts an object of key/value pairs to a URL parameter string.
		 * @function
		 * @alias DDC.Util.urlize
		 * @param {object} params is an object of key/value pairs to
		 * convert to url parameters
		 * @returns {string} Returns the URL parameter string
		 */
		urlize: function (arg, x, y, z) {
			x = x || '?';	// parameter string prefix
			y = y || '&';	// parameter pair delimiter
			z = z || '=';	// key / value delimiter
			var i, l, s = '', v,
				urlencode = function (str) {
					return encodeURIComponent(str)
						.replace(/\+/g, '%2B')
						.replace(/\"/g, '%22')
						.replace(/\'/g, '%27');
				};
			
			switch (typeof arg) {
			case 'object':
				if (arg) {
					for (i in arg) {
						if (typeof (v = DDC.Util.urlize(arg[i])) !==
							'function') {
							if (s) {
								s += y;
							}
							s += urlencode(DDC.Util.urlize(i)) + z +
								urlencode(v);
						}
					}
					return (s.length >= 1 ? x : '') + s;
				} else {
					return 'null';
				}
				break;
			case 'string':
				return arg;
			case 'number':
				return String(arg);
			case 'boolean':
				return arg.toString();
			default:
				return 'null';
			}
		},
		/**
		 * Sets url parameters based on a diff algorithm:  new params are added
		 * to the existing parameters, and conflict parameters are replaced
		 * with the newest.
		 * @param {Object} params is an object of key/value pairs to convert to
		 * url parameters
		 */
		setUrlParams: function (params) {
			var cleaned = function (obj) {
				for (var x in obj) {
					if ((obj[x] === '') || (obj[x] ===
					'InventoryListing')) {
						// delete empty params and the reset parameter
						delete obj[x];
					}
				}
				return obj;
			},
			updateUrl = function (params) {
				var currentUrl = window.location.toString();
				currentUrl = currentUrl.replace(/\?(.+)$/, '');
				params = params.replace(/\%2B/g, ' ').replace(/\+/g, ' ');
				window.location = currentUrl + (params || '');
			};
			
			params = $.extend({}, DDC.Util.getUrlParams(), params || {});
			updateUrl(DDC.Util.urlize(cleaned(params)));
			
			if (arguments[1] && (typeof arguments[1] === 'function')) {
				arguments[1]();
			}
		},
		/**
		 * Gets current url parameters.
		 * @return {Object} Returns an object representing the current url
		 * parameters.
		 */
		getUrlParams: function () {
			var deurlize = function (str) {
				var obj = {},
					items = str.split('&'),
					currentItem,
					i;
				for (i = 0; i < items.length; i++) {
					currentItem = items[i].split('=');
					if (currentItem instanceof Array) {
						obj[currentItem[0]] = (currentItem[1] || '')
						.replace(/\%2C/g, ',').replace(/\%20/g, ' ')
						.replace(/\%26/g, '&') || undefined;
					}
				}
				return obj;
			};
			
			return deurlize(((window.location.toString().split('?')[1] || '')
			.split('#')[0]) || '');
		}
	});
}());
