window.ABS = window.ABS || {};

jQuery(function () {
    ABS.spi.initialize();
});

/* general container for bible search behavior */
ABS.spi = (function ($) {
    var that = {};
    
    /* public functions */
    that.initialize = function () {
        ABS.jst.initialize();
        ABS.pageSetup.initialize();
        Backbone.history.start();
    };

    return that;
}(jQuery));

/* 
 * Class for our JavaScript templates
 * Lots of logic taken from ICanHaz.js
 * */
ABS.jst = (function($) {
    var that = {},
        templates = {};

    that.initialize = function () {
        that.grabTemplates();
    };

    that.grabTemplates = function () {
        $('script[type="text/html"]').each(function(a, b) {
            var script = $(this),
                text   = $.trim(script.html());

            that.addTemplate(script.attr('id'), text);
            script.remove();
        });
    };

    that.addTemplate = function(name, templateString) {
        if (that[name]) { throw "Template \"" + name + "\" exists"; }
        that[name] = function (args) {
            args = _.extend({}, args);
            
            // interpolate the template, passing it an 'args' variable that can 
            // be used to test the original arguments
            return _.template(
                templateString, 
                _.extend(args, {
                    i18n: ABS.common.i18n, 
                    attrEsc: ABS.util.attrEsc, 
                    args: args, 
                    locale: ABS.bootstrap.locale
                })
            );
        };
    };
    
    return that;
}(jQuery));

ABS.util = (function($) {
    var that = {};

    // escape attribute values
    that.attrEsc = function(text) {
        return text.replace(/[&<>"'`]/g, function (chr) {
            return '&#' + chr.charCodeAt(0) + ';';
        });
    };

    that.validUrl = function(id, url) {
        if (url) {
            return url;
        }
        else {
            return ABS.common.osis.toUrl(id);
        }
    };
   
    // given a language abbreviation, return the full
    // localized name of the language
    that.languageAbbrToName = function(abbr) {
        return window.ABS.bootstrap.langs[abbr];
    };
    
    // given some response HTML, get the DOM element(s) identified by the 
    // given selector
    that.extractResponse = function (txt, selector) {
        return $("<div/>")
            .append(txt.replace(/<script(.|\s)*?\/script>/g, ""))
            .find(selector);
    };
    
    return that;
}(jQuery));
 
/* Sets up the page when it's loaded */
ABS.pageSetup = (function ($) {
    var that = {};
    that.initialize = function () {
        window.ABS.app = new ABS.Controller.Main();
        window.ABS.spi.myTags  = new ABS.Collection.TagList();
        window.ABS.spi.myNotes = new ABS.Collection.NoteList();
        window.ABS.spi.myVersions = new ABS.Collection.UserVersionList();

        if (ABS.bootstrap !== undefined) { 
            if ((ABS.bootstrap.my_tags !== undefined) && 
                (ABS.bootstrap.my_tags !== null)) {
                window.ABS.spi.myTags.refresh(ABS.bootstrap.my_tags);
            }

            if ((ABS.bootstrap.my_notes !== undefined) && 
                (ABS.bootstrap.my_notes !== null)) {
                window.ABS.spi.myNotes.refresh(ABS.bootstrap.my_notes);
            }

            if ((ABS.bootstrap.my_versions !== undefined) && 
                (ABS.bootstrap.my_versions !== null)) {
                window.ABS.spi.myVersions.refresh(ABS.bootstrap.my_versions);
            }
        }

        addLeftSidebar();
        addMainViewer();
        setupSearchForm();
        setupModals();
        
        $('a.login-link').click(function(ev) {
            ev.preventDefault();

            ABS.spi.leftSidebar.showTransferAnimation(ev.target);
            ABS.spi.leftSidebar.makePanelActive('login');
        });
        
        $(window).resize(_.debounce(function(ev) {
            $('.scrollable:visible').each(function(i, scrollable) {
                scrollable = $(scrollable);
                // is there a better way to find related footer?
                var footer = scrollable.closest('.divsection').first().siblings('.divfooter');
                var bottom = scrollable.closest('.maincolumn').first().children('.divfooter');
                var newHeight = $(window).height() - scrollable.offset().top - footer.outerHeight() - bottom.outerHeight();
                if (scrollable.height() !== newHeight) {
                    scrollable.height(newHeight);
                }
            });

            if (window.ABS.spi.mainViewer !== undefined) {
                window.ABS.spi.mainViewer.updateCopyrightNoticeWidth();
            }

        }, 50));
        $(window).resize();
        
    };
    
    function addLeftSidebar() {
        if ($('#main-viewer-area').length === 0) {
            // Only insert the sidebar if there is a main viewer to put it next to
            return;
        }
        
        // add a window name so links can target it, if needed
        window.name = 'bibles-home';
        
        $('#content').find('div.onecol').remove();
        $('div.tencol').first().removeClass('tencol').addClass('sevencol last');
        window.ABS.spi.leftSidebar = new ABS.View.Sidebar({
            
            // FIXME: these panel names should be i18n'd, but they can't be yet 
            // because the name is used to create a class name that JS and CSS 
            // will hook into.  We should explicitly set a class name apart from
            // the display name to allow the copy to be i18n'd.
            panels: {
                'welcome' : [
                    new ABS.View.WelcomeView({
                        name: 'Welcome',
                        displayname: ABS.common.i18n('welcome')
                    })
                ],
                'browse' : [
                    new ABS.View.BrowseView({
                        name: 'Browse',
                        displayname: ABS.common.i18n('browse')
                    }),
                    {primary: true}
                ],
                'note'   : [
                    new ABS.View.NoteSidebarView({
                        name: 'Notebook',
                        displayname: ABS.common.i18n('my_notes'),
                        collection: window.ABS.spi.myNotes
                    }),
                    {primary: true}
                ],
                'tag'    : [
                    new ABS.View.TagSidebarView({
                        name: 'Tags',
                        displayname: ABS.common.i18n('my_tags'),
                        collection: window.ABS.spi.myTags
                    }),
                    {primary: true}
                ],
                'noteSubset' : [
                    new ABS.View.NoteSidebarView({
                        name: 'Notebook',
                        displayname: ABS.common.i18n('my_notes'),
                        collection: window.ABS.spi.myNotes
                    }),
                    {primary: false}
                ],
                'tagCreate' : [
                    new ABS.View.TagCreateView({
                        name: 'Create Tag',
                        displayname: ABS.common.i18n('create_tag'),
                        collection: window.ABS.spi.myTags
                    }),
                    {primary: false}
                ],
                'noteCreate' : [
                    new ABS.View.NoteCreateView({
                        name: 'Create Note',
                        displayname: ABS.common.i18n('create_note'),
                        collection: window.ABS.spi.myNotes
                    }),
                    {primary: false}
                ],
                'contact' : [
                    new ABS.View.ContactUsView({
                        name: 'contactus_zenbox',
                        displayname: ABS.common.i18n('contact_us')
                    }),
                    {secondary: false}
                ],
                'login' : [
                    new ABS.View.SidebarLoginView({
                        name: 'Login',
                        displayname: ABS.common.i18n('login')
                    }),
                    {secondary: false}
                ],
                'verified' : [
                    new ABS.View.SidebarVerifiedView({
                        name: 'Verified',
                        displayname: ABS.common.i18n('account_verified')
                    }),
                    {secondary: false}
                ],
                'notverified' : [
                    new ABS.View.SidebarNotVerifiedView({
                        name: 'Not Verified',
                        displayname: ABS.common.i18n('bad_verification_key')
                    }),
                    {secondary: false}
                ],
                'register' : [
                    new ABS.View.SidebarRegisterView({
                        name: 'Register',
                        displayname: ABS.common.i18n('register')
                    }),
                    {secondary: false}
                ],
                 'developer' : [
                     new ABS.View.DeveloperView({
                         name: 'Developer Tools',
						 displayname: ABS.common.i18n('developer_tools')
                     }),
                     {secondary: true}
                 ]
            }
        });
        var sidebarEl = $(window.ABS.spi.leftSidebar.render().el);
        var footerEl = $('#pagefooter');
        sidebarEl.append(footerEl.clone());
        footerEl.closest('.row').remove();
        $(sidebarEl).find('.scrollable').height(
            ABS.View.util.scrollableHeightGuess()
        );
        var sidebarHolder = $('#content').find('.divsection').first();
        sidebarHolder.prepend(sidebarEl);
    }

    function addMainViewer() {
        var viewerArea = $('#main-viewer-area');
        window.ABS.spi.mainViewer = new ABS.View.MainViewerView({
            el : viewerArea
        });
    }

    function setupSearchForm() {
        var searchFormHolder = $('#search-form-holder');
        window.ABS.spi.searchForm = new ABS.View.SearchFormView({
            el : searchFormHolder
        });

        $('div.slide-block').find('.open-close').click(function (ev) {
            ev.preventDefault();
            $('.versions-form').slideToggle('400');
        });

        $(document).bind('click', function (ev) {
            if (!$(ev.target).parents().hasClass('slide-block')) {
                $('.versions-form').slideUp('400');
            }
        });
        
        // hintify the search box on page load, and focus it
        searchFormHolder.find('input[type="text"]').hint().focus();
    }

    function setupModals() {
        $('.forgotPassword').fancierBox({width: 600, height: 330});
    }
    
    return that;
}(jQuery));

