var application = {
    data : [],
    pictures_path : "pictures/",
    current_picture_path : "",

    launch_timer : false,
    cleared_launch_timer : false,

    hash_key : "",
    picture_key : 1,

    init : function(data)
    {
        this.data = jQuery.parseJSON(data);

        $(window).ready(function() {
            application.setup_popovers();
        });

        $(window).load(function() {
            application.setup_nav();
            application.setup_tabs();

            application.get_hash_key();
            application.get_picture_key();
        })

        $(window).resize(function() {
            application.resize_picture();
        });

        $(window).hashchange(function() {
            application.hash_key = application.get_hash_key();
            application.picture_key = application.get_picture_key();

            if ((d = application.data[application.hash_key]) !== undefined && d[1][application.picture_key-1] !== undefined)
            {
                application.current_picture_path = application.get_picture_path();

                application.set_category();
                application.set_nav_links();
                application.load_picture();
            }
            else
            {
                alert("No such category or picture.");
                application.set_hash($("#nav h2 a:first").html(), 1);
            }
        });
    },

    set_hash : function(category, id)
    {
        window.location.hash = "/" + encodeURIComponent(category) + "/" + id;
    },

    get_hash_key : function()
    {
        var h = window.location.hash.split('/');
        return decodeURIComponent(h[1]);
    },

    get_picture_key : function()
    {
        var h = window.location.hash.split('/');
        return parseInt(h[2]);
    },

    get_picture_path : function(hash_key, picture_key)
    {
        var hash_key = typeof(hash_key) != 'undefined' ? hash_key : this.hash_key;
        var picture_key = typeof(picture_key) != 'undefined' ? picture_key : this.picture_key;

        return this.pictures_path + this.data[hash_key][0] + '/' + this.data[hash_key][1][picture_key-1][0];
    },

    content_loader_overlay : function(enable)
    {
        var id = "content_loader"
        if (!$("#" + id).length) $("body").prepend("<div id=\"" + id + "\">loading content</div>");
        (enable) ? $("#" + id).show() : $("#" + id).hide();
    },

    resize_picture : function()
    {
        var img, ratio;
        img = $("#content > img:first-child");
        ratio = this.data[this.hash_key][1][this.picture_key-1][1];

        if (ratio <= 1)
        {
            var width = Math.round(ratio * $(window).height());
            img.css("margin-left", Math.round(($(window).width() - width) / 2));
            img.css("width", width);
            img.css("height", $(window).height());
        }
        else
        {
            var height = Math.round($(window).width() / ratio);
            img.css("margin-top", Math.round(($(window).height() - height) / 2));
            img.css("width", $(window).width());
            img.css("height", height);
        }
    },

    resize_nav : function(animate)
    {
        var width = 1;
        $("#categories > li").each(function(i, e) {
            width += $(e).width() + 10;
        });

        $("#categories div").css("left", ((width > 320) ? width : 320));

        if (this.hash_key)
        {
            var cell = $("#categories li li:visible:first-child");
            var cell_width = cell.outerWidth() + parseInt(cell.css("margin-left")) + parseInt(cell.css("margin-right"));

            var picture_count = this.data[this.hash_key][1].length;
            var scroll_container = $("#categories > li.active div");
            var scrollable = $("#categories > li.active ul");
            var visible_index = Math.round((scroll_container.width() / cell_width / 2) + 0.5);

            scrollable.width(picture_count * cell_width);
            var scroll_target = ((this.picture_key-visible_index) / picture_count) * scrollable.width();

            scroll_container.stop(true, false);
            if (animate)
                scroll_container.animate({scrollLeft : scroll_target}, 500);
            else
                scroll_container.scrollLeft(scroll_target);
        }

        $("#click-left, #click-right").css("padding-top", ($(window).height() / 2 - 10));
    },

    setup_nav : function()
    {
        if (!($.browser.msie && parseInt($.browser.version, 10) == 7))
        {
            $(document).mousemove(function(e) {
                if (application.cleared_launch_timer)
                {
                    if (e.pageY < ($("#nav").height()) + 100 || $(".popover").is(":visible") )
                    {
                        if (!$("#nav").is(":visible"))
                        {
                            $("#nav").fadeIn("fast");
                            application.resize_nav(false);
                        }
                    }
                    else
                        $("#nav").fadeOut('fast');
                }
                else
                {
                    if (!application.launch_timer)
                        application.launch_timer = setTimeout(function() {
                            application.cleared_launch_timer = true;
                        }, 2000);
                }
            });
        }

        $("#content").prepend($("<a />").attr("href", "#").attr("id", "click-right").html("&gt;"));
        $("#content").prepend($("<a />").attr("href", "#").attr("id", "click-left").html("&lt;"));

        application.resize_nav(false);
    },

    set_nav_links : function()
    {
        if ((d = this.data[this.hash_key][1]))
        {
            e = $("#click-left");
            if (d[(this.picture_key-2)])
            {
                e.removeClass("disabled");
                e.unbind("click");
                e.click(function() {
                    if ($(".popover").is(":visible"))
                    {
                        $(".popover").fadeOut('fast');
                        return false;
                    }
                    application.set_hash(application.hash_key, application.picture_key-1);
                    return false;
                });
            }
            else e.addClass("disabled");

            e = $("#click-right");
            if (d[this.picture_key])
            {
                e.removeClass("disabled");
                e.unbind("click");
                e.click(function() {
                    if ($(".popover").is(":visible"))
                    {
                        $(".popover").fadeOut('fast');
                        return false;
                    }
                    application.set_hash(application.hash_key, application.picture_key+1);
                    return false;
                });
            }
            else e.addClass("disabled");
        }
    },

    setup_popovers : function()
    {
        var a = $("<a />").html("close").attr("href", "#").addClass("close-popover").click(function() {
            $(this).parent().parent().fadeOut('fast');
            return false;
        });

        $(".popover > div").append(a);

        $(".popover").hide();
        $(".popover_link a").click(function() {
            var div = $("" + $(this).attr("href"));
            if (!div.is(":visible"))
            {
                $(".popover").fadeOut('fast');
                div.fadeIn('fast');
            }
            return false;
        });

        $(".popover").click(function() {
            $(this).fadeOut('fast');
        });

        $(".popover > div").click(function() {
            return false;
        });
    },

    setup_tabs : function()
    {
        $("#nav h2 a").not(".popover_link a").click(function () {
            application.set_hash($(this).html(), 1);
            return false;
        });

        $("#nav li li a").each(function(i, link) {
            $(link).click(function() {
                var hash_key = $(this).parent().parent().parent().parent().find("h2 a").html();
                var picture_key = $(this).parent().index() + 1;
                application.set_hash(hash_key, picture_key);
                return false;
            })
        });

        if (!window.location.hash) this.set_hash($("#nav h2 a:first").html(), 1);
        else $(window).hashchange();
    },

    set_category : function()
    {
        var i = 0;

        $(".popover").fadeOut("fast");
        d = this.data[this.hash_key];

        cat_id = "#cat-" + this.hash_key.replace(/\s+/gi, '-');

        if (!(cat_li = $(cat_id)).hasClass("active"))
        {
            $("#nav li").removeClass("active");
            cat_li.addClass("active");
        }
        else
        {
            $("#nav li li").removeClass("active");
        }

        $($(cat_id + " li").get(this.picture_key-1)).addClass("active");
        application.resize_nav(true);
    },

    load_picture : function()
    {
        this.content_loader_overlay(true);
        $("#content > img").remove();

        $("<img />").attr("src", this.current_picture_path).load(function() {
            if (application.current_picture_path == $(this).attr("src"))
            {
                $(this).hide();
                $("#content").prepend($(this));
                $(window).resize();
                application.content_loader_overlay(false);
                $(this).fadeIn(300);
            }
            else
                $(this).remove();
        });

        /* preload next image */
        if (this.data[this.hash_key][1][this.picture_key])
        {
            $("<img />").attr("src", this.get_picture_path(this.hash_key, this.picture_key+1)).load(function() { $(this).remove() });
        }
    }
}
