/**
 * JS code for Zotero's website
 *
 * LICENSE: This source file is subject to the ECL license that is bundled with this
 * package in the file LICENSE.txt. It is also available through the
 * world-wide-web at this URL: http://www.opensource.org/licenses/ecl1.php
 *
 * @category  Zotero_WWW
 * @package   Zotero_WWW_Index
 * @copyright Copyright (c) 2008  Center for History and New Media (http://chnm.gmu.edu)
 * @license   http://www.opensource.org/licenses/ecl1.php    ECL License
 * @version   $Id: zotero.js 5449 2009-11-28 03:05:29Z fcheslack $
 * @since     0.0
 */

var J = jQuery.noConflict();
jQuery(document).ready(function() {
    zoterojs.base.init();

    // Page templates that require additional js should add an object within the zoterojs object. 
    // Then define zoterojsClass to be the name of the object within zoteojs.
    if(undefined !== window.zoterojsClass){
        try{
            zoterojs[zoterojsClass].init();
        }catch(err){}
    }
});

/**
* Object containing all javascript necessary for zotero_www
* 
* @param string baseURL The URL for the application's public directory. Must be set in the global namespace.
* @param string staticPath The URL for static media. Must be set in the global namespace.
**/
var zoterojs = {    

    baseURL:    baseURL,
    staticPath: staticPath,
    baseDomain: baseDomain,

    base: {

        init: function(){
            this.tagline();
            this.setupSearch();
            this.setupNav();
            J("#sitenav .toggle").click(this.navMenu);
        },
    
        /**
         * Selects a random tagline for the header
         *
         * @return void
         **/
        tagline: function(){
            var taglines = [
                'See it. Save it. Sort it. Search it. Cite it.',
                'Leveraging the long tail of scholarship.',
                'A personal research assistant. Inside your browser.',
                'Goodbye 3x5 cards, hello Zotero.',
                'Citation management is only the beginning.',
                'The next-generation research tool.',
                'Research, not re-search',
                'The web now has a wrangler.'
            ];
            var pos = Math.floor(Math.random() * taglines.length);
            J("#tagline").text(taglines[pos]);
        },

        /**
         * Make the flyout menus work
         *
         * @return void
         **/
        navMenu: function (e) {
            // Toggle the selected menu and hide all other menus
            subnav = J(this).next("ul.subnav");
            subnav.toggle();
            J("ul.subnav").not(subnav).hide();
            
            // Hide the menu if the user clicks anywhere
            J(document).one("click", {subnav:subnav}, function(e){
                e.data.subnav.hide();
            });
            return false;
        },
        
        /**
         * Send search to the right place
         *
         * @return void
         **/
        setupSearch: function() {
            var context = "support";
            var label   = "";
            
            // Look for a context specific search
            if(undefined !== window.zoterojsSearchContext){
                context = zoterojsSearchContext;
                switch (context) {
                    case "people"        : label = "Search for people";    break;
                    case "group"         : label = "Search for groups";    break;
                    case "documentation" : label = "Search documentation"; break;
                    case "support"       : label = "Search support";       break;
                }
            }
            
            J("#header-search-query").val("");
            J("#header-search-query").inputLabel(label, {color:"#aaa"});
            J("#header-search-form").submit(function(){
                var searchUrl = zoterojs.baseDomain + "/search/#" + context;
                var query     = J("#header-search-query").val();
                if(query != "" && query != label){ 
                    searchUrl = searchUrl + "/" + encodeURIComponent(query);
                }
                location.href = searchUrl;
                return false;
            });
        },
        
        /**
         * Select the right nav tab
         *
         * @return void
         **/
        setupNav: function () {
            var tab = "";
            // Look for a context specific search
            if(undefined !== window.zoterojsSearchContext){
                tab = zoterojsSearchContext;
                if(tab == "support") { tab = ""; }
                
            }
            // special case for being on the home page
            if(location.pathname == "/" && location.href.search("forums.") < 0){
                tab = "home";
            }
            J("#"+tab+"-tab").addClass("selected-nav");
        },
    },
    
    extension_style: {
        init: function(){
            var url = zoterojs.baseURL + "/extension/autocomplete/";
            J("#styleSearch").autocomplete({
                'url': url,
                'matchContains':true,
                'mustMatch': true,
                'cacheLength': 1,
                extraParams:{"type":"style"},
                formatItem: function(resultRow, i, total, value) {
                    return resultRow[0];
                }
            });
            J("#styleSearch").autocomplete("result", function(event, data, formatted){
                location.href = zoterojs.baseURL + "/extension/style/" + data[1];
            });
        },
    },
    
    settings_cv: {
        init: function(){            
            // Delete the cv section when the delete link is clicked
            J("#cv-sections .cv-delete").live("click", function(e){
                if(confirm ("Are you sure you want to delete this section")){
                    J(this).closest("li").remove();
                    zoterojs.settings_cv.hideMoveLinks();
                    return false;
                }
            });
            
            // Add a new cv section when the add button is clicked
            J("#cv-sections .cv-insert-section").live("click", function(e){
                // Make sure the template textarea isn't a tiny mce instance
                tinyMCE.execCommand('mceRemoveControl', true, "template");
                
                // Get the number of sections that exist before adding a new one
                sectionCount  = J("#cv-sections li").length;
                
                // Clone the template html
                newSection    = J("#cv-section-template li").clone(true);
                
                // The new textarea needs a unique id for tinymce to work
                newTextareaID = "cv_" + (sectionCount + 1) + "_text";
                newSection.children("textarea").attr("id", newTextareaID);
                
                // Insert the new section into the dom and activate tinymce control
                J(this).closest("li").after(newSection);
                tinyMCE.execCommand('mceAddControl', true, newTextareaID);
                
                zoterojs.settings_cv.hideMoveLinks();
                return false;
            });
            
            // Add a new cv collection when the add button is clicked
            J("#cv-sections .cv-insert-collection").live("click", function(e){
                // Get the number of sections that exist before adding a new one
                sectionCount  = J("#cv-sections li").length;
                
                // Clone the template html
                newSection    = J("#cv-collection-template li").clone(true);
                
                // The new textarea needs a unique id for tinymce to work
                newCollectionID = "cv_" + (sectionCount + 1) + "_collection";
                newHeadingID    = "cv_" + (sectionCount + 1) + "_heading";
                newSection.children("select").attr("id", newCollectionID);
                newSection.children("select").attr("name", newCollectionID);
                newSection.children(".cv-heading").attr("name", newHeadingID);
                
                // Insert the new section into the dom
                J(this).closest("li").after(newSection);
                
                zoterojs.settings_cv.hideMoveLinks();
                return false;
            });
            
            // Move the section down when the down link is clicked
            J("#cv-sections .cv-move-down").live("click", function(e){
                if(J(this).siblings("textarea").length > 0){
                    // Get the id of this section's textarea so we can disable the tinymce control before the move
                    textareaId = J(this).siblings("textarea")[0].id;
                    tinyMCE.execCommand('mceRemoveControl', true, textareaId);
                    
                    // Move the section and reenable the tinymce control
                    J(this).closest("li").next().after(J(this).closest("li"));
                    tinyMCE.execCommand('mceAddControl', true, textareaId);
                }
                else {
                    J(this).closest("li").next().after(J(this).closest("li"));
                }

                zoterojs.settings_cv.hideMoveLinks();
                return false;
            });
            
            // Move the section up when the up link is clicked
            J("#cv-sections .cv-move-up").live("click", function(e){
                if(J(this).siblings("textarea").length > 0){
                    // Get the id of this section's textarea so we can disable the tinymce control before the move
                    textareaId = J(this).siblings("textarea")[0].id;
                    tinyMCE.execCommand('mceRemoveControl', true, textareaId);
                    
                    // Move the section and reenable the tinymce control
                    J(this).closest("li").prev().before(J(this).closest("li"));
                    tinyMCE.execCommand('mceAddControl', true, textareaId);
                }
                else {
                    J(this).closest("li").prev().before(J(this).closest("li"));
                }
                zoterojs.settings_cv.hideMoveLinks();
                return false;
            });
            
            // reindex the field names before submitting the form
            J("#cv-submit").click(function(e){
                J("#cv-sections li").each(function(i){
                    if(J(this).attr("class") == "cv-freetext"){
                        var heading = J(this).children(".cv-heading").attr("name", "cv_"+(i+1)+"_heading");
                        if(heading.val() == "Enter a section name"){
                            heading.val("");
                        }
                        J(this).children(".cv-text").attr("name", "cv_"+(i+1)+"_text");
                    }
                    else if(J(this).attr("class") == "cv-collection"){
                        var heading = J(this).children(".cv-heading").attr("name", "cv_"+(i+1)+"_heading");
                        if(heading.val() == "Enter a section name"){
                            heading.val("");
                        }
                        J(this).children("select.cv-collection").attr("name", "cv_"+(i+1)+"_collection");
                    }
                });
            });
            
            // Hide unusable move links
            this.hideMoveLinks();
            
            // Add some helper text over the section name
            J("li input").inputLabel("Enter a section name", {color:"#d5d5d5"});
        },
        
        // Hides move links that can't be used. e.g. you can't move the top section up.
        hideMoveLinks: function(){
            J("#cv-sections .cv-move-down").show();
            J("#cv-sections .cv-move-up").show();
            J("#cv-sections .cv-move-up:first").hide();
            J("#cv-sections .cv-move-down:last").hide();
        },
    },
    
    settings_account: {
        init: function(){
            //insert slug preview label
            J('input#username').after("<label id='slugpreview'>Profile URL: " +
                                      zoterojs.baseDomain + "/" +
                                      zoterojs.utils.slugify(J("input#username").val()) +
                                      "</label>");
    
            // When the value of the input box changes, 
            J("input#username").bind("keyup change", zoterojs.user_register.nameChange);
            parent.checkUserSlugTimeout;
        },
        
        nameChange: function(){
            //make sure label is black after each change before checking with server
            J("#slugpreview").css("color", "black");
            
            //create slug from username
            parent.slug = zoterojs.utils.slugify( J("input#username").val() );
            J("#slugpreview").text( "Profile URL: " + zoterojs.baseDomain + "/" + parent.slug );
            
            //check slug with server after half-second
            clearTimeout(parent.checkUserSlugTimeout);
            parent.checkUserSlugTimeout = setTimeout('zoterojs.user_register.checkSlug()', 500);
        },
        
        checkSlug: function(){
            J.getJSON(baseURL + "/user/checkslug", {"slug":slug}, function(data){
                if(data.valid){
                    J("#slugpreview").css("color", "green");
                } else {
                    J("#slugpreview").css("color", "red");
                }
            });
        },
    },
    
    settings_profile: {
        init: function(){
            tinyMCE.execCommand('mceAddControl', true, "profile_bio1");
            J("#submit").bind("click", function(){ tinyMCE.execCommand('mceRemoveControl', true, 'profile_bio1');});
        }
    },
    
    settings_privacy: {
        init: function(){
            if(!J("input#privacy_publishLibrary").attr("checked")){
                J("input#privacy_publishNotes").attr("disabled","disabled");
            }
            J("input#privacy_publishLibrary").bind("change", function(){
                if(!J("input#privacy_publishLibrary").attr("checked")){
                    J("input#privacy_publishNotes").removeAttr("checked").attr("disabled","disabled");
                }
                else{
                    J("input#privacy_publishNotes").removeAttr("disabled");
                }
            });
        }
        
    },
    
    settings_apikeys: {
        init: function(){
            // enforce valid dependencies of library/notes/revoke checkboxes
            J(".pk_row").each(function(){
                var key = J(this).attr("id");
                var library_access = J("input#" + key + "_library");
                //if library unchecked, notes cannot be checked or enabled
                if(!library_access.attr("checked")){
                    J("input#" + key + "_notes").attr("disabled","disabled").removeAttr("checked");
                }
                //disable + uncheck notes if library unchecked, enable notes if library checked
                library_access.bind("change", function(e){
                    var key = J(e.target).closest("tr").attr("id");
                    if(!J(e.target).attr("checked")){
                        J("input#" + key + "_notes").removeAttr("checked").attr("disabled","disabled");
                    }
                    else{
                        J("input#" + key + "_notes").removeAttr("disabled");
                    }
                });
                //disable + uncheck library and notes if revoke selected, enable library and notes if revoke deselected
                J("input#" + key + "_delete").bind("change", function(e){
                    var key = J(e.target).closest("tr").attr("id");
                    if(J(e.target).attr("checked")){
                        J("input#" + key + "_library").removeAttr("checked").attr("disabled","disabled");
                        J("input#" + key + "_notes").removeAttr("checked").attr("disabled","disabled");
                    }
                    else{
                        J("input#" + key + "_library").removeAttr("disabled");
                    }
                });
            });
        }
    },
    
    settings_newkey: {
        init: function(){
            if(!J("input#library_access").attr("checked")){
                J("input#notes_access").attr("disabled","disabled");
            }
            J("input#library_access").bind("change", function(){
                if(!J("input#library_access").attr("checked")){
                    J("input#notes_access").removeAttr("checked").attr("disabled","disabled");
                }
                else{
                    J("input#notes_access").removeAttr("disabled");
                }
            });
            J("input#name").focus();
        }
    },
    
    settings_storage: {
        init: function(){
            selectedLevel = J("input[name=storageLevel]:checked").val();
            
            zoterojs.settings_storage.showSelectedResults(selectedLevel);
            
            J("input[name=storageLevel]").change(function(){
                zoterojs.settings_storage.showSelectedResults(J("input[name=storageLevel]:checked").val());
            })
            
            J("#purge-button").click(function(){
                if(confirm("You are about to remove all uploaded files associated with your personal library.")){
                    J("#confirm_delete").val('confirmed');
                    return true;
                }
                else{
                    return false;
                }
            });
        },
        
        showSelectedResults: function(selectedLevel){
            if(selectedLevel == 2){
                J("#order-result-div").html(zoteroData.orderResult2);
            }
            else if(selectedLevel == 3){
                J("#order-result-div").html(zoteroData.orderResult3);
            }
            else if(selectedLevel == 4){
                J("#order-result-div").html(zoteroData.orderResult4);
            }
        }
    },
    
    settings_commons: {
        init: function(){
        },
    },
    
    
    group_new: {
        init: function(){
            var timeout;
            // When the value of the input box changes, 
            J("input#name").keyup(function(e){
                clearTimeout(timeout);
                timeout = setTimeout('zoterojs.group_new.nameChange()', 300);
            });
            
            J("input[name=group_type]").change(zoterojs.group_new.nameChange);
            
            //insert slug preview label
            J('input#name').after("<label id='slugpreview'>Group URL: " + 
                                      zoterojs.baseDomain + "/" + "groups/" +
                                      zoterojs.utils.slugify(J("input#name").val()) +
                                      "</label>");
            
        },
        
        nameChange: function(){
            //make sure label is black after each change before checking with server
            J("#slugpreview").css("color", "black");
            var groupType = J('input[name=group_type]:checked').val();
            // update slug preview text
            if(groupType == 'Private'){
                J("#slugpreview").text("Group URL: " +zoterojs.baseDomain + "/" + "groups/<number>");
            }
            else{
                J("#slugpreview").text("Group URL: " +zoterojs.baseDomain + "/" + "groups/" +
                zoterojs.utils.slugify(J("input#name").val()) + "/<number>");
            }
            
            if(groupType != 'Private'){
                // Get the value of the name input
                var input = J("input#name").val();
                // Poll the server with the input value
                J.getJSON(baseURL+"/group/checkname/", {"input":input}, function(data){
                    J("#namePreview span").text(data.slug);
                    if(data.valid){
                        J("#slugpreview").css({"color":"green"});
                    } else {
                        J("#slugpreview").css({"color":"red"});
                    }
                    J("#namePreview img").remove();
                });
            }
        },
    },
    
    group_settings: {
        init: function(){
            tinyMCE.execCommand('mceAddControl', true, "description");
            J("#settings_submit").bind("click", function(){ tinyMCE.execCommand('mceRemoveControl', true, 'description');});
            J("#deleteForm").submit(function(){
                if(confirm("This will permanently delete this group, including any items in the group library")){
                    J("#confirm_delete").val('confirmed');
                    return true;
                }
                else{
                    return false;
                }
            });
        }
    },
    
    group_view: {
        init: function(){
            if(zoteroData.member == false){
                J("#membership-button").click(zoterojs.group_view.joinGroup);
            }
            else{
                J("#membership-button").click(zoterojs.group_view.leaveGroup);
            }
            
            J("#group-message-form").hide();
            J("#new-message-link").click(function(){
                J("#group-message-form").toggle();
                return false;
            });
            J(".delete-group-message-link").click(function(){
                if(confirm("Really delete message?")){
                    return true;
                }
                else{
                    return false;
                }
            });
            
        },
        
        joinGroup: function(){
            J("#membership-button").after("<img id='spinner' src='/static/images/theme/ajax-spinner.gif'/>");
            J('img#spinner').show();
            J.post("/groups/" + zoteroData.groupID + "/join", {ajax:true}, function(data){
                if(data.pending == true){
                    J("#membership-button").replaceWith("Membership Pending");
                    J('img#spinner').remove();
                }
                else if(data.success == true){
                    J("#membership-button").val("Leave Group")
                                           .unbind()
                                           .remove()
                                           .click(zoterojs.group_view.leaveGroup)
                                           .wrap(document.createElement("li"))
                                           .appendTo('ul.group-information');
                    
                    if(zoteroData.group.type == 'Private'){
                        window.location = '/groups';
                    }
                    J('img#spinner').remove();
                }
                else{
                    J('img#spinner').remove();
                }
            }, 
            "json");
        },
        
        leaveGroup: function(){
            if(confirm("Leave group?")){
                J("#membership-button").after("<img id='spinner' src='/static/images/theme/ajax-spinner.1231947775.gif'/>");
                J('img#spinner').show();
                J.post("/groups/" + zoteroData.groupID + "/leave", {ajax:true}, function(data){
                    if(data.success == true){
                        J("#membership-button").val("Join Group").unbind().click(zoterojs.group_view.joinGroup);
                        J('img#spinner').remove();
                        J('a[title="'+zoteroData.user.username+'"]').remove();
                    }
                    else{
                        J('img#spinner').remove();
                    }
                }, 
                "json");
            }
        },
        
    },
    
    group_index: {
        init: function(){
            J("button[id^='invite-join-']").click(function(){
                J.post(J(this).attr("href"), {ajax:true}, function(data){
                    
                }, "text");
                var groupID = J(this).attr("id").substr(12);
                J(this).closest("li").remove();
            });
            J("button[id^='invite-ignore-']").click(function(){
                J.post(J(this).attr("href"), {ajax:true}, function(data){
                    
                }, "text");
                J(this).closest("li").remove();
            });
            flowplayer("group-intro-screencast", zoterojs.staticPath+"/library/flowplayer/flowplayer-3.1.1.swf");
        },
        
    },
    
    user_register: {
        init: function(){
            //insert slug preview label
            J('input#username').after("<label id='slugpreview'>Profile URL: " + 
                                      zoterojs.baseDomain + "/" +
                                      zoterojs.utils.slugify(J("input#username").val()) +
                                      "</label>");

            // When the value of the input box changes, 
            J("input#username").bind("keyup change", zoterojs.user_register.nameChange);
            parent.checkUserSlugTimeout;
        },
        
        nameChange: function(){
            //make sure label is black after each change before checking with server
            J("#slugpreview").css("color", "black");
            
            //create slug from username
            parent.slug = zoterojs.utils.slugify( J("input#username").val() );
            J("#slugpreview").text( "Profile URL: " + zoterojs.baseDomain + "/" + parent.slug );
            
            //check slug with server after half-second
            clearTimeout(parent.checkUserSlugTimeout);
            parent.checkUserSlugTimeout = setTimeout('zoterojs.user_register.checkSlug()', 500);
        },
        
        checkSlug: function(){
            J.getJSON(baseURL + "/user/checkslug", {"slug":slug}, function(data){
                if(data.valid){
                    J("#slugpreview").css("color", "green");
                } else {
                    J("#slugpreview").css("color", "red");
                }
            });
        },
    },
    /*
    user_home: {
        init: function(){
            zoterojs.user_home.zoteroTips = new Array("TIP 1", "TIP 2", "TIP 3", "TIP 4", "TIP 5");
            J("#zotero-tip").append(zoterojs.user_home.zoteroTips[Math.floor(Math.random()*(zoterojs.user_home.zoteroTips.length))]);
            J(".feed-page").hide();
            J(".feed-div").each(function(){
                J(this).children(".feed-page:first").show();
            });
            J(".feed-page-prev").click(function(){
                J(this).closest(".feed-page").hide().prev(".feed-page").show();
                return false;
            });
            J(".feed-page-next").click(function(){
                J(this).closest(".feed-page").hide().next(".feed-page").show();
                return false;
            });
        },
    },
    */
    user_profile: {
        init: function(){
            J('#invite-button').click(function(){
                var groupID = J("#invite_group").val();
                J.post("/groups/inviteuser", {ajax:true, groupID:groupID, userID:zoteroData.profileUserID}, function(data){
                    if(data == 'true'){
                        J('#invited-user-list').append("<li>" + J("#invite_group > option:selected").html() + "</li>");
                        J('#invite_group > option:selected').remove();
                        if(J('#invite_group > option').length == 0){
                            J('#invite_group').remove();
                            J('#invite-button').remove();
                        }
                    }
                }, "text");
            });
            J('#follow-button').click(zoterojs.user_profile.follow);
            J("#tag-cloud").tagcloud({type:'list', height:200, sizemin:8, sizemax:18, colormin:'#99000', colormax:'#99000'});
        },
        
        follow: function(){
            var followText = J('#follow-status-text');
            var followHtml = followText.html();
            followText.html("<img src='/static/images/theme/ajax-spinner.1231947775.gif'/>");
            J.post("/user/follow/" + zoteroData.profileUserID, {ajax:true}, function(data){
                    if(data.status == "following"){
                        J('#follow-button').val("Unfollow");
                        followText.html( followHtml.replace("not following", "following"));
                    }
                    else if(data.status == 'not following'){
                        J('#follow-button').val("Follow");
                        followText.html( followHtml.replace("following", "not following"));
                    }
                }, "json");
        }
    },
    
/*    user_tag: {
        init: function(){
            J("#spinner").hide();
            if(location.hash == "#ajaxy"){
                J("#tag-type-select").change(function(){
                    zoteroData.tagsPage = 0;
                    zoteroData.tagType = J(this).val();
                    zoterojs.user_tag.next_tags();
                });
                J(".tag-list .paginationControl").remove();
                J(".tag-list").append("<a href='' id='prev-tags'>< Previous</a> | <a href='' id='next-tags'>Next ></a><br /><img class='ajax-spinner' id='spinner' src='/static/images/theme/ajax-spinner.gif'/>");
                J("#spinner").hide();
                J("#prev-tags").click(zoterojs.user_tag.prev_tags);
                J("#next-tags").click(zoterojs.user_tag.next_tags);
                J(".tag-link").live('click', function(){
                    zoteroData.tag = J(this).attr('tag');
                    zoterojs.user_tag.load_items();
                    return false;
                });
                J(".paginator-first").live('click', function(){
                    zoteroData.itemsPage = 1;
                    zoterojs.user_tag.load_items();
                    return false;
                });
                J(".paginator-prev").live('click', function(){
                    zoteroData.itemsPage -= 1;
                    zoterojs.user_tag.load_items();
                    return false;
                });
                J(".paginator-next").live('click', function(){
                    zoteroData.itemsPage += 1;
                    zoterojs.user_tag.load_items();
                    return false;
                });
                J(".paginator-last").live('click', function(){
                    zoteroData.itemsPage = zoteroPaginatorItemLast;
                    zoterojs.user_tag.load_items();
                    return false;
                });
                
                zoteroData.pageSize = 25;
                zoteroData.itemsPage = 1;
                zoteroData.tagsPage = 1;
                zoteroData.tagType  = '';
                zoteroData.tags = {'all': [], 'manual': [], 'auto': []};
                
                switch(J("#tag-type-select").val()){
                    case '':
                        zoteroData.tags.all = new Array(J("#tag-list").html())
                        break;
                    case '0':
                        zoteroData.tags.manual = new Array(J("#tag-list").html());
                        break;
                    case '1':
                        zoteroData.tags.auto = new Array(J("#tag-list").html())
                        break;
                }
            }
            else{
                J("#tag-type-select").change(function(){
                    J(this).parent().submit();
                });
            }
        },
        
        next_tags: function(){
            console.log("next_tags");
            zoteroData.tagsPage++;
            if(zoteroData.tagType === '0') var curTags = zoteroData.tags.manual;
            else if(zoteroData.tagType === '1') var curTags = zoteroData.tags.auto;
            else var curTags = zoteroData.tags.all;
            
            if(curTags.length < (zoteroData.tagsPage)){
                J("#spinner").show();
                J.get("/proxyrequest", 
                        {'userslug':zoteroData.libraryUserSlug, 
                         'target':'tags', 
                         'limit':zoteroData.pageSize, 
                         'start':((zoteroData.tagsPage - 1)*zoteroData.pageSize),
                         'order':'title',
                         'sort':'asc',
                         'fq':(zoteroData.tagType === '' ? '' : 'TagType:'+zoteroData.tagType),
                         'content':'full'
                         },
                        function(data, textStatus){
                            J("#tag-list").html(data);
                            curTags[zoteroData.tagsPage-1] = data;
                            J("#spinner").hide();
                        }, "html");
            }
            else {
                J("#tag-list").html(curTags[zoteroData.tagsPage-1]);
            }
            return false;
        },
        
        prev_tags: function(){
            console.log("prev_tags");
            zoteroData.tagsPage--;
            if(zoteroData.tagType === '0') var curTags = zoteroData.tags.manual;
            else if(zoteroData.tagType === '1') var curTags = zoteroData.tags.auto;
            else var curTags = zoteroData.tags.all;
            J("#tag-list").html(curTags[zoteroData.tagsPage-1]);
            return false;
        },
        
        load_items: function(){
            console.log("load_items");
            console.log("tag:" + zoteroData.tag);
            J("#spinner").show();
            J.get("/proxyrequest", {'content':'none', 'userslug':zoteroData.libraryUserSlug, 'target':'items', 'tag':zoteroData.tag, 'limit':zoteroData.pageSize, 'start':((zoteroData.itemsPage - 1) * zoteroData.pageSize)}, function(data, textStatus){
                J(".major-col").html(data);
                J("#spinner").hide();
                return false;
            });
        },
        
    },
    
    group_tag: {
        init: function(){
            J("#tag-type-select").change(function(){
                J(this).parent().submit();
            });
        }
    },
*/    
    user_library: {
        init: function(){
            //console.log("initializing user_library");
            //set up zotero mappings
            //zoteroData.mappings = {};
            //zoteroData.mappings;
            
            zoteroData.pageSize = 25;
            zoteroData.itemsPage = 1;
            zoteroData.collectionID = '';
            zoteroData.curDisplayedVars = {};
            
            J("#collection-list ul").hide().siblings(".folder-toggle").children(".folder-spacer").removeClass("folder-spacer").addClass("img-tick-right").addClass("toggle-icon");
            J(".current-collection").parents("ul").show();
            J("#collection-list-label").click(function(){J("#collection-list").slideToggle("fast");});
            J("#tags-list-label").click(function(){J("#tags-list-div").slideToggle("fast");});
            J(".folder-toggle").live('click', function(){
                if(J(this).children(".img-tick-right").length){
                    J(this).siblings("ul").show("fast");
                    J(this).children(".img-tick-right").removeClass("img-tick-right").addClass("img-tick-down");
                }
                else if(J(this).children(".img-tick-down").length) {
                    J(this).siblings("ul").hide("fast");
                    J(this).children(".img-tick-down").removeClass("img-tick-down").addClass("img-tick-right");
                }
            });
            
            /*
            if(zoteroData.ui == "ajax"){
                //setup initial vars from hash or default
                zoteroData.userPrefs = {
                    columns : ['title', 'creatorSummary', 'dateAdded'],
                    columnHeadings : ['Title', 'Creator', 'Date Added'],
                };
                zoteroData.pageSize = 25;
                zoteroData.itemsPage = 1;
                zoteroData.tagsPage = 1;
                zoteroData.tagType  = J("#tag-type-select").val();
                zoteroData.tags = {'auto':[], 'user':[]};
                zoteroData.selectedTags = [];
                
                zoteroData.hashVars = zoterojs.user_library.parseHash();
                
                J.each(zoteroData.hashVars, function(i, val){
                    if(i == "tag"){ zoteroData["selectedTags"] = val; }
                    else { zoteroData[i] = val; }
                });
                J("#tag-type-select").val(zoteroData.tagType);
                
                // get tags and items that should be on current page
                zoterojs.user_library.load_all_tags();
                zoterojs.user_library.load_items();
                
                J(".item-row").live('click', function(){
                    var itemID = J(this).closest('tr').attr('id');
                    J(this).closest('tr').children('td:first').prepend("<img id='spinner' src='/static/images/theme/ajax-spinner.gif'/>");
                    J.each(zoteroData.items.entries, function(i, val){
                        if(val.itemID == itemID){
                            J("#item-dialog").html(zoterojs.user_library.item_table(val)).dialog().dialog('option', 'title', val.title).dialog('open');
                            return false;
                        }
                    });
                    return false;
                });
                
                J(".collection-row a").live('click', function(){
                    zoteroData.collectionID = /collection-(\d+)/.exec(J(this).attr('id'))[1];
                    J(".current-collection").removeClass('current-collection');
                    J(this).addClass('current-collection');
                    zoterojs.user_library.updateHash();
                    zoterojs.user_library.load_items();
                    return false;
                });
                
                J(".tag-link").live('click', function(){
                    if(J.inArray(J(this).attr('tag'), zoteroData.selectedTags) != (-1) ){
                        var tag = J(this).attr('tag');
                        zoteroData.selectedTags = J.map(zoteroData.selectedTags, function(n, i){ if(n == tag) return null; return n});
                        J(this).parent("li").removeClass("selected-tag");
                    }
                    else {
                        zoteroData.selectedTags.push(J(this).attr('tag'));
                        J(this).parent("li").addClass("selected-tag");
                    }
                    zoterojs.user_library.updateHash();
                    zoterojs.user_library.load_items();
                    return false;
                });
                
                //setup paginators
                J("#tag-paginator-first").live('click', function(){zoteroData.tagsPage = 1; zoterojs.user_library.updateHash(); return false;});
                J("#tag-paginator-prev").live('click', function(){zoteroData.tagsPage -= 1; zoterojs.user_library.updateHash(); return false;});
                J("#tag-paginator-next").live('click', function(){zoteroData.tagsPage = Number(zoteroData.tagsPage) + 1; zoterojs.user_library.updateHash(); return false;});
                J("#tag-paginator-last").live('click', function(){zoteroData.tagsPage += 1; zoterojs.user_library.updateHash(); return false;});
                
                J("#item-paginator-first").live('click', function(){zoteroData.itemsPage = 1; zoterojs.user_library.updateHash(); return false;});
                J("#item-paginator-prev").live('click', function(){zoteroData.itemsPage -= 1; zoterojs.user_library.updateHash(); return false;});
                J("#item-paginator-next").live('click', function(){zoteroData.itemsPage = Number(zoteroData.itemsPage) + 1; zoterojs.user_library.updateHash(); return false;});
                J("#item-paginator-last").live('click', function(){zoteroData.itemsPage = 1; zoterojs.user_library.updateHash(); return false;});
                
                J("#tag-type-select").change(function(){
                    zoteroData.tagType = J(this).val();
                    zoterojs.user_library.display_tags();
                });
                
                //initialize jquery ajax history plugin
                jQuery.historyInit(zoterojs.user_library.updatePage);
            }
            else {
            */
                J("#tag-type-select").change(function(){
                    J(this).parent().submit();
                });
            /*
            }
            */
        },
        /*
        parseHash: function(hash, updateVars) {
            //console.log('parseHash');
            updateVars = typeof updateVars != 'undefined' ? updateVars : false;
            hash = typeof hash != 'undefined' ? hash : location.hash;
            hash = hash.replace(/^#/, '');
            var delimiter = "/";
            var args = hash.split(delimiter);
            var item_vars = {'tag':[]};
            while(args.length){
                var key = args.shift();
                if(key){
                    if(item_vars[key]){
                        if(typeof item_vars[key] == "string"){
                            var tmp = item_vars[key];
                            item_vars[key] = [tmp, args.shift()];
                        }
                        else {
                            item_vars[key].push(args.shift());
                        }
                    }
                    else{
                        item_vars[key] = args.shift();
                    }
                }
            }
            if(!item_vars.tag) item_vars.tag = [];
            return item_vars;
        },
        
        updateHash: function(){
            //console.log('updateHash');
            hashVars = {
                itemsPage : zoteroData.itemsPage,
                tagsPage : zoteroData.tagsPage,
                tagType : zoteroData.tagType,
                tag : zoteroData.selectedTags,
                };
            var hashString = '';
            J.each(hashVars, function(key, val){
                if(typeof val != "object"){
                    hashString += "/" + key + "/" + val;
                }
                else{
                    J.each(val, function(subkey, subval){
                        hashString += "/" + key + "/" + subval;
                    });
                }
            });
            location.hash = "#" + hashString;
            jQuery.historyLoad('#' + hashString);
            return hashString;
        },
        
        updatePage: function(hash){
            console.log('updatePage');
            var hashVars = zoteroData.hashVars = zoterojs.user_library.parseHash(location.hash);
            //display different tags if hash changed
            var reloadTags = false;
            var reloadItems = false;
            if(hashVars.tagsPage != zoteroData.curDisplayedVars.tagsPage || hashVars.tagType != zoteroData.curDisplayedVars.tagType){
                reloadTags = true;
            }
            //display different items if values changed in hash
            if(hashVars.itemsPage != zoteroData.curDisplayedVars.itemsPage){
                reloadItems = true;
            }
            if(hashVars.collection != zoteroData.curDisplayedVars.collectionID && (hashVars.collection || zoteroData.curDisplayedVars.collectionID)){
                reloadItems = true;
            }
            J.each(hashVars.tag, function(i, val){
                if(hashVars.tag[i] != zoteroData.curDisplayedVars.selectedTags[i]){
                    reloadItems = true;
                    return false;
                }
            });
            
            J.each(hashVars, function(i, val){
                if(i == "tags"){ zoteroData["selectedTags"] = val; }
                else { zoteroData[i] = val; }
            });
            
            if(reloadTags) {zoterojs.user_library.display_tags();}
            if(reloadItems) {zoterojs.user_library.load_items();}
        },
        
        load_items: function(){
            //console.log("getJSON items");
            window.scrollBy(0, -5000);
            J(".major-col").html("<img id='spinner' src='/static/images/theme/ajax-spinner.gif'/>");
            var requrl = "/jsonproxyrequest";
            var tagQuery = "";
            if(zoteroData.selectedTags.length > 0){
                tagQuery = 'tag=' + encodeURIComponent(zoteroData.selectedTags[0]);
                for(var i = 1; i < zoteroData.selectedTags.length; i++){
                    tagQuery += "&tag=" + encodeURIComponent(zoteroData.selectedTags[i]);
                }
            }
            if(tagQuery != ""){
                requrl += "?" + tagQuery;
            }
            
            var args = {'userslug':zoteroData.libraryUserSlug, 
                         'target':'items', 
                         'limit':zoteroData.pageSize, 
                         'start':((zoteroData.itemsPage - 1)*zoteroData.pageSize),
                         //'order':'Title',
                         //'sort':'asc',
                         'fq': '',
                         'content':'full'
                         };
            if(zoteroData.collectionID){
                args.collection = zoteroData.collectionID;
            }
            
            J.getJSON(requrl, 
                        args,
                        function(data, textstatus){
                            zoteroData.items = data;
                            
                            zoterojs.user_library.display_items(data.entries);
                        });
            
        },
        
        display_items: function(entries){
            //console.log('display_items');
            var columns = zoteroData.userPrefs.columns;
            var columnHeadings = zoteroData.userPrefs.columnHeadings;
            var itemTypeClass = function(itemType, mimeType, linkMode) 
                {
                    if (itemType == 'attachment') {
                        if (mimeType == 'application/pdf') {
                            itemType += '-pdf';
                            
                        }
                        else {
                            switch (linkMode) {
                                case 0: itemType += '-file'; break;
                                case 1: itemType += '-file'; break;
                                case 2: itemType += '-snapshot'; break;
                                case 3: itemType += '-web-link'; break;
                            }
                        }
                    }
                    return "img-" + itemType;
                };
            var output = '<table><thead>';
            J.each(columnHeadings, function(i, val){
                output += "<th>" + val + "</th>";
            });
            output += '</thead><tbody>';
            J.each(entries, function(i, entry){
                output += '<tr id="' + entry.itemID + '" class="item-row clickable">';
                J.each(columns, function(i, col){
                    if(col == 'title'){
                        output += '<td class="title"><span class="' + itemTypeClass(entry.itemType) + '"></span>' + entry.title + '</td>';
                    }
                    else {
                        output += '<td>' + entry[col] + '</td>';
                    }
                });
                output += '</tr>';
                //'<td class="summary">' + val.creatorSummary + '</td><td class="date-added">' + val.dateAdded + '</td></tr>';
            });
            output += '</tbody></table>';
            
            //update pagination links
            var paginationControl = "";//J("#tags-list-div .paginationControl").empty();
            if(zoteroData.itemsPage > 1){
                //show first and prev links
                paginationControl += "<a id='item-paginator-first' class='paginator-first' href='" + window.location.href.replace("itemPage/"+zoteroData.itemsPage, "itemPage/1") + "'>First</a>";
                paginationControl += " | <a id='item-paginator-prev' class='paginator-prev' href='" + window.location.href.replace("itemPage/"+zoteroData.itemsPage, "itemPage/"+(zoteroData.itemsPage-1)) + "'>Prev</a>";
            }
            if(zoteroData.items.totalResults > (zoteroData.itemsPage * zoteroData.pageSize)){
                //show next and last
                if(window.location.href.match(/itemPage\/[\d]+/)){
                    paginationControl += " | <a id='item-paginator-next' class='paginator-next' href='" + window.location.href.replace("itemPage/"+zoteroData.itemsPage, "itemPage/1") + "'>Next</a>";
                    paginationControl += " | <a id='item-paginator-last' class='paginator-last' href='" + window.location.href.replace("itemPage/"+zoteroData.itemsPage, "itemPage/"+(zoteroData.itemsPage-1)) + "'>Last</a>";
                }
                else{
                    paginationControl += " | <a id='item-paginator-next' class='paginator-next' href='" + window.location.href.replace("itemPage/"+zoteroData.itemsPage, "itemPage/1") + "'>Next</a>";
                    paginationControl += " | <a id='item-paginator-last' class='paginator-last' href='" + window.location.href.replace("itemPage/"+zoteroData.itemsPage, "itemPage/"+(zoteroData.itemsPage-1)) + "'>Last</a>";
                }
            }
            
            J(".major-col").html(output);
            J(".major-col").append(paginationControl);
            zoteroData.curDisplayedVars.itemsPage = zoteroData.itemsPage;
            zoteroData.curDisplayedVars.collectionID = zoteroData.collectionID;
            zoteroData.curDisplayedVars.selectedTags = zoteroData.selectedTags;
        },
        
        item_table: function(item){
            var output = '<table><tbody>';
            output += '<tr><th>Item Type</th><td>' + item.itemType + '</td></tr>';
            J.each(item.creators, function(i, val){
                output += '<tr><th>' + val.creatorType + '</th><td>' + ((typeof val["name"]) == "object" ? val["name"].firstName + " " + val["name"].lastName : val["name"]) + '</td></tr>';
            });
            J.each(item.fields, function(i, val){
                output += '<tr><th>' + i + '</th><td>' + val + '</td></tr>';
            });
            output += '<tr><th>Date Added</th><td>' + item.dateAdded + '</td></tr>';
            output += '<tr><th>Date Modified</th><td>' + item.dateModified + '</td></tr>';
            output += '<tr><th>Attached</th><td>' + 'not implemented' + '</td></tr>';
            if(item.itemType == 'note'){
                output += '<tr><th>Note Text</th><td>' + item.note + '</td></tr>';
            }
            output += '</tbody></table>';
            return output;
        },
        
        load_all_tags: function(){
            //console.log("getJSON tags");
            J.getJSON("/jsonproxyrequest", 
                        {'userslug':zoteroData.libraryUserSlug, 
                         'target':'tags', 
                         //'limit':zoteroData.pageSize, 
                         //'start':((zoteroData.tagsPage - 1)*zoteroData.pageSize),
                         'order':'title',
                         'sort':'asc',
                         'fq': '',
                         'content':'full'
                         },
                        function(data, textstatus){
                            zoteroData.tags = data;
                            zoteroData.tags.user = [];
                            zoteroData.tags.auto = [];
                            J.each(zoteroData.tags.entries, function(i, val){
                                if(val.properties.type){
                                    zoteroData.tags.auto.push(val);
                                }
                                else{
                                    zoteroData.tags.user.push(val);
                                }
                            });
                            zoterojs.user_library.display_tags(data);
                        });
            
        },
        
        display_tags: function(){
            //console.log('display_tags');
            var tagList = J("#tag-list").empty();
            var starti = (zoteroData.tagsPage - 1) * zoteroData.pageSize;
            
            if(zoteroData.tagType == 'user'){
                var tagArray = zoteroData.tags.user;
            }
            else if(zoteroData.tagType == 'auto'){
                var tagArray = zoteroData.tags.auto;
            }
            else {
                var tagArray = zoteroData.tags.entries;
            }
            
            for(var i = starti; i < starti + zoteroData.pageSize; i++){
                if(tagArray.length <= i) break;
                tagList.append("<li><a class='tag-link' tag='" + encodeURIComponent(tagArray[i].title) +
                "' href='/" + zoteroData.libraryUserSlug + "/items/tag/" + encodeURIComponent(tagArray[i].title) +
                "'>" + tagArray[i].title + "</a></li>");
            }
            
            //update pagination links
            var paginationControl = J("#tags-list-div .paginationControl").empty();
            if(zoteroData.tagsPage > 1){
                //show first and prev links
                paginationControl.append("<a id='tag-paginator-first' class='paginator-first' href='" + window.location.href.replace("tagPage/"+zoteroData.tagsPage, "tagPage/1") + "'>First</a>");
                paginationControl.append(" | <a id='tag-paginator-prev' class='paginator-prev' href='" + window.location.href.replace("tagPage/"+zoteroData.tagsPage, "tagPage/"+(zoteroData.tagsPage-1)) + "'>Prev</a>");
            }
            if(tagArray.length > (zoteroData.tagsPage * zoteroData.pageSize)){
                //show next and last
                if(window.location.href.match(/tagPage\/[\d]+/)){
                    paginationControl.append(" | <a id='tag-paginator-next' class='paginator-next' href='" + window.location.href.replace("tagPage/"+zoteroData.tagsPage, "tagPage/1") + "'>Next</a>");
                    paginationControl.append(" | <a id='tag-paginator-last' class='paginator-last' href='" + window.location.href.replace("tagPage/"+zoteroData.tagsPage, "tagPage/"+(zoteroData.tagsPage-1)) + "'>Last</a>");
                }
                else{
                    paginationControl.append(" | <a id='tag-paginator-next' class='paginator-next' href='" + window.location.href.replace("tagPage/"+zoteroData.tagsPage, "tagPage/1") + "'>Next</a>");
                    paginationControl.append(" | <a id='tag-paginator-last' class='paginator-last' href='" + window.location.href.replace("tagPage/"+zoteroData.tagsPage, "tagPage/"+(zoteroData.tagsPage-1)) + "'>Last</a>");
                }
            }
            
            //update selected tags highlighting
            J(".tag-link").each(function(i){
                if(J.inArray(J(this).attr("tag"), zoteroData.selectedTags) != (-1) ){
                    J(this).parent("li").addClass("selected-tag");
                }
            });
            
            J("#spinner").hide();
            zoteroData.curDisplayedVars.tagsPage = zoteroData.tagsPage;
            zoteroData.curDisplayedVars.tagType = zoteroData.tagType;
        },
        */
    },
    
    group_library: {
        init: function(){
            J("#collection-list ul").hide().siblings(".folder-toggle").children(".folder-spacer").removeClass("folder-spacer").addClass("img-tick-right").addClass("toggle-icon");
            J(".current-collection").parents("ul").show();
            J("#collection-list-label").click(function(){J("#collection-list").slideToggle("fast");});
            J("#tags-list-label").click(function(){J("#tags-list-div").slideToggle("fast");});
            J(".folder-toggle").live('click', function(){
                if(J(this).children(".img-tick-right").length){
                    J(this).siblings("ul").show("fast");
                    J(this).children(".img-tick-right").removeClass("img-tick-right").addClass("img-tick-down");
                }
                else if(J(this).children(".img-tick-down").length) {
                    J(this).siblings("ul").hide("fast");
                    J(this).children(".img-tick-down").removeClass("img-tick-down").addClass("img-tick-right");
                }
            });
        },
    },
    
    message_inbox: {
        init: function(){
            var checked = false;
            var selector = J("#selector");
            
            J("#selector").change(function(){
                if(checked){
                    checked = false;
                    selector.attr("checked", false);
                    J("input[type=checkbox]").attr("checked", false);
                }
                else{
                    checked = true;
                    selector.attr("checked", true);
                    J("input[type=checkbox]").attr("checked", true);
                }
            });
            
            J("input[type=checkbox]").change(function(){
                if(J("input[type=checkbox][checked=false][id!=selector]").length > 0){
                    selector.attr("checked", false);
                    checked = false;
                }
                else{
                    selector.attr("checked", true);
                    checked = true;
                }
            });
            
            J.each(zoteroData.messages, function(i, msg){
                if(msg.read == 1){
                    J("#message-row-" + msg.messageID).addClass("read-message");
                }
            });
            
            J("#read-button").click(function(){zoterojs.message_inbox.readStatus(true);});
            J("#unread-button").click(function(){zoterojs.message_inbox.readStatus(false);});
            J("#delete-button").click(function(){zoterojs.message_inbox.deleteMessage();});
            
        },
        
        //set all checked messages to read/unread
        readStatus: function(read){
            var messageIDs = "";
            var rows = J([]);
            J("#message-spinner").show();
            
            if(J("input[type=checkbox][id^=check-]:checked").length == 0){
                return true;
            }
            J("input[type=checkbox][id^=check-]:checked").each(function(){
                messageIDs += this.id.substr(6) + ",";
                if(!rows) rows = J("#message-row-"+this.id.substr(6));
                else rows = rows.add("#message-row-"+this.id.substr(6));
            });
            
            if(read == true){
                J.post("/message/read", {ajax:true, messageIDs:messageIDs }, function(data){
                    if(data.success == true){
                        J("input[type=checkbox]").attr("checked", false);
                        checked = false;
                        rows.addClass("read-message");
                        J("#message-spinner").hide();
                    }
                    else {
                        J("#message-spinner").hide();
                        return false;
                    }
                }, "json");
            }
            else{
                J.post("/message/unread", {ajax:true, messageIDs:messageIDs }, function(data){
                    if(data.success == true){
                        J("input[type=checkbox]").attr("checked", false);
                        checked = false;
                        rows.removeClass("read-message");
                        J("#message-spinner").hide();
                    }
                    else {
                        J("#message-spinner").hide();
                        return false;
                    }
                }, "json");
            }
        },
        
        //delete all checked messages and hide them from the inbox view
        deleteMessage: function(){
            var messageIDs = "";
            var rows = J([]);
            J("#message-spinner").show();
            
            J("input[type=checkbox][id^=check-]:checked").each(function(){
                messageIDs += this.id.substr(6) + ",";
                if(!rows) rows = J("#message-row-"+this.id.substr(6));
                else rows = rows.add("#message-row-"+this.id.substr(6));
            });
            
            J.post("/message/delete", {ajax:true, messageIDs:messageIDs }, function(data){
                if(data.success == true){
                    J("input[type=checkbox]").attr("checked", false);
                    checked = false;
                    rows.hide();
                    J("#message-spinner").hide();
                }
                else {
                    J("#js-message").html("Error deleting messages");
                    J("#message-spinner").hide();
                    return false;
                }
            }, "json");
        },
    },
    
    message_view: {
        init: function(){
            if(zoteroData.read == 0){
                var inboxLink = J('#login-links > a[href="/message/inbox"]');
                inboxLink.html( inboxLink.html().replace(zoteroData.unreadCount, (zoteroData.unreadCount - 1)) );
            }
            
            //delete message
            J("#delete-button").click(function(){
                if(confirm("Delete Message?")){
                    J.post("/message/delete", {ajax:true, messageIDs: zoteroData.messageID }, function(data){
                        if(data.success == true){
                            window.location = "/message/inbox";
                        }
                    }, "json");
                }
            });
        },
    },
    
    message_compose: {
        init: function(){
            J("#contact-list").click(function(){
                J("#messageRecipient").val(J("#contact-list").val().join(", "));
            });
        },
    },
    
    index_index: {
        init: function(){
            flowplayer("intro-screencast", zoterojs.staticPath+"/library/flowplayer/flowplayer-3.1.1.swf");
        },
        
        /*
        init: function(){
            J("#intro-screencast-small").click(function(){
                J('#content').prepend("<div id='intro-screencast-lightbox-div'><a href='/static/videos/zotero_1_5_cast.flv' id='intro-screencast-lightbox'></a><a id='close-lightbox-link' href='#'>close</a></div>");
                zoterojs.index_index.player = flowplayer("intro-screencast-lightbox", zoterojs.staticPath+"/library/flowplayer/flowplayer-3.1.1.swf", 
                    {clip:
                        {autoPlay:true}
                    }
                );
                J('#close-lightbox-link').click(function(){
                    zoterojs.index_index.player.close();
                    J('#intro-screencast-lightbox-div').remove();
                });
                return false;
            });
            
        },
        */
    },
    
    search_index: {        
        init: function(){
            // Set up our tabs
            J("#tabs").tabs({
                show: function(event, ui) {
                    // configure global search box with the right helper text when the tab changes
        		    zoterojsSearchContext = ui.panel.id;
                    zoterojs.base.setupSearch();
                },
            });
            
            // re-run search when a new tab is clicked
            J("#tabs li a").click(function(e){
                var params  = zoterojs.search_index.parseHash(location.hash);
                if(!params.query == undefined || params.query == "") {return;}
                
                var newQueryType = J(this).attr("id").split("-")[1];
                var newHash = newQueryType + "/" + encodeURIComponent(params.query);
                location.hash = newHash;
                jQuery.historyLoad(newHash);
            });
            
            // set onlick event for submit buttons
    		J(".submit-button").click(function(){
    		    var queryType   = this.id.split("-")[0];
                var queryString = J("#"+queryType+"Query").val();
                if(!queryString || queryString == "") {return false;}
                
    		    // If this is a support search, see if we need to refine to forums or documentation
    		    if(queryType == "support"){
    		        queryType = J("input[name=supportRefinement]:checked").val(); 
    		    }
                
    		    var hash = queryType + "/" + encodeURIComponent(queryString);
                location.hash = hash;
                jQuery.historyLoad(hash);
    			return false;
    		});
    		
    		// Set up the history plugin
            jQuery.historyInit(zoterojs.search_index.pageload);
        },
        
        parseHash: function(hash){
            var params = {"type":"", "query":"", "page":""};
            
            // parse out search type
			queryTypeArray = /^(#(group|people|support|forums|documentation)\/?)/.exec(hash);
			if(!queryTypeArray || queryTypeArray[2] == undefined) { return params; }
			params.type = queryTypeArray[2];
			
			// parse out the page if present
			pageArray = /^#.+\/.+(\/p(\d{1,2}))$/.exec(hash);
			if(pageArray && pageArray[2] != undefined) {
			    params.page = pageArray[2];
			    // If we found a page, slice it off the hash to make query extraction easier
			    hash = hash.slice(0, hash.length - pageArray[1].length);
			}
			
			// parse out the query
            queryArray = /\/(.+)/.exec(hash);
			if(queryArray && queryArray[1] != undefined){
			    params.query = decodeURIComponent(queryArray[1]);
			}
			
			return params;
        },
        
        pageload: function(hash){
            // Clear any results
            zoterojs.search_index.clearResults();
            
            // In safari, the hash passed to this function by the history plugin is always whatever the hash was
            // when the page was first loaded. To get around this bug, we just refresh the hash by grabbing it from
            // the location object.
            hash = location.hash;
            
            // Parse the hash or if there is nothing in the hash, just bail now
            if(hash) {
                params = zoterojs.search_index.parseHash(hash);
            } else { return; }
			
			// Show the right tab and select the right support refinement if needed
		    switch (params.type) {
		        case "support": 
		        case "forums": 
		        case "documentation": 
		            J("#tabs").tabs('select','#support');
		            J("input[name=supportRefinement]").val([params.type]); 
		            break;
		        default: J("#tabs").tabs('select','#' + params.type); 
		    }
		    
		    //add pubLibOnly param if box is checked
		    if((params.type == "people") && (J("#peopleLibraryOnly:checked").length)){
		        params.pubLibOnly = 1;
		    }
		    
		    // give focus to the search box
		    J("#" + params.type + "Query").focus();
		    
			// Load the query into the right search field
			J("#search-form .textinput").val(params.query);
            
            // If it's a request for support results, pass to google search function
            if(params.type == "support" || params.type == "forums" || params.type == "documentation"){
                zoterojs.search_index.fetchGoogleResults(params);
            // otherwise, Make ajax request for results page
            } else if (params.query != "") {
                J("#search-spinner").show();
    			J.post(baseURL + "/search/searchresults", params, function(response){
    			    J("#search-spinner").hide();
                    J("#search-results").html(response.results);
                    J("#search-result-count").html("Found " + response.resultCount + " results");
                    J("#search-pagination").html(response.paginationControl);
    			}, "json");   
            }
        },
        
        fetchGoogleResults: function(params){
            // Create a new WebSearch object
            searcher = new google.search.WebSearch();
            
            // Restrict to the zotero custom search engine and specific refinments if present
            var refinement = null;
            switch (params.type) {
                case "documentation" : refinement = "Documentation"; break;
                case "forums"        : refinement = "Forums"; break;
            }
            searcher.setSiteRestriction("003601903170755827562:_vpllldihai", refinement);
            
            // Turn off safe search, set result set size, and disable HTML that we won't use
            searcher.setRestriction(google.search.Search.RESTRICT_SAFESEARCH, google.search.Search.SAFESEARCH_OFF);
            searcher.setResultSetSize(google.search.Search.LARGE_RESULTSET);
            searcher.setNoHtmlGeneration();
            
            // Setup a callback to handle the results
            // Callback arguments have to be an array, so make a quick array out of our params object
            paramsArray = [params.type, params.query, params.page];
            searcher.setSearchCompleteCallback(zoterojs, zoterojs.search_index.displayGoogleResults, paramsArray);
            
            // Execute our query
            searcher.clearResults();
            searcher.execute(params.query);
        },
        
        displayGoogleResults: function(type, query, page){
            zoterojs.search_index.clearResults();
            
            // Check if we have any results and displays them if we do
            if (searcher.results && searcher.results.length > 0) {
                for (var i in searcher.results) {
                    var r = searcher.results[i];
                    J("#search-results").append("                                                                 \
                        <li class='support-result'>                                                                    \
                          <div class='support-result-title'>                                                           \
                            <a href='"+r.url+"'>"+r.title+"</a>                                                        \
                          </div>                                                                                       \
                          <div class='support-result-content'>"+r.content+"</div>                                      \
                          <div class='support-result-url'>"+r.url.replace("http://", "")+"</div>                       \
                        </li>");
                }
                
                // Display the number of results found
                J("#search-result-count").html("Found " + searcher.cursor.estimatedResultCount + " results");
                
                // Add pagination links
                for (var i in searcher.cursor.pages){
                    var p = searcher.cursor.pages[i];
                    // If we're on the current page, output a number
                    if (i == searcher.cursor.currentPageIndex) {
                        J("#search-pagination").append(p.label + " | ");
                    } else {
                        J("#search-pagination").append("<a href='javascript:searcher.gotoPage("+i+")'>"+p.label+"</a> | ");
                    }
                }
            }
        },
        
        clearResults: function(){
            J("#search-results").empty();
            J("#search-result-count").empty();
            J("#search-pagination").empty();
            window.scrollBy(0, -500);
        },
    },
    
    index_start: {
        init: function() {
            // Fit the iFrame to the window
            zoterojs.index_start.sizeIframe();

            // Resize the iframe when the window is resized
            J(window).resize(zoterojs.index_start.sizeIframe);
            
            // Change the iframe src
            J(".start-select").click(function(){
                J("iframe").attr("src", J(this).attr("href"))
                return false;
            })
            
            J(".start-show-overlay").click(function(){
                J("#start-overlay").show();
                return false;
            });
            
            J(".start-hide-overlay").click(function(){
                J("#start-overlay").hide();
                return false;
            });
        },
        // Resize the height of the iframe to fill the page
        sizeIframe: function() {
            J("iframe").css("height", J(window).height() - 144);
        }
    },
    
    admin_dashboard: {
        init: function(){
            // Set up some helper text and make sure it doesn't get submitted
            var inputLabelText = "Filter log messages by keyword or log ID";
            J("#admin-query").inputLabel(inputLabelText, {color:"#999"});
            J("#admin-query-form").submit(function(){
                // This is covering for what I think is a bug in the inputLabel plugin
                if(J("#admin-query").val() == inputLabelText){
                    J("#admin-query").val("");
                }
            });
            
            // Slide down the message bodies when clicked
            J(".admin-message-title").click(function(){
                J(this).siblings(".admin-message-body").slideToggle(150);
            });
            
            // Put up a confirm when doing special admin stuff
            J("button").click(function(){
                if(!confirm("Are you sure?")){
                    return false;
                }
            });
            
            J("#admin-toggle-link").click(function(){
                J(".admin-message-body").slideToggle(true);
                return false;
            });
        },
    },
    
    admin_userstorage: {
        init: function(){
            J(".userstorage-section").hide();
            if(zoteroData.admin_userstorage_display == "user-storage-info-div"){
                J("#user-storage-info-div").show();
            }
            else if(zoteroData.admin_userstorage_display == "checkout-history-div"){
                J("#checkout-history-div").show();
            }
            J("#user-storage-button").click(function(){
                J(".userstorage-section").hide();
                J("#user-storage-info-div").show();
            });
            J("#checkout-history-button").click(function(){
                J(".userstorage-section").hide();
                J("#checkout-history-div").show();
            });
        },
    },
    
    utils: {
        printProperties: function(obj){
            for(att in obj){
                //console.log(obj[att]);
            }
        },
        
        slugify: function(name){
            var slug = J.trim(name);
            slug = slug.toLowerCase();
            slug = slug.replace( /[^a-z0-9 ._-]/g , "");
            slug = slug.replace( " ", "_", "g");
            
            return slug;
        },
                
    },

} // end zoterojs
