/**
 * jQEm v0.2 - Interact with the base 'em' unit.
 *   * http://davecardwell.co.uk/javascript/jquery/plugins/jquery-em/0.2/
 * 
 * Dave Cardwell <http://davecardwell.co.uk/>
 *
 * Built on the shoulders of giants:
 *   * John Resig <http://jquery.com/>
**/

new function() {

    var Public = {

            'auto': function( bool ) {
                        return bool != undefined ? Private.auto = bool
                                                 : Private.auto;
                    },
            'init': function() {
                        return Private.init();
                    },

            'bind': function( callback ) {
                        return Private.bind( callback );
                    },
          'unbind': function( callback ) {
                        return Private.unbind( callback );
                    },

         'trigger': function( force, args ) {
                        return Private.trigger( force, args );
                    },

          'active': function() {
                        return Private.active;
                    },
           'delay': function( milliseconds ) {
                        return milliseconds ? Private.delay = milliseconds
                                            : Private.delay;
                    },
           'start': function() {
                        return Private.start();
                    },
            'stop': function() {
                        return Private.stop();
                    },

         'current': function() {
                        return Private.current;
                    },
        'previous': function() {
                        return Private.previous;
                    }
    };

    $.jqem = Public;


    var Private = {
        // The element used in detecting changes to the base 'em' unit.
            '$em': $( document.createElement('i') ),

         'active': false,
         'canExp': undefined,
        'current': undefined,
          'delay': 100,  // milliseconds
            'iid': undefined,
       'previous': undefined,

           'auto': true,
           'init': init,

           'bind': bind,
         'unbind': unbind,

        'trigger': trigger,
         'update': function() {
                       Private.trigger( false );
                       return '1em';
                   },

          'start': start,
           'stop': stop
    };

    $(document).ready(function() {
        if( Private.auto ) init();
    });


    function init() {

        $('body').prepend(
            Private.$em.css({
                   'display': 'block',
                      'left': '-1em',
                  'position': 'absolute',
                'visibility': 'hidden',
                     'width': '1em'
            })
        );


        Private.canExp = ( Private.$em.style != undefined
                        && Private.$em.style.setExpression != undefined );

        Private.start();
    };

    function bind( callback ) {
        Private.$em.bind( 'emchange', callback );
    };

    function unbind( callback ) {
        Private.$em.unbind( 'emchange', callback );
    };

    function trigger( force, args ) {
        if( force == undefined ) force = false;

        if( force || Private.$em.width() != Private.current ) {
            Private.previous = Private.current;
            Private.current  = Private.$em.width();
            $.event.trigger( 'emchange', args );
        }
    };


    function start() {
        if( Private.active ) return;

        Private.current = Private.previous = Private.$em.width();

        if( Private.canExp ) {
            Private.$em.style.setExpression( 'width', '$.jqem.update();' );
        } else {
            Private.iid = window.setInterval( Private.update, Private.delay );
        }
        Private.active = true;
    };

    function stop() {
        if( !Private.active ) return;

        if( Private.canExp ) {
            Private.$em.style.removeExpression('width');
        } else {
            window.removeInterval( Private.iid );
        }
    };
}();
