﻿/// <reference path="jquery.js"/>
(function($) {
    $.fn.maxlength = function(settings) {

        if (typeof settings == 'string') {
            settings = { feedback: settings };
        }

        settings = $.extend({}, $.fn.maxlength.defaults, settings);

        function length(el) {
            var parts = el.value;
            if (settings.words)
                parts = el.value.length ? parts.split(/\s+/) : { length: 0 };
            return parts.length;
        }

        return this.each(function() {
            var field = this,
        	$field = $(field),
        	$form = $(field.form),
            limit = settings.useInput ? $form.find('input[name=maxlength]').val() : $field.attr('maxlength'),
            $charsLeft = $form.find(settings.feedback);

            function limitCheck(event) {
                var len = length(this),
        	    exceeded = len >= limit,
        		code = event.keyCode;

                if (!exceeded)
                    return;

                switch (code) {
                    case 8:  // allow delete
                    case 9:
                    case 17:
                    case 36: // and cursor keys
                    case 35:
                    case 37:
                    case 38:
                    case 39:
                    case 40:
                    case 46:
                    case 65:
                        return;

                    default:
                        return settings.words && code != 32 && code != 13 && len == limit;
                }
            }


            var updateCount = function() {
                var len = length(field),
            	diff = limit - len;

                $charsLeft.html(diff || "0");

                // truncation code
                if (settings.hardLimit && diff < 0) {
                    field.value = settings.words ?
                    // split by white space, capturing it in the result, then glue them back
            		field.value.split(/(\s+)/, (limit * 2) - 1).join('') :
            		field.value.substr(0, limit);

                    updateCount();
                }
            };

            $field.focus(updateCount).blur(updateCount).keyup(updateCount).change(updateCount);
            if (settings.hardLimit) {
                $field.keydown(limitCheck);
            }

            updateCount();
        });
    };

    $.fn.maxlength.defaults = {
        useInput: false,
        hardLimit: true,
        feedback: '#feedback',
        words: false
    };
})(jQuery);