/*!
 * jQuery hasher
 * 
 * Copyright (c) 2011 Bart de Boer
 * @dependency jquery.hashchange.js
 * http://benalman.com/projects/jquery-hashchange-plugin/
 */

(function ($) {
    
    $.hasher = {
        info: { },
        splitChar: '/',
        seperatorChar: ':',
        
        /**
         * Reads the current location.hash and splits the key/value pairs
         * based on the splitChar and seperatorChar e.g.:
         * #key:value/key2:othervalue/boolkey3/key4:...
         * 
         * @param boolean onLoad Is this function called on page load?
         */
        readHash: function(onLoad) {
            var hash = location.hash;
            hash = hash.replace( /^#/, '' );
            hash = $.trim(hash);
            if ( hash != '' ) {
                var exploded = hash.split($.hasher.splitChar);
                $.each(exploded, function(i,item){
                    if ( item != '' ) {
                        var parts = item.split($.hasher.seperatorChar);
                        $.hasher.setHash(parts[0], (parts.length == 2 ? parts[1] : undefined), true, onLoad);
                    }
                });
            }
        },
        
        /**
         * Writes the location.hash from the current info object.
         * Key value pairs will be written based on the current 
         * splitChar and seperatorChar e.g.:
         * #key:value/key2:othervalue/boolkey3/key4:...
         */
        writeHash: function() {
            var locationHash = '';
            $.each($.hasher.info, function(key, arr){
                if ( arr != undefined ) {
                    if ( arr.value === true ) {
                        locationHash += key+$.hasher.seperatorChar;
                    } else {
                        locationHash += key+$.hasher.seperatorChar+arr.value+$.hasher.splitChar;
                    }
                }
            });
            if ( locationHash != '' || location.hash != '' ) {
                location.hash = locationHash;
            }
        },
        
        /**
         * Register a callback for a specific hash key when the value changes.
         * Example: If you want a callback on #cams:ebony register a callback
         * for the key 'cams'.
         * 
         * @param string key The key to set the callback for.
         * @param function callback The function to call when the value changes.
         */
        registerCallback: function(key, callback) {
            if ( $.hasher.info[key] == undefined ) {
                $.hasher.info[key] = { };
            }
            $.hasher.info[key]['callback'] = callback;
        },
        
        /**
         * Set a specific hash key/value pair.
         * 
         * @param string key Which key to set
         * @param string value A value, if undefined true will be stored
         * @param boolean fromRead Is this function called from readHash?
         * @param boolean onLoad Is this function called on page load?
         */
        setHash: function(key, value, fromRead, onLoad) {
            var changed = false;
            var callback = undefined;
            if ( $.hasher.info[key] == undefined || 
                    ($.hasher.info[key] != undefined && 
                     $.hasher.info[key]['value'] != value) ) {
                changed = true;
            }
            if ( $.hasher.info[key] != undefined && 
                    $.hasher.info[key]['callback'] != undefined ) {
                callback = $.hasher.info[key]['callback'];
            }
            if ( $.hasher.info[key] == undefined ) {
                $.hasher.info[key] = { };
            }
            $.hasher.info[key]['value'] = (value == undefined ? true : value);
            if ( !fromRead ) {
                $.hasher.writeHash();
            }
            if ( changed && undefined != callback ) {
                callback($.hasher.info[key], onLoad);
            }
        },
        
        /**
         * Clears the hash, if a key is given only that key will be cleared
         * or else the complete hash will be destroyed.
         * 
         * @param string key The key of the hash
         */
        clearHash: function(key) {
            if ( typeof(key) == 'undefined' ) {
                location.hash = '_';
                $.each($.hasher.info, function(key, arr){
                    $.hasher.info[key]['value'] = undefined;
                });
            } else if ( typeof($.hasher.info[key]) != undefined ) {
                $.hasher.info[key] = undefined;
                $.hasher.writeHash();
            }
        },
        
        /**
         * Call this function to start catching hash changed, if not called
         * callbacks will not be triggered, put this in your document.ready.
         */
        catchEvents: function() {
            $.hasher.readHash(true);
            $(window).hashchange($.hasher.readHash());
        },
        
        _eeo: true
    };

})(jQuery);
