/*
 * jQuery JSON Plugin
 * version: 2.1 (2009-08-14)
 *
 * This document is licensed as free software under the terms of the
 * MIT License: http://www.opensource.org/licenses/mit-license.php
 *
 * Brantley Harris wrote this plugin. It is based somewhat on the JSON.org
 * website's http://www.json.org/json2.js, which proclaims:
 * "NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.", a sentiment that
 * I uphold.
 *
 * It is also influenced heavily by MochiKit's serializeJSON, which is
 * copyrighted 2005 by Bob Ippolito.
 */

(function($) {
    /** jQuery.toJSON( json-serializble )
        Converts the given argument into a JSON respresentation.

        If an object has a "toJSON" function, that will be used to get the representation.
        Non-integer/string keys are skipped in the object, as are keys that point to a function.

        json-serializble:
            The *thing* to be converted.
     **/
    $.toJSON = function(o)
    {
        if (typeof(JSON) == 'object' && JSON.stringify)
            return JSON.stringify(o);

        var type = typeof(o);

        if (o === null)
            return "null";

        if (type == "undefined")
            return undefined;

        if (type == "number" || type == "boolean")
            return o + "";

        if (type == "string")
            return $.quoteString(o);

        if (type == 'object')
        {
            if (typeof o.toJSON == "function")
                return $.toJSON( o.toJSON() );

            if (o.constructor === Date)
            {
                var month = o.getUTCMonth() + 1;
                if (month < 10) month = '0' + month;

                var day = o.getUTCDate();
                if (day < 10) day = '0' + day;

                var year = o.getUTCFullYear();

                var hours = o.getUTCHours();
                if (hours < 10) hours = '0' + hours;

                var minutes = o.getUTCMinutes();
                if (minutes < 10) minutes = '0' + minutes;

                var seconds = o.getUTCSeconds();
                if (seconds < 10) seconds = '0' + seconds;

                var milli = o.getUTCMilliseconds();
                if (milli < 100) milli = '0' + milli;
                if (milli < 10) milli = '0' + milli;

                return '"' + year + '-' + month + '-' + day + 'T' +
                             hours + ':' + minutes + ':' + seconds +
                             '.' + milli + 'Z"';
            }

            if (o.constructor === Array)
            {
                var ret = [];
                for (var i = 0; i < o.length; i++)
                    ret.push( $.toJSON(o[i]) || "null" );

                return "[" + ret.join(",") + "]";
            }

            var pairs = [];
            for (var k in o) {
                var name;
                var type = typeof k;

                if (type == "number")
                    name = '"' + k + '"';
                else if (type == "string")
                    name = $.quoteString(k);
                else
                    continue;  //skip non-string or number keys

                if (typeof o[k] == "function")
                    continue;  //skip pairs where the value is a function.

                var val = $.toJSON(o[k]);

                pairs.push(name + ":" + val);
            }

            return "{" + pairs.join(", ") + "}";
        }
    };

    /** jQuery.evalJSON(src)
        Evaluates a given piece of json source.
     **/
    $.evalJSON = function(src)
    {
        if (typeof(JSON) == 'object' && JSON.parse)
            return JSON.parse(src);
        return eval("(" + src + ")");
    };

    /** jQuery.secureEvalJSON(src)
        Evals JSON in a way that is *more* secure.
    **/
    $.secureEvalJSON = function(src)
    {
        if (typeof(JSON) == 'object' && JSON.parse)
            return JSON.parse(src);

        var filtered = src;
        filtered = filtered.replace(/\\["\\\/bfnrtu]/g, '@');
        filtered = filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
        filtered = filtered.replace(/(?:^|:|,)(?:\s*\[)+/g, '');

        if (/^[\],:{}\s]*$/.test(filtered))
            return eval("(" + src + ")");
        else
            throw new SyntaxError("Error parsing JSON, source is not valid.");
    };

    /** jQuery.quoteString(string)
        Returns a string-repr of a string, escaping quotes intelligently.
        Mostly a support function for toJSON.

        Examples:
            >>> jQuery.quoteString("apple")
            "apple"

            >>> jQuery.quoteString('"Where are we going?", she asked.')
            "\"Where are we going?\", she asked."
     **/
    $.quoteString = function(string)
    {
        if (string.match(_escapeable))
        {
            return '"' + string.replace(_escapeable, function (a)
            {
                var c = _meta[a];
                if (typeof c === 'string') return c;
                c = a.charCodeAt();
                return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
            }) + '"';
        }
        return '"' + string + '"';
    };

    var _escapeable = /["\\\x00-\x1f\x7f-\x9f]/g;

    var _meta = {
        '\b': '\\b',
        '\t': '\\t',
        '\n': '\\n',
        '\f': '\\f',
        '\r': '\\r',
        '"' : '\\"',
        '\\': '\\\\'
    };
})(jQuery);

/**
* author Remy Sharp
* url http://remysharp.com/tag/marquee
*/



/* ===========================================================================
 *
 * JQuery URL Parser
 * Version 1.0
 * Parses URLs and provides easy access to information within them.
 *
 * Author: Mark Perkins
 * Author email: mark@allmarkedup.com
 *
 * For full documentation and more go to http://projects.allmarkedup.com/jquery_url_parser/
 *
 * ---------------------------------------------------------------------------
 *
 * CREDITS:
 *
 * Parser based on the Regex-based URI parser by Steven Levithan.
 * For more information (including a detailed explaination of the differences
 * between the 'loose' and 'strict' pasing modes) visit http://blog.stevenlevithan.com/archives/parseuri
 *
 * ---------------------------------------------------------------------------
 *
 * LICENCE:
 *
 * Released under a MIT Licence. See licence.txt that should have been supplied with this file,
 * or visit http://projects.allmarkedup.com/jquery_url_parser/licence.txt
 *
 * ---------------------------------------------------------------------------
 *
 * EXAMPLES OF USE:
 *
 * Get the domain name (host) from the current page URL
 * jQuery.url.attr("host")
 *
 * Get the query string value for 'item' for the current page
 * jQuery.url.param("item") // null if it doesn't exist
 *
 * Get the second segment of the URI of the current page
 * jQuery.url.segment(2) // null if it doesn't exist
 *
 * Get the protocol of a manually passed in URL
 * jQuery.url.setUrl("http://allmarkedup.com/").attr("protocol") // returns 'http'
 *
 */

jQuery.url = function()
{
    var segments = {};

    var parsed = {};

    /**
    * Options object. Only the URI and strictMode values can be changed via the setters below.
    */
      var options = {

        url : window.location, // default URI is the page in which the script is running

        strictMode: false, // 'loose' parsing by default

        key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], // keys available to query

        q: {
            name: "queryKey",
            parser: /(?:^|&)([^&=]*)=?([^&]*)/g
        },

        parser: {
            strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,  //less intuitive, more accurate to the specs
            loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // more intuitive, fails on relative paths and deviates from specs
        }

    };

    /**
     * Deals with the parsing of the URI according to the regex above.
      * Written by Steven Levithan - see credits at top.
     */
    var parseUri = function()
    {
        str = decodeURI( options.url );

        var m = options.parser[ options.strictMode ? "strict" : "loose" ].exec( str );
        var uri = {};
        var i = 14;

        while ( i-- ) {
            uri[ options.key[i] ] = m[i] || "";
        }

        uri[ options.q.name ] = {};
        uri[ options.key[12] ].replace( options.q.parser, function ( $0, $1, $2 ) {
            if ($1) {
                uri[options.q.name][$1] = $2;
            }
        });

        return uri;
    };

    /**
     * Returns the value of the passed in key from the parsed URI.
       *
     * @param string key The key whose value is required
     */
    var key = function( key )
    {
        if ( ! parsed.length )
        {
            setUp(); // if the URI has not been parsed yet then do this first...
        }
        if ( key == "base" )
        {
            if ( parsed.port !== null && parsed.port !== "" )
            {
                return parsed.protocol+"://"+parsed.host+":"+parsed.port+"/";
            }
            else
            {
                return parsed.protocol+"://"+parsed.host+"/";
            }
        }

        return ( parsed[key] === "" ) ? null : parsed[key];
    };

    /**
     * Returns the value of the required query string parameter.
       *
     * @param string item The parameter whose value is required
     */
    var param = function( item )
    {
        if ( ! parsed.length )
        {
            setUp(); // if the URI has not been parsed yet then do this first...
        }
        return ( parsed.queryKey[item] === null ) ? null : parsed.queryKey[item];
    };

    /**
     * 'Constructor' (not really!) function.
     *  Called whenever the URI changes to kick off re-parsing of the URI and splitting it up into segments.
     */
    var setUp = function()
    {
        parsed = parseUri();

        getSegments();
    };

    /**
     * Splits up the body of the URI into segments (i.e. sections delimited by '/')
     */
    var getSegments = function()
    {
        var p = parsed.path;
        segments = []; // clear out segments array
        segments = parsed.path.length == 1 ? {} : ( p.charAt( p.length - 1 ) == "/" ? p.substring( 1, p.length - 1 ) : path = p.substring( 1 ) ).split("/");
    };

    return {

        /**
         * Sets the parsing mode - either strict or loose. Set to loose by default.
         *
         * @param string mode The mode to set the parser to. Anything apart from a value of 'strict' will set it to loose!
         */
        setMode : function( mode )
        {
            strictMode = mode == "strict" ? true : false;
            return this;
        },

        /**
         * Sets URI to parse if you don't want to to parse the current page's URI.
         * Calling the function with no value for newUri resets it to the current page's URI.
         *
         * @param string newUri The URI to parse.
         */
        setUrl : function( newUri )
        {
            options.url = newUri === undefined ? window.location : newUri;
            setUp();
            return this;
        },

        /**
         * Returns the value of the specified URI segment. Segments are numbered from 1 to the number of segments.
         * For example the URI http://test.com/about/company/ segment(1) would return 'about'.
         *
         * If no integer is passed into the function it returns the number of segments in the URI.
         *
         * @param int pos The position of the segment to return. Can be empty.
         */
        segment : function( pos )
        {
            if ( ! parsed.length )
            {
                setUp(); // if the URI has not been parsed yet then do this first...
            }
            if ( pos === undefined )
            {
                return segments.length;
            }
            return ( segments[pos] === "" || segments[pos] === undefined ) ? null : segments[pos];
        },

        attr : key, // provides public access to private 'key' function - see above

        param : param // provides public access to private 'param' function - see above

    };

}();

(function ($) {
    $.fn.marquee = function (klass) {
        var newMarquee = [],
            last = this.length;

        // works out the left or right hand reset position, based on scroll
        // behavior, current direction and new direction
        function getReset(newDir, marqueeRedux, marqueeState) {
            var behavior = marqueeState.behavior, width = marqueeState.width, dir = marqueeState.dir;
            var r = 0;
            if (behavior == 'alternate') {
                r = newDir == 1 ? marqueeRedux[marqueeState.widthAxis] - (width*2) : width;
            } else if (behavior == 'slide') {
                if (newDir == -1) {
                    r = dir == -1 ? marqueeRedux[marqueeState.widthAxis] : width;
                } else {
                    r = dir == -1 ? marqueeRedux[marqueeState.widthAxis] - (width*2) : 0;
                }
            } else {
                r = newDir == -1 ? marqueeRedux[marqueeState.widthAxis] : 0;
            }
            return r;
        }

        // single "thread" animation
        function animateMarquee() {
            var i = newMarquee.length,
                marqueeRedux = null,
                $marqueeRedux = null,
                marqueeState = {},
                newMarqueeList = [],
                hitedge = false;

            while (i--) {
                marqueeRedux = newMarquee[i];
                $marqueeRedux = $(marqueeRedux);
                marqueeState = $marqueeRedux.data('marqueeState');

                if ($marqueeRedux.data('paused') !== true) {
                    // TODO read scrollamount, dir, behavior, loops and last from data
                    marqueeRedux[marqueeState.axis] += (marqueeState.scrollamount * marqueeState.dir);

                    // only true if it's hit the end
                    hitedge = marqueeState.dir == -1 ? marqueeRedux[marqueeState.axis] <= getReset(marqueeState.dir * -1, marqueeRedux, marqueeState) : marqueeRedux[marqueeState.axis] >= getReset(marqueeState.dir * -1, marqueeRedux, marqueeState);

                    if ((marqueeState.behavior == 'scroll' && marqueeState.last == marqueeRedux[marqueeState.axis]) || (marqueeState.behavior == 'alternate' && hitedge && marqueeState.last != -1) || (marqueeState.behavior == 'slide' && hitedge && marqueeState.last != -1)) {
                        if (marqueeState.behavior == 'alternate') {
                            marqueeState.dir *= -1; // flip
                        }
                        marqueeState.last = -1;

                        $marqueeRedux.trigger('stop');

                        marqueeState.loops--;
                        if (marqueeState.loops === 0) {
                            if (marqueeState.behavior != 'slide') {
                                marqueeRedux[marqueeState.axis] = getReset(marqueeState.dir, marqueeRedux, marqueeState);
                            } else {
                                // corrects the position
                                marqueeRedux[marqueeState.axis] = getReset(marqueeState.dir * -1, marqueeRedux, marqueeState);
                            }

                            $marqueeRedux.trigger('end');
                        } else {
                            // keep this marquee going
                            newMarqueeList.push(marqueeRedux);
                            $marqueeRedux.trigger('start');
                            marqueeRedux[marqueeState.axis] = getReset(marqueeState.dir, marqueeRedux, marqueeState);
                        }
                    } else {
                        newMarqueeList.push(marqueeRedux);
                    }
                    marqueeState.last = marqueeRedux[marqueeState.axis];

                    // store updated state only if we ran an animation
                    $marqueeRedux.data('marqueeState', marqueeState);
                } else {
                    // even though it's paused, keep it in the list
                    newMarqueeList.push(marqueeRedux);
                }
            }

            newMarquee = newMarqueeList;

            if (newMarquee.length) {
                setTimeout(animateMarquee, 25);
            }
        }

        // TODO consider whether using .html() in the wrapping process could lead to loosing predefined events...
        this.each(function (i) {
            var $marquee = $(this),
                width = $marquee.attr('width') || $marquee.width(),
                height = $marquee.attr('height') || $marquee.height(),
                $marqueeRedux = $marquee.after('<div ' + (klass ? 'class="' + klass + '" ' : '') + 'style="display: block-inline; width: ' + width + 'px; height: ' + height + 'px; overflow: hidden;"><div style="float: left; white-space: nowrap;">' + $marquee.html() + '</div></div>').next(),
                marqueeRedux = $marqueeRedux.get(0),
                hitedge = 0,
                direction = ($marquee.attr('direction') || 'left').toLowerCase(),
                marqueeState = {
                    dir : /down|right/.test(direction) ? -1 : 1,
                    axis : /left|right/.test(direction) ? 'scrollLeft' : 'scrollTop',
                    widthAxis : /left|right/.test(direction) ? 'scrollWidth' : 'scrollHeight',
                    last : -1,
                    loops : $marquee.attr('loop') || -1,
                    scrollamount : $marquee.attr('scrollamount') || this.scrollAmount || 2,
                    behavior : ($marquee.attr('behavior') || 'scroll').toLowerCase(),
                    width : /left|right/.test(direction) ? width : height
                };

            // corrects a bug in Firefox - the default loops for slide is -1
            if ($marquee.attr('loop') == -1 && marqueeState.behavior == 'slide') {
                marqueeState.loops = 1;
            }

            $marquee.remove();

            // add padding
            if (/left|right/.test(direction)) {
                $marqueeRedux.find('> div').css('padding', '0 ' + width + 'px');
            } else {
                $marqueeRedux.find('> div').css('padding', height + 'px 0');
            }

            // events
            $marqueeRedux.bind('stop', function () {
                $marqueeRedux.data('paused', true);
            }).bind('pause', function () {
                $marqueeRedux.data('paused', true);
            }).bind('start', function () {
                $marqueeRedux.data('paused', false);
            }).bind('unpause', function () {
                $marqueeRedux.data('paused', false);
            }).data('marqueeState', marqueeState); // finally: store the state

            // todo - rerender event allowing us to do an ajax hit and redraw the marquee

            newMarquee.push(marqueeRedux);

            marqueeRedux[marqueeState.axis] = getReset(marqueeState.dir, marqueeRedux, marqueeState);
            $marqueeRedux.trigger('start');

            // on the very last marquee, trigger the animation
            if (i+1 == last) {
                animateMarquee();
            }
        });

        return $(newMarquee);
    };
}(jQuery));

(function($){
    var $document = $(document),
        iframe,
        hash = '', // инициализируем пустым, чтобы учесть первоначальный хеш
        // считаем, что только IE нужно насильно записывать хистори (остальные сами справляются)
        needHistoryAdd = /MSIE/.test(navigator.userAgent),
        afterHistoryRead = false,
        afterHistoryAdd = false;

    // функция проверки изменения хеша, она же записывает хистори и вещает основное событие
    function check() {
        if (hash != (hash = document.location.hash)) {
            // если мы только что прочли из хистори, не надо туда записывать
            if (!afterHistoryRead && needHistoryAdd) historyAdd(hash);
            afterHistoryRead = false;
            $document.trigger('hashChange', [hash]);
            // console.log('hashChange: ' + hash);
        }
        setTimeout(check, 42); // варварство из-за отсутствия полноценного события
    }

    // функция насильной записи в хистори через скрытый iframe
    function historyAdd(hash) {
        if (!iframe) iframe = $('<iframe style="display:none" src="javascript:false;"></iframe>').appendTo('body')[0];
        var d = iframe.contentDocument ||
            (iframe.contentWindow ? iframe.contentWindow.document : iframe.document);
        d.open();
        // можем позволить себе вольности с незакрытыми тегами, браузер достроит
        d.write('<html><head><title>' + document.title + '</title></head><body>'); // NOTE: потенциальная опасность с ескейпингом document.title
        d.write($('<div/>').append($('<div id="hashdiv"></div>').text(hash)).html()); // типа ради ескейпинга
        // приписываем в тело фрейма скрипт, который будет срабатывать при возвращении на него по хистори
        d.write(
            '<script>' +
                // портим объект window для связи между фреймами
                'window._hash = document.getElementById("hashdiv").innerText;' +
                'window.onload = parent._historyRead;' +
            '</script>'
        );
        afterHistoryAdd = true;
        d.close();
        // console.log('historyAdd: ' + hash);
    }

    // для IE немного ускоряем обработку изменения хеша,
    // но поидее можно обойтись постоянно повторяющимся check()
    if ('onpropertychange' in document && 'attachEvent' in document) {
        document.attachEvent('onpropertychange', function(){
            if (event.propertyName == 'location') {
                check();
                // console.log('onpropertychange: ' + document.location.hash);
            }
        });
    }

    if (needHistoryAdd) {
        // портим объект window, чтобы работало восстановление хистори через iframe
        window._historyRead = function(){
            // console.log('try historyRead: ' + this._hash);
            // если мы только что добавили, читать не надо
            if (!afterHistoryAdd) {
                var newHash = this._hash;
                // console.log('newHash: ' + newHash + ', currentHash: ' + document.location.hash);
                // без надобности не присваиваем, как минимум из-за звука "клака" в IE
                if (document.location.hash != newHash) {
                    afterHistoryRead = true;
                    document.location.hash = newHash;
                    // console.log('historyRead: ' + newHash);
                }
            }
            afterHistoryAdd = false;
        };
    }

    $(function(){ setTimeout(check, 1); }); // запускаем постоянную проверку с задержкой, чтобы все успели начать слушать события

})(jQuery);

// ################################ DOCUMENT READY ########################## //

$(document).ready ( function() {
    in_admin = window.location.href.match(/\/admin\//);


    nav_edrowcol = function(e) {
        if (e.altKey){
            obj = $(this);

            while (obj && !obj.attr('edrowcol')) { obj = $(obj).parent(); };

            row_col = obj.attr('edrowcol');

            while (obj && !obj.attr('parentfile')) { obj = $(obj).parent(); };

            fn = 'sblm://' + obj.attr('parentfile') + ':' + row_col;
            $('body').append($('<iframe style="width:0;height:0;border:0;"  />').attr('src', fn));

            return false;
        }
    }


    news_margins = function() {

        $('div.news-item').each(function(index) {
            if ( $(this).height() > 100) {
                 $(this).css({marginBottom:'30px'});
            }
        });
    }

    center_content = function(){
        var content_css = {
            'margin-left': - $('#content').width()  / 2,
            'margin-right': '0',
            left: '50%',
            'float': 'left'
        };


        //$('#content img').css({
        //
        //});
        
        var play = $(window).height() - $('#content').height();
        
        if ( play > 100 ) {
            content_css['marginTop'] = - $('#content').height() / 2;
            content_css['top'] = '50%';
            $('html').height($(window).height());

        } else {
            content_css['top'] = '100px';
            $('html').height($('#content').height());
            $('#content').height($('#content').height()+100)
            
        };

        $('#content').css(content_css);
    };

// ############################## ZILCH ##################################### //

    show_zilch =  function() {
        $('#overlay').fadeIn( function() {
            $('#zilch-box embed').show();
            $('#zilch-box').attr('class', 'zilch-box-show');
            $('#zilch-box :header').css({'z-index':'3', position:'absolute'}).show();
            $('#zilch-box :header').fadeOut(10000);
        });
    };

    $('a[href=#zilch]').click(show_zilch);

// ################################# HASHIFY LINKS ########################## //


    update_links = function() {
        /* TODO */

        var host = jQuery.url.setUrl(window.location.href).attr("host");

        $('a').each( function() {
            var url = $(this).attr('href');

            if (url.substr(0, 1) != '#') {
                urler = jQuery.url.setUrl(url);

                var path = urler.attr("path") + (urler.attr("hash") || '');

                if (urler.attr('host') == host) {
                    $(this).attr('href', path)
                };
            }
        })

        $('#navigation a[href!=#zilch], #artists-index a').each( function() {
            var url = $(this).attr('href');

            if (url.substr(0, 1) == '#') {
                url = url.substr(1);
            }

            $('a[href='+ url +']').each(function() {
                $(this).attr('href', '#' + url);
            })
        });

        $('a.sound_link').click( function() {
            //alert();
            show_music_player();
            play_sound($.secureEvalJSON($(this).attr('datafld')) );
            return false;
        })
    }

    update_page = function() {
        // If we aren't running admin
        if (!in_admin) { update_links(); }

        center_content();
        handle_contact_form(center_content);

        news_margins();

        $('*').unbind('click', nav_edrowcol)
        $('*').click(nav_edrowcol)

        $('#top10-year').change (
            function(){
                $('select[name="month"] option.selected').toggleClass('selected');
                $('select option[year="' + $(this).val() + '"]').toggleClass('selected');
            }
        );

        $('#top10-archives form').submit(
           function(){
               var thisThis = $(this);
               var getM = function(v){return $('select[name=' + v + ']', thisThis).val();}

               //setTimeout(
                //function(){
                    window.location.href = '/#/top10/' + getM('year') + '/' + getM('month') + '/archives';
                //}, 100 )

               return false;
           }
        )



        //hide_overlay();
        //if ($('#overlay').visible()){  }
    };

// ############################## HASH CHANGES ############################## //

    $(document).bind('hashChange', function(e, newHash) {
        if (newHash.substr(1,1) == '/') {

          $("#inner").toggleClass('loading');
          $('#content').remove();

          $("#inner").load (
              newHash.substr(1) + " #content",

              function(responseText, status, res) {
                  /*

                  repl.home();
                  repl.enter(content)

                  responseText = '<html><title>whatever dude</title><html>';

                  */


                  if (status == 'error') {
                     $('#inner').empty().append('<div id="content" />').find('div').html(responseText);
                  } else {
                    // doc = $(responseText);
                    // alert(doc.find('title').length);
                  };

                  update_page();
                  document.title = $('#content #content-title').text();
                  $("#inner").toggleClass('loading');
              }
          );
        }

        if (newHash.match('#zilch') ){
            show_zilch();
        } else {
            hide_overlay();
        }

    });

// ############################## OVERLAY HIDE ############################## //

    hide_overlay = function() {
        $('#zilch-box').attr('class', 'zilch-box-hide');
        $('#music-player').attr('class', 'hide');
        $('#overlay').fadeOut();
    }

    $('#overlay').click(hide_overlay);

// ############################## MUSIC PLAYER ############################## //


    show_music_player = function(){
        // TODO: create show overlay function
        
        if ($('#content').height() > $(window).height()) {
            $('#overlay').height($('#content').height() + $('#content').offset().top);
        }
        
        $('#overlay').fadeIn('fast', function(){
            $('#music-player').attr('class', 'show');
        });
    };

    play_sound = function( sound ){
        $('#jquery_jplayer').data('isplaying', true).setFile(sound.link).play();

        ( $('#songname-marquee').empty()
                                .append( '<marquee behavior="scroll" scrollamount="1" scrolldelay="1"  direction="right"><p></p></marquee>' )
                                .find('p')
                                .css({color:'#999', cursor:'e-resize'})
                                .text(' - ' + sound.name)
                                .prepend('<a />')
                                .find('a').css( {fontWeight: '700', color: '#777'} )
                                .text(sound.artist.name )
                                .attr('href', '/#' + sound.artist.link || window.location.href ) )

        song_marquee =  $('#songname-marquee marquee').css({color:'#999', cursor:'move'})
                                                      .marquee('pointer')
                                                      .mouseover(function () {
                                                        $(this).trigger('stop');
                                                      }).mouseout(function () {
                                                        if ( $("#jquery_jplayer").data('isplaying') ) {
                                                            $(this).trigger('start');
                                                        };
                                                      }).mousemove(function (event) {
                                                        if ($(this).data('drag') == true) {
                                                          this.scrollLeft = $(this).data('scrollX') + ($(this).data('x') - event.clientX);
                                                        }
                                                      }).mousedown(function (event) {
                                                        $(this).data('drag', true).data('x', event.clientX).data('scrollX', this.scrollLeft);
                                                      }).mouseup(function () {
                                                        $(this).data('drag', false);
                                                      });

    };

    $('#navigation > img').click(function(e){
        if (e.ctrlKey || in_admin) {
            if (in_admin) { window.location.href = '/'} else {window.open('/admin')};
        }
        else {
            show_music_player();
        };
        return false;
    });

    var global_lp = 0; // Stores the value of percentage of track loaded

    // #################################### BUTTONS ####################### //

    $("#jquery_jplayer").each(function(){

        $("#jquery_jplayer").jPlayer({
            //oggSupport: true,
            ready: function () {

                var ctrlBar = "";
                for (i=0; i < 100; i++){
                     ctrlBar = ctrlBar + "<a href='#' id='lb-"+i+"'>|<\/a>";
                }

                $('#player_progress_ctrl_bar').html(ctrlBar);
            }
        })
        .onProgressChange( function(lp,ppr,ppa,pt,tt) {
             var lpInt = parseInt(lp);
             var ppaInt = parseInt(ppa);

             global_lp = lpInt;

             var loadBar = "";
             for (l=0; l < lpInt; l++){
                 loadBar = loadBar + "|";
             };

             var playBar = "";
             for (i=0; i < ppaInt; i++){
                 playBar = playBar + "|";
             };

             $('#player_progress_play_bar').text(playBar);
             $('#player_progress_load_bar').text(loadBar);
        })
        .onSoundComplete( function() {
            $(this).data('isplaying', false);
        });

        $("#player_play").click( function() {
            $('#jquery_jplayer').data('isplaying', true).play();
            $(song_marquee).trigger('unpause');
            return false;
        });

        $("#player_pause").click( function() {
            $('#jquery_jplayer').data('isplaying', false).pause();

            $(song_marquee).trigger('pause');

            return false;
        });

        $("#player_stop").click( function() {
            $('#jquery_jplayer').data('isplaying', false).stop();
            $(song_marquee).trigger('stop');

            return false;
        });

        $("#player_progress_ctrl_bar a").live( "click", function() {
            $("#jquery_jplayer").data('isplaying', true).playHead(this.id.substring(3)*(100.0/global_lp));
            $(song_marquee).trigger('unpause');
            return false;
        });
    });

// ################################### INIT PAGE ############################ //

var song_marquee;

update_page();
$('#menu a').click(function(){ this.blur(); });



});
