if(typeof console == 'undefined'){
	console = {
		log: function(m){			
			return false;
		}
	};
};

// common helper functions
(function($){
	var undefined;
	
	$.regex = {
		phone: 		/^(1\s*[-\/\.]?)?(\((\d{3})\)|(\d{3}))\s*[-\/\.]?\s*(\d{3})\s*[-\/\.]?\s*(\d{4})\s*(([xX]|[eE][xX][tT])\.?\s*(\d+))*$/,
		email: 		/^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)+$/,
		zip: 		/(^\d{5}$)|(^\d{5}-\d{4}$)/,
		name:		/^([a-zA-Z0-9-.\s])+$/,
		address: 	/^([a-zA-Z0-9-.\s])+$/,
		url:		/(ftp|http|https)?:\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
	};
	
	$.extend({
		validationRules: {
			"value": function(value, val){
				var proceed = false;
				
				if (typeof val == 'boolean'){
					proceed = (val != '');
				}
				else if (typeof val == 'string'){
					proceed = (value == val);
				}
				else if ($.isArray(val)){
					$.each(val, function(k, v){
						if (value == v) proceed = true;
					});
				}
				
				return proceed;
			}
			,"regex": function(value, regex){
				return regex.test(value);
			}
			,"format": function(value, format){
				if (format == 'url'){
					if (value.indexOf('http') == -1) value = 'http://' + value;
				}
				
				return $.validationRules.regex(value, $.regex[format]);
			}
			,"between": function(value, range){
				var numberRange = [];
				var start = range[0];
				var end = range[1];
				
				for(i = start; i <= end; i++){
					numberRange.push(i);
				}

				return this.value(value, numberRange);
			}
			,"under": function(value, num){
				return value < num;
			}
						
			,"minLength": function(value, min){
				return value.length >= min;
			}
			,"maxLength": function(value, max){
				return value.length <= max;
			}
			,"onlyNumbers": function(value, bool){
				return (bool) ? !isNaN(value) : true;
			}
			,"onlyLetters": function(value, bool){
				return (bool) ? /^[a-zA-Z ]+$/.test(value) : true; 
			}
			,"match": function(value, $elem){
				return (value == $elem.val());
			}
			,"ban": function(value, letters){
				var proceed = true;

				$.each(letters, function(k, character){
					if (value.indexOf(character) > -1) proceed = false;
				});
				
				return proceed;
			}
		},
		validate: function(value, rules){
			rules = rules || {};
			var _isValid = true;
			
			$.each(rules, function(ruleName, ruleProps){
				if ($.validationRules[ruleName] && !$.validationRules[ruleName](value, ruleProps)) _isValid = false;
			});

			if (rules == undefined && value == '') _isValid = false; 
			
			return _isValid;
		},
		truncate: function(options){
			// options = text, max, ellipsis
			this.defaults = { max: 100, ellipsis: '...' };
			
			this.settings = $.extend({}, this.defaults, options);
			var text = this.settings.text;
			
			if(typeof text == 'string' && text.length > this.settings.max){
				return text.substring(0, this.settings.max - this.settings.ellipsis.length) + this.settings.ellipsis;
			}
			else {
				return text;
			}
		},
		listen: function(evt, fn){
			$(document).bind(evt, fn);
		},
		dispatch: function(evt, args){
			$(document).trigger(evt, args);
		},
		// returns a json object of url params
		getParams: function(hash){
			var query = (hash) ? window.location.hash : window.location.search;
			var p = query.substring(1, query.length).split('&');
			var params = {};
			
			$.each(p, function(k, v){
				var tmp = v.split('=');
				params[tmp[0]] = tmp[1];
			});
			
			return params;
		}
	});
	
	$.fn.extend({
		downsize: function(options){
			return this.each(function(){
				var $this = $(this);
				options.dimensions = {
					width: $this.width(), height: $this.height()
				};
				
				if (options.maxWidth) _fitToWidth($this, options); else _fitToHeight($this, options);
			});
			
			function _fitToWidth($elem, config){
				if (config.dimensions.width > config.maxWidth){
					var change = (config.maxWidth - config.dimensions.width)/config.dimensions.width;
					$elem.css({
						width: config.maxWidth, height: (config.dimensions.height + (config.dimensions.height * change))
					});
				}
			}
			
			function _fitToHeight($elem, config){
				if (config.dimensions.height > config.maxHeight){
					var change = (config.maxHeight - config.dimensions.height)/config.dimensions.height;
					$elem.css({
						height: config.maxHeight, width: (config.dimensions.width + (config.dimensions.width * change))
					});
				}
			}
		},
		delegate: function(eventType, rules){
			return this.bind(eventType, function(e) {
				for (var selector in rules) if ($(e.target).is(selector)) return rules[selector].apply(this, arguments);
			});
		},
		// returns a boolean
		exists: function(){
			return ($(this).size() > 0);
		},
		check: function(){
			return this.each(function(){
				var $this = $(this);
				if ($this.is(':radio') || $this.is(':checkbox')) $this.attr('checked', 'checked');
				$this.change();
			});
		},
		uncheck: function(){
			return this.each(function(){
				var $this = $(this);
				if ($this.is(':radio') || $this.is(':checkbox')) $this.attr('checked', '');
				$this.change();
			});
		}
	});
})(jQuery);

Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};
