/*global $,window */

(function (window) {
	"use strict";

    // Prepare our Variables
    var
        History = window.History,
        document = window.document;

    // Check to see if History.js is enabled for our Browser
    if (!History.enabled) {
        return false;
    }

    // Check Location
    if (document.location.protocol === 'file:') {
        return false;
    }


    $(document).ready(function () {
        var
            /* Application Specific Variables */
            /* Application Generic Variables */
            rootUrl = History.getRootUrl(),
            $body = $(document.body),
            contentCell = $('#contentCell');


        /* A bug in FF: Adding a hidden span element to dom, cause span background to stretch full screen width */
        $('<div id="messageBarContainer"><span id="messageBar"/></div>').hide().prependTo('body');
        $('#messageBar').hide();
        $('#messageBarContainer').show();

        $('#messageBar').ajaxStart(function () {
            $(this).stop(true, true).text('Loading...').show();
        });

        $('#messageBar').ajaxError(function () {
            $(this).stop(true, true).text('Loading failed').show().delay(500);
        });

        $('#messageBar').ajaxSuccess(function () {
            //$(this).text('Success');
        });

        $('#messageBar').ajaxStop(function () {
            $(this).fadeOut(400);
        });

        function showContent(data) {
            contentCell.promise().done(function () {
                var content = $('#content', data);
                document.title = $('#content > h1', data).text();
                content.ajaxify();
                contentCell.html(content).animate({opacity : 1}, 500);
            });
        }

        $.expr[':'].internal = function (obj) {
            var
                $this = $(obj),
                url = $this.attr('href') || '';

            return url.substring(0, rootUrl.length) === rootUrl || url.indexOf(':') === -1;
        };

        // Ajaxify Helper
        $.fn.ajaxify = function () {
            var $this = $(this);

            $this.find('a:internal').click(function (e) {
                var $this = $(this),
                    url = $this.attr('href');

                // Ajaxify this link
                e.preventDefault();
                History.pushState(null, null, url);
                return false;
            });

            // Chain
            return $this;
        };

        $body.ajaxify();

        // Hook into State Changes
        $(window).bind('statechange', function () {
            // Prepare Variables
            var
                State = History.getState(),
                url = State.url,
                relativeUrl = url.replace(rootUrl, '/');

            contentCell.animate({opacity : 0}, 400);

            $.get(relativeUrl).done(function (data) {
                showContent(data);
            }).fail(function (xhr) {
                showContent(xhr.responseText);
            });

        });

    });

}(window)); // end closure
