(function($) {

    /*
    * Auto-growing textareas; technique ripped from Facebook
    */
    $.fn.autogrow = function(options) {

        this.filter('textarea').each(function() {

            var $this = $(this);
            var minHeight = $this.height();
            var lineHeight = $this.css('line-height');

            var shadow = $('<div></div>').css
            (
                {
                    'font-size': $this.css('font-size'),
                    'font-family': $this.css('font-family'),
                    'width': $this.width(),// - parseInt($this.css('paddingLeft')) - parseInt($this.css('paddingRight')),
                    'min-height': minHeight,
                    'padding': $this.css('padding'),
                    'line-height': $this.css('line-height'),
                    'overflow-x': 'hidden',
                    'position': 'absolute',
                    'top': 0,
                    'left': -9999,
                    'resize': 'none'
                }
            ).appendTo(document.body);

            var update = function() {

                var times = function(string, number) {
                    for (var i = 0, r = ''; i < number; i++) r += string;
                    return r;
                };

                var val = this.value.replace(/</g, '&lt;')
                                    .replace(/>/g, '&gt;')
                                    .replace(/&/g, '&amp;')
                                    .replace(/\n$/, '<br/>&nbsp;')
                                    .replace(/\n/g, '<br/>')
                                    .replace(/ {2,}/g, function(space) { return times('&nbsp;', space.length - 1) + ' ' });

                shadow.html(val);
                $(this).css('height', Math.max(shadow.height() + 20, minHeight));

            }

            $(this).change(update).keyup(update).keydown(update);

            update.apply(this);

        });

        return this;

    }

})(jQuery);
