/**
 * File: jquery.jLimit.js
 * Date: 2009-09-10
 * Auth: jmcclure@sonicradish.com
 * Legal: Copyright 2009 jmcclure@sonicradish.com
 * Version: 1.0
 * Description:
 * Form Field Length Limit and Notification Plugin
 *
 * Credit: Modified from http://ndpsoftware.com/show_char_limit.php
 */

jQuery.fn.jLimit = function (limit,options) {

	if(!options) { options ={ }; }

	if( typeof(limit) === 'number') {
		options['limit'] = limit;
	} else if( typeof(limit) === 'object') {
		options = limit;
	} else {
		return false;
	}

	var defaults = {
		triggers : [],
		target    : false,
		overflow  : false,
		message   : '#R# character#RS# remaining',
		warning   : 'You may only enter #M#  character#MS#',
		limit     : 500,
		warnclass : false,
		maximum   : 10000,
		minimum   : 0
	};

	var o = jQuery.extend(defaults, options);

	// Default Warning if Not Defined
	if(typeof(o.triggers[0]) === 'undefined'){
		o.triggers[0] = defaults.warning;
	}

	var l = o.limit; 
	var c = 0;

	var process = function(el) {
		el = jQuery(el);

		if(o.target) { target = jQuery(o.target); }

		var curtext   = el.val();
		var curlength = curtext.length;
		var maxlength = el.attr('maxlength');
		if(!maxlength || maxlength == '' || parseInt(maxlength) < o.minimum || parseInt(maxlength) > o.maximum) {
			maxlength = o['limit'];
		}
		o.limit = maxlength;

		var charsleft = maxlength - curlength;
		l = charsleft;
		c = curlength;

		if(charsleft <= 0){
			if(o.warnclass && target && target != '_alert') {
				target.addClass(o.warnclass);
			}	
			if(typeof(o.overflow) === 'undefined' || !o.overflow){
                                el.val(curtext.substr(0,maxlength));
                        }
		}
		else {
			if(o.warnclass && target && target != '_alert') {	
				target.removeClass(o.warnclass);
			}
		}

		var action = false;

		if(o.triggers.length > 0 && curlength != 0){
			for(var i = maxlength;i>=charsleft;i--){
				if(typeof(o.triggers[i]) !== 'undefined'){
					if(typeof(o.triggers[i]) === 'function'){
						action = o.triggers[i];
					}else if(typeof(o.triggers[i]) === 'string'){
						var msg = o.triggers[i];
						action = function() { notify(msg); };
					}
				}
			}
		}

		if(action){ 
			action();
		} else {
			notify(o.message);
		}
	};

	var notify = function(message){

		if(typeof(message) !== 'string' || message.length <= 0) {
			return false; 
		}

		if(o.target) { 
			if(o.target == '_alert'){
				target = o.target;
			} else {
				target = jQuery(o.target); 
			}
		}

		if(!target) { return false; }

		if(message.indexOf('#R#') > -1){
			message = message.replace('#R#',l);
		}
		if(message.indexOf('#RS#') > -1){
                        var suffix = (Math.abs(l) != 1 ? 's' : '');
                        message = message.replace('#RS#',suffix);
                }
		if(message.indexOf('#S#') > -1){
                        var suffix = (Math.abs(l) != 1 ? 's' : '');
                        message = message.replace('#S#',suffix);
                }
		if(message.indexOf('#M#') > -1){
			message = message.replace("#M#",o.limit);
		}
		if(message.indexOf('#MS#') > -1){
			var suffix = (Math.abs(o.limit) != 1 ? 's' : '');
                        message = message.replace('#MS#',suffix);
                }
		if(message.indexOf('#C#') > -1){
			message = message.replace('#C#',c);
		}
		if(message.indexOf('#CS#') > -1){
                        var suffix = (Math.abs(c) != 1 ? 's' : '');
                        message = message.replace('#CS#',suffix);
                }

		if(target == '_alert'){
			alert(message);
		} else {
			target.html(message);
		}
	};

	return this.each(function() {
		process(this);
		jQuery(this).keyup(function() {
			process(this);
		});
	});
};

