;(function( $ ){
    
    // Matches 'presence-' prefixed words in a string.
    var _regex = /(presence-[^\s]+)\s?/g;
    
    /**
     * @class Presence
     *
     * This class deals with modifying a users state on the client only.
     *
     * @param element
     * @param data Define 'state' or it is set to Presence.states.OFFLINE. 'userId' is required.
     */
    function Presence( element, data ) {
    
        this.element = $(element);
    
        this.data = $.extend({
            
            state: Presence.states.OFFLINE
        
        }, data);
        
        this.init();
        
    }
    
    Presence.prototype = {
    
        init: function() {
        
            this.update( this.data.state );
            
        },
        
        update: function( state ) {

            var current = this.element.attr('class');
            
            this.element.attr('class', Presence.cssClass( state, current ));
        
            this.element.trigger('presence.updated', [ state ]); // Fire an event to let objects that care know what your new state is.
            
            this.data.state = state;
        
        }

    };
    
    Presence.states = {
    
        OFFLINE     : 'offline',
        AVAILABLE   : 'available',
        BUSY        : 'busy'
    
    };
    
    /** 
     * An adaptor that returns a universal state identifier based on general presence model information. 
     */
    Presence.state = function( model ){
    
        // If a user is available, they are also online.
        if ( model.IsAvailable )
        {
            return Presence.states.AVAILABLE;        
        }
        
        // If they're not available, but they are online, then they must be busy.
        if ( model.IsOnline )
        {
            return Presence.states.BUSY;
        }
        
        //Since they weren't available or online, they're obviously offline.
        return Presence.states.OFFLINE;
        
    };
    
    /* 
     * This helper method generates a uniform CSS classname for representing presence by creating a 'presence-' prefixed string based on the state supplied.
     * Passing in an existing classname as the second argument will first remove all 'presence-' prefixed strings and then apply the above mentioned operation.
     */
    Presence.cssClass = function( state, current ){
    
        var output = state !== Presence.states.OFFLINE ? 'presence-online presence-' + state : '';
        
        if ( current ){
        
            output += ' ' + current.replace(_regex, '').trim();
        
        }
        
        return output;
        
    };
        
    $.fn.presence = function( data ){
    
        if (!this.length) { return; }
        
        return this.each(function(){
        
            $(this).data('presence', new Presence( this, data ));
        
        });
    
    };
    
    Chemistry.include({ Presence:Presence });

})( jQuery );
