/**
 * Dependencies: jquery.js, jquery.history.js, imageframe.js, thickbox.js, main.js
 */

$(function() {
    Dispatcher.init();    
});

// Dispatcher will call the proper page methods based on the url
var Dispatcher = {
    init: function() {
        var path = window.location.pathname.replace(RegExp(webroot.replace(/\//,'\/')),'').replace(/\/$/,'');
        if( !window.location.hash && path && path != '/') {
            window.location.href = webroot + '#'+ path;
        }
        Page.init();

        $('#nav-menu a').each(function(){
            var href = Dispatcher.get_url_hash(this.href);
            this.href = href;
            $(this).attr('rel', href.replace(/^#/, ''));
        }).click(function(){
            var hash = this.href.replace(/^.*#+/,'');
            $.historyLoad(hash);
        });

        $.historyInit(Dispatcher.dispatch);
    },

    dispatch: function(hash) {
        hash = hash.replace(/\/$/,'');
        if( !hash ) hash = 'home';
        else if ( hash == 'gallery' ) hash = 'pages';
        hash = hash.split('/');
        var method = hash.slice(0,2).join('_');
        func = eval('Dispatcher.'+method);
        if( typeof(func) != 'function' ) return;
        var args = hash.slice(2);
        func.apply(this, args);
    },

    get_url_hash: function(url) {
        url = url.replace('http://','').replace(window.location.hostname,'').replace('#','').replace(webroot,'').replace(/^\//,'');
        return '#'+url;
    },

    highlight_menu_item: function(rel) {
        $('#nav-menu a').removeClass('ignore').trigger('mouseout');
        $('#nav-menu a[rel='+rel+']').trigger('mouseover').addClass('ignore');
    },

    // These methods call Page object to display content
    home: function() {
        Dispatcher.highlight_menu_item('gallery');
        Page.load_exhibition('current');
        Page.load_page();
    },

    pages: function() {
        Dispatcher.highlight_menu_item('gallery');
        Page.load_page();
        if( $('.column-right').is(':empty') ) Page.load_exhibition('current');
    },

    exhibitions: function() {
        Dispatcher.highlight_menu_item('exhibitions');
        Page.load_exhibition_list();
        if( $('.column-right').is(':empty') ) Page.load_exhibition('current');
    },
    exhibitions_view: function(id) {
        Page.load_exhibition(id);
        if( $('.column-left .content').is(':empty') ) Page.load_page();
    },

    artists: function() {
        Dispatcher.highlight_menu_item('artists');
        Page.load_artist_list();
        if( $('.column-right').is(':empty') ) Page.load_exhibition('current');
    },
    artists_view: function(id) {
        Page.load_artist(id);
        if( $('.column-left .content').is(':empty') ) Page.load_page();
    },

    news: function() {
        Dispatcher.highlight_menu_item('news');
        Page.load_news();
        if( $('.column-right').is(':empty') ) Page.load_exhibition('current');
    }
};


var Page = {
    data : {}, // Data for the currently loading page
    column_switch: 0,  // keep track of which column last loaded (0: right, 1: left)

    // Initialize the page
    init: function() {
        var self = this;
        // Set up columns
        $('.column-left').empty().attr('class','column-right');
        $('#header').wrap('<div class="column-left"></div>');
        $('.column-left').attr('id','').append('<div class="content"></div>').append('<div id="related-frame"></div>');
       
        $(window).resize(function() {
            self.column_right_callback();
            self.column_left_callback();
        });
        $('.column-left').load(function(){self.column_left_callback()});
        $('.column-right').load(function(){self.column_right_callback()});

        // Image replacement for header
        $('#header h1').imageReplace({size:23,pad:0});
        $('#header a').imageReplace({size:13}).textover();
        $('#header .col2 span, #header .col2 a').imageReplace({size:13});
    },
    
    // Called when right column completes loading and on resize
    column_right_callback: function() {
        var h = $('.column-right').height() - $('.secondary-menu').height() - 20;
        $('.column-right .content').height(h);
        $('.jquery-scroller', '.column-right').each(function(){
            this.jqueryScroller.resize();
        });
    },

    // Called when left column completes loading and on resize
    column_left_callback: function() {
        var h = $('.column-left').height() - $('#related-frame').height() - $('#header').height()  - 40;
        $('.column-left .content').height(h);
        $('.jquery-scroller', '.column-left').each(function(){
            this.jqueryScroller.resize();
        });
    },
    
    // Load an exhibition page
    load_exhibition: function(id) {
        var url = (id == 'current')? 'exhibitions/current.json' : 'exhibitions/view/'+id+'.json';
        $.getJSON(url, function(data) {
            if( data.length < 1 ) return;
            Page.data['exhibition'] = data;
            $rcol = $('.column-right').empty().attr('id','exhibition');
            
            var skeleton = '<div class="secondary-menu"><table><tr><td class="col1"></td><td class="col2"></td></tr></table></div>' + 
                           '<div class="content"><div class="images"><div class="image-frame"></div>' +
                           '<div class="image-info"><div class="image-caption"></div></div></div>' +
                           '<div class="text"></div></div>';

            $rcol.append(skeleton);

            // Build top menu
            var exhibit = Page.data.exhibition.Exhibition;
            var $c1 = $('#exhibition .secondary-menu .col1');
            $c1.empty().append('<span class="highlight">'+exhibit.title+'</span><br><span>'+exhibit.formatted_date+'</span>');
            var $c2 = $('#exhibition .secondary-menu .col2');
            $.each(Page.data.exhibition.Textnode, function(i, node) {
                $('<a>'+node.title+'</a>').attr({
                    href: '#'+node.slug,
                    rel: node.slug
                }).appendTo($c2).after('<br>');
            });
            if ( Page.data.exhibition.Textnode && Page.data.exhibition.Textnode.length <= 1 ) {
                $c2.css({width: '1%'}).hide();
                $c1.css({width: 'auto', 'border-right': 'none'});
            }

            // Menu Events
            $('.secondary-menu .col2 a', $rcol).click(function() { 
                var anchor = this;
                $.each(Page.data.exhibition.Textnode, function(i, node){
                    if(node.slug == anchor.rel) {
                        $('.text',$rcol).empty().append(node.body).Scroller({paginate:true});
                    }
                });
                return false;
            }).slice(0,1).click();
            $('.secondary-menu a').imageReplace({size:13,pad:1}).textover();
            $('.secondary-menu span').imageReplace({size:13,pad:1});

            if( Page.data.exhibition.Image.length < 1 && Page.data.exhibition.Textnode.length < 1) {
                $('.content',$rcol).empty().hide().append('<p>Content forthcoming</p>').css('text-align','center').fadeIn();
            }

            // Build images
            if( Page.data.exhibition.Image.length > 0 ) {
                var $images = $('.column-right .images');
                var $i = $('<a><img></a>').appendTo('.image-frame');
                $('img', $i).attr({
                    src: 'img/thumbnail.php?img=gallery/'+Page.data.exhibition.Image[0]['filename']+'&w=450&h=350',
                    alt: 'Image'
                });
                $i.attr({
                    href: webroot + 'media/gallery/'+Page.data.exhibition.Image[0]['filename']
                });
                $('.image-caption',$images).append(Page.data.exhibition.Image[0]['caption']);
                $('.image-frame').ImageFrame( $.map(Page.data.exhibition.Image,function(obj){
                    obj.filename = 'gallery/'+obj.filename;
                    return obj;
                }));
            }            

            $('.scroller-next, .image-next, .image-prev','.column-right').imageReplace({size:13}).textover();
            $('.scroller-prev', '.column-right').show().imageReplace({size:13}).textover().hide();

            $rcol.hide().fadeIn(600, function(){
                $('.column-right').trigger('load');
            });

            $('.col1 span.highlight img').one('load', function() { // fix for long title images (scrollboxes)
                Page.column_right_callback();
            });
            
            // Related Collections
            var related = new RelatedFrame(Page.data.exhibition);

        });
    },

    // Load an artist page
    load_artist: function(id) {
        var url = 'artists/view/'+id+'.json';
        $.getJSON(url, function(data) {
            if( data.length < 1 ) return;
            Page.data['artist'] = data;
            $rcol = $('.column-right').empty().attr('id','artist');
            
            var skeleton = '<div class="secondary-menu"><table><tr><td class="col1"></td><td class="col2"></td></tr></table></div>' +
                           '<div class="content"><div class="images"><div class="image-frame"></div>' +
                           '<div class="image-info"><div class="image-caption"></div></div></div>' +
                           '<div class="text"></div></div>';

            $rcol.append(skeleton);

            // Build top menu
            var artist = Page.data.artist.Artist;
            var $c1 = $('#artist .secondary-menu .col1');
            $c1.empty().append('<span class="highlight">'+artist.name+'</span><br>');
            var $c2 = $('#artist .secondary-menu .col2');
            // Bio
            $('<a>bio</a>').attr({
                href: '#bio',
                rel: 'bio'
            }).appendTo($c2).after('<br>');
            // Text
            $.each(Page.data.artist.Textnode, function(i, node) {
                $('<a>'+node.title+'</a>').attr({
                    href: '#'+node.slug,
                    rel: node.slug
                }).appendTo($c2).after('<br>');
            });
            if ( Page.data.artist.Textnode && Page.data.artist.Textnode.length <= 1 ) {
                $c2.css({width: '1%'}).hide();
                $c1.css({width: 'auto', 'border-right': 'none'});
            }
            
            // Menu Events
            $('.secondary-menu .col2 a', $rcol).click(function() { 
                var anchor = this;
                if( anchor.rel == 'bio' ) {
                    $('.text',$rcol).empty().append(Page.data.artist.Artist.biography).Scroller({paginate:true});
                    return false;
                }
                $.each(Page.data.artist.Textnode, function(i, node){
                    if(node.slug == anchor.rel) {
                        $('.text',$rcol).empty().append(node.body).Scroller({paginate:true});
                    }
                });
                return false;
            }).slice(0,1).click();
            $('.secondary-menu a').imageReplace({size:13,pad:1}).textover();
            $('.secondary-menu span').imageReplace({size:13,pad:1});

            if( Page.data.artist.Image.length < 1 && Page.data.artist.Textnode.length < 1 &&
                !Page.data.artist.Artist.biography ) {
                $('.content',$rcol).empty().hide().append('<p>Content forthcoming</p>').css('text-align','center').fadeIn();
            }

            // Build images
            if( Page.data.artist.Image.length > 0 ) {
                var $images = $('.column-right .images');
                var $i = $('<a><img></a>').appendTo('.image-frame');
                $('img', $i).attr({
                    src: 'img/thumbnail.php?img=gallery/'+Page.data.artist.Image[0]['filename']+'&w=450&h=350',
                    alt: 'Image'
                });
                $i.attr({
                    href: webroot + 'media/gallery/'+Page.data.artist.Image[0]['filename']
                });
                $('.image-caption',$images).append(Page.data.artist.Image[0]['caption']);
                $('.image-frame').ImageFrame( $.map(Page.data.artist.Image,function(obj){
                    obj.filename = 'gallery/'+obj.filename;
                    return obj;
                }));
            }            

            $('.scroller-next, .image-next, .image-prev','.column-right').imageReplace({size:13}).textover();
            $('.scroller-prev', '.column-right').show().imageReplace({size:13}).textover().hide();

            $rcol.hide().fadeIn(600, function(){
                $('.column-right').trigger('load');    
            });

            $('.col1 span.highlight img').one('load', function() { // fix for long title images (scrollboxes)
                Page.column_right_callback();
            });

            // Related Collections
            var related = new RelatedFrame(Page.data.artist);

        });
    },
    
    // Loads the exhibition index list
    load_exhibition_list: function() {
        $.get('exhibitions',function(data){
            $('.column-left .content').empty().append('<div class="text">').attr('id','exhibition-list');
            var html = $.trim(data).replace(/<div[^>]+>/, '').replace(/<\/div>$/, '');
            $('.column-left .text').html(html).Scroller({paginate:true,nextButtonHTML:'<a>MORE</a>'});
            $('.column-left .text a').each(function(){
                this.href= Dispatcher.get_url_hash(this.href);
            }).click(function(){
                var hash = this.href.replace(/^.*#/,'');
                $.historyLoad(hash);
            });
            $('.scroller-next','.column-left').imageReplace({size:13}).textover();
            $('.scroller-prev','.column-left').show().imageReplace({size:13}).textover();
            $('.column-left .text > div').addClass('clearfix');

            $('.column-left h2').imageReplace({size:13}).height(16);
            $('.column-left').trigger('load');
         });

    },
    
    // Loads the artist index list
    load_artist_list: function() {
        $.get('artists',function(data){
            $('.column-left .content').empty().append('<div class="text">').attr('id','artist-list');
            var html = $.trim(data).replace(/<div[^>]+>/, '').replace(/<\/div>$/, '');
            $('.column-left .text').html(html).Scroller({paginate:true,nextButtonHTML:'<a>MORE</a>'});            
            $('.column-left .text a').each(function(){
                this.href= Dispatcher.get_url_hash(this.href);
            }).click(function(){
                var hash = this.href.replace(/^.*#/,'');
                $.historyLoad(hash);
            });

            $('#artist-list ul li').slice(0,-1).after('<li><img src="img/dot.png" alt="*" class="dot"></li>');
            $('.column-left').trigger('load');

         });

    },
    
    // Load a given page into the Page object
    load_page: function(page_slug) {
        var url = 'pages.json';
        $.getJSON(url, function(data) {
            if( data.length < 1 ) return;
            Page.data['pages'] = data;            
            var page;
            $.each(Page.data['pages'], function(i,p) {
                if( p['Page']['slug'] == page_slug ) {
                    page = p;
                }
            });
            if( !page ) page = Page.data['pages'][0];
            
            $lcol = $('.column-left');
            $content = $('.content', $lcol).empty().attr('id','page');
            $content.prepend('<ul id="pages-menu"></ul><div class="text"></div>');
            if (Page.data['pages'].length > 1 ){
                $.each(Page.data['pages'], function(i, p){
                    $('<li><a href="#" rel="'+p['Page']['slug']+'">'+p['Page']['title']+'</a></li>').
                        appendTo('#pages-menu');
                });
            }
            $('#pages-menu > li').slice(0,-1).after('<li><img src="img/dot.png" alt="*" class="dot"></li>');
            $('#pages-menu > li > a[rel="'+page['Page']['slug']+'"]').addClass('hover');
            $('#pages-menu > li > a').click(function(){
                var p = $(this).attr('rel')
                Page.load_page(p);
                return false;
            }).imageReplace({size:13}).textover();
            $('.text',$lcol).append(page['Textnode'][0]['body']).show().Scroller({paginate:true}).
                parent().hide().fadeIn(600);
            $('.scroller-next', '.column-left').imageReplace({size:13}).textover();
            $('.scroller-prev', '.column-left').show().imageReplace({size:13}).textover();
            $('.column-left').trigger('load');

        });
    },

    load_news: function() {
        var $lcol = $('.column-left');
        var $content = $('.content', $lcol).hide().empty().attr('id','news-index');
        $.get('news', function(data) {
            data = data.replace(/<div id="news-index"[^>]*>/,'').replace(/<\/div>\s*$/,'');
            var $text = $('<div class="text"></div>').appendTo($content);
            $text[0].innerHTML = data;
            $content.show();
            $('.column-left').trigger('load');
            $('.text',$content).Scroller({paginate:true});
            $('.scroller-next', $content.parent()).imageReplace({size:13}).textover();
            $('.scroller-prev', $content.parent()).show().imageReplace({size:13}).textover().hide();
        });
    }
   
};


var RelatedFrame = function() {
    return this.initialize.apply(this, arguments);
}

RelatedFrame.prototype = {
    exhibitions_url: 'exhibitions.json',
    artists_url: 'artists.json',

    initialize: function (data) {
        var self = this;
        var $frame = $('#related-frame').empty();
        var $parent = $frame.parent();
        $frame.append('<div class="related-exhibitions"></div><div class="related-artists"></div>');
       
        self.selected_exhibition = self.selected_artist = 0;

        $.getJSON(self.exhibitions_url, function(exhibit_data) {
            for( i=0; i < exhibit_data.length; i++){
                exhibit = exhibit_data[i];
                if( exhibit.Exhibition.id == data.Exhibition.id ) { // remove current
                    exhibit_data.splice(i,1);
                    --i; continue;
                }
                for( j=0; j < data.RelatedExhibition.length; j++) { // related go up-front
                    related = data.RelatedExhibition[j];
                    if( related.id == exhibit.Exhibition.id ) {
                        exhibit_data.splice(i,1);
                        exhibit_data.unshift(exhibit);                        
                    }                    
                }                
            }
            self.exhibitions = $.unique(exhibit_data);
            self.updateExhibition(0);
        });

        if(data.Artist && !data.RelatedArtist ) data.RelatedArtist = data.Artist;
        $.getJSON(self.artists_url, function(artist_data) {
            for( i=0; i < artist_data.length; i++){
                artist = artist_data[i];
                if(artist.Artist.id == data.Artist.id) { // remove current
                    artist_data.splice(i,1);
                    --i; continue;
                }
                for( j=0; j < data.RelatedArtist.length; j++) { // related go up-front
                    related = data.RelatedArtist[j];
                    if( related.id == artist.Artist.id ) {
                        artist_data.unshift(artist);
                        artist_data.splice(i,1);
                    }                    
                }                
            }
            self.artists = $.unique(artist_data);
            self.updateArtist(0);            
        });
        
    },

    rotateExhibition: function(n) {
        var self = this;
        n = parseInt(n);
        var i = ((n + self.selected_exhibition) + self.exhibitions.length) % self.exhibitions.length;
        self.selected_exhibition = i;
        self.updateExhibition(i);
    },
    
    rotateArtist: function(n) {
        var self = this;
        n = parseInt(n);
        var i = ((n + self.selected_artist) + self.artists.length) % self.artists.length;
        self.selected_artist = i;
        self.updateArtist(i);
    },

    updateExhibition: function(index) {
        var self = this;
        if( ! self.exhibitions) return;
        var exhibition = self.exhibitions[index];
        $container = $('.related-exhibitions', self.parent).empty();

        // Build DOM elements
        $container.append('<div class="related-image"><a class="related-prev"><img src="img/left.png"></a><a href="#exhibitions/view/'+exhibition['Exhibition']['slug']+'" class="related-main-image"></a><a class="related-next"><img src="img/right.png"></a></div><div class="related-info"></div>');
        if( exhibition['Image'][0] || exhibition['Invitation'] ) {
            var file;
            if(exhibition['Invitation']['filename']) {
                file = exhibition['Invitation']['filename'];
            } else if (exhibition['Image'].length > 0 ) {
                file = exhibition['Image'][0]['filename'];
            }
            if ( file ) {
                $('<img>').attr({
                    'src':'img/thumbnail.php?img=gallery/'+encodeURIComponent(file)+'&w=100&h=90&crop=1'
                }).appendTo( $('.related-main-image', $container) );
            }
        }
        var title = exhibition['Exhibition']['short_title']? exhibition['Exhibition']['short_title'] : exhibition['Exhibition']['title'];
        $('.related-info', $container).append('<span class="highlight title">'+title.substr(0,34)+'</span><br><span class="date">'+exhibition['Exhibition']['formatted_date']+'</span><br><a href="#exhibitions">VIEW ALL EXHIBITIONS</a>');

        // Image rollovers and replacements
        $('.related-prev img, .related-next img', $container).rollover();

        // Events
        $('.related-next', $container).click(function(){
            self.rotateExhibition(-1);
            return false;
        });
        $('.related-prev', $container).click(function(){
            self.rotateExhibition(1);
            return false;
        });
        $('.related-main-image, .related-info a:last', $container).click(function(){
            var hash = this.href.replace(/^.*#/,'');
            $.historyLoad(hash);
        });
    },

    updateArtist: function(index) {
        var self = this;
        if( ! self.artists) return;
        var artist = self.artists[index];
        $container = $('.related-artists', self.parent).empty();

        // Build DOM elements
        $container.append('<div class="related-image"><a class="related-prev"><img src="img/left.png"></a><a href="#artists/view/'+artist['Artist']['slug']+'" class="related-main-image"></a><a class="related-next"><img src="img/right.png"></a></div><div class="related-info"></div>');
        if( artist['Image'][0] ) {
            $('<img>').attr({
                'src':'img/thumbnail.php?img=gallery/'+encodeURIComponent(artist['Image'][0]['filename'])+'&w=100&h=90&crop=1'
            }).appendTo( $('.related-main-image', $container) );
        }      
        $('.related-info', $container).append('<span class="highlight title">'+artist['Artist']['name']+'</span><br><a href="#artists">VIEW ALL ARTISTS</a>');
        
        // Image rollovers and replacements
        $('.related-prev img, .related-next img', $container).rollover();

        // Events
        $('.related-next', $container).click(function(){
            self.rotateArtist(1);
            return false;
        });
        $('.related-prev', $container).click(function(){
            self.rotateArtist(-1);
            return false;
        });
        $('.related-main-image, .related-info a:last', $container).click(function(){
            var hash = this.href.replace(/^.*#/,'');
            $.historyLoad(hash);
        });
    }
};
