(function($) {
  $.fn.textLimiter = function(options) {
	return this.each( function() {
	  var $this = $(this);
	  options = $.extend({
		'maxLength': 100,
		'align': 'right',
		'valign': 'bottom',
		'show': 'auto',
		'elCount': 'auto'
	  }, options);

	  $this.attr('maxLength', options['maxLength']);

	  $this.keyup( function () {
		processTextAreaText($this);
	  });
	  $this.keydown( function () {
		processTextAreaText($this);
	  });
	  $this.change( function () {
		processTextAreaText($this);
	  });
	  if (options['elCount'] == 'auto') {
		if (options['show'] == 'always') {
		  showCount($this, options['align'], options['valign'], options['show']);
		} else if (options['show'] == 'auto') {
		  $this.focusin( function () {
			showCount($this, options['align'], options['valign'], options['show']);
		  });
		}
	  } else {
		$this.attr('divName', options['elCount']);
		$('#' + $this.attr('divName')).html($this.attr('maxLength') - $this.text().length);
	  }

	  $this.focusout( function () {
		if (options['elCount'] == 'auto' && options['show'] != 'always') {
		  $('#' + $this.attr('divName')).hide();
		}
	  });
	});
  };

  function processTextAreaText($obj) {
	var maxLength = $obj.attr('maxLength');
	var text = $obj.text();
	var $cc = $('#' + $obj.attr('divName'))

	$cc.html(maxLength - text.length);

	if (parseInt($cc.html()) < 0)
	  $cc.html('0');

	if (maxLength != 0 && text.length > maxLength)
	  $obj.text(text.substr(0, maxLength));
  };

  function showCount($obj, align, valign, show) {
	if (show == 'always') {
	  var divName = 'textAreaMaxLengthPlugin_divCharCount_' + $obj.attr('id');
	} else {
	  var divName = 'textAreaMaxLengthPlugin_divCharCount';
	}

	if (!$('#' + divName).length) {
	  $('body').append('<div id="' + divName + '"></div>');
	}

	$obj.attr('divName', divName);

	var $cc = $('#' + divName);

	$cc.html($obj.attr('maxLength') - $obj.text().length);

	var x = $obj.position().left;

	if (valign == 'bottom') {
	  var y = $obj.offset().top + $obj.height() - $cc.height();
	} else if (valign == 'top') {
	  var y = $obj.position().top + 2;
	}

	$cc.css('position', 'absolute');
	$cc.css('text-align', align);
	$cc.css('padding', '0px 20px 0px 5px');
	$cc.css('width', $obj.innerWidth());
	$cc.css('opacity', 0.5);
	$cc.css('left', x);
	$cc.css('top', y);

	if (show != 'never') {
	  $cc.fadeTo(200, .5);
	}
  }

})(jQuery);