(function($) {
    $.fn.tristate = function(settings) {
        var config = {
            initialState: 'intermediate',
            imgPath: '/i/checkbox/',
            onChange: null,
            after: null
        };

        if (settings) $.extend(config, settings);

        var getNextState = function(state) {
            switch (state) {
            case 'intermediate':
                return 'checked';
            case 'unchecked':
                return 'checked';
            case 'checked':
                return 'unchecked';
            }
        }

        this.each(function() {
            var html = '<img src="' + config.imgPath + config.initialState + '.gif' + '"/>' +
                '<input type="hidden" value="' + config.initialState + '" />';
            $(this).html(html);

            $(this).unbind('click');
            $(this).click(function() {
                var nextState = getNextState($('input', this).val());
                $('img', this).attr('src', config.imgPath + nextState + '.gif');
                $('input', this).val(nextState);
                if (config.onChange)
                    config.onChange(nextState);
            });
            $('img', this).hover(function() {   /* in */
                var src = $(this).attr('src').replace(/\.gif$/i, '_highlighted.gif');
                $(this).attr('src', src);
            }, function() {                     /* out */
                var src = $(this).attr('src').replace(/_highlighted/, '');
                $(this).attr('src', src);
            });

            if (settings.after)
                settings.after(this);
        });
    };
})(jQuery);