function capitalize(string) {
    return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase();
}

if (!Array.prototype.forEach)
{
  Array.prototype.forEach = function(fun /*, thisp*/)
  {
    var len = this.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
        fun.call(thisp, this[i], i, this);
    }
  };
}

if (!Array.prototype.some)
{
  Array.prototype.some = function(fun /*, thisp*/)
  {
    var i = 0,
        len = this.length >>> 0;

    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (; i < len; i++)
    {
      if (i in this &&
          fun.call(thisp, this[i], i, this))
        return true;
    }

    return false;
  };
}


if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length >>> 0;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}

function Publisher() {
  this.subscribers = [];
}

Publisher.prototype.deliver = function(data) {
  this.subscribers.forEach(
    function(fn) {
      fn(data);
    }
  );
  return this;
};

Function.prototype.subscribe = function(publisher) {
  var that = this;
  var alreadyExists = publisher.subscribers.some(
    function(el) {
      if ( el === that ) {
        return;
      }
    }
  );
  if ( !alreadyExists ) {
    publisher.subscribers.push(this);
  }
  return this;
};

Function.prototype.unsubscribe = function(publisher) {
  var that = this;
  publisher.subscribers = publisher.subscribers.filter(
    function(el) {
      if ( el !== that ) {
        return el;
      }
    }
  );
  return this;
};
if(typeof TmpVars == "undefined"){
    TmpVars = {};
}
Constants = {
    generalDocumentCategories : ["All Titles A to Z","Featured"],
    startingTab : false,
    browserIe : false,
    browserIeSix : false,
    animateSlideshow : true,
    tabAnimationDuration : 250,
    schedulerInterval : 100,
    flashDialogDuration : 10000,
    addToCartUrl : "http://store.coverleaf.com/softslate/CartAdd.do", //this is a default value that's overridden in the footer.tt file
    addToCartErrorMsg : "<div><p>We&rsquo;re sorry, there was a problem adding this item to your cart.</p><p>Please try again later</p></div>",
    clippingRemoveFromGroupDialog : "<div><p>Are you sure you would like to remove this clipping from the #{folder_name} folder</p></div>",
    clippingRemoveFromGroupTitle : "Remove clipping from group",
    addcompLoginErrorHeader : "Login Unsuccessful",
    addcompLoginErrorMsg : '<div><p>We&rsquo;re sorry, there was a problem <br>with your login request.</p><p>Please check your <br>username and password and try again.</p><a id="login_error_forgot" title="Forgot your password?" onclick="Coverleaf.Account.View.hideSignInForm();" href="#" rel="Forgot_Password" class="select_tab">Forgot your password?</a></div>',
    addcompRegErrorHeader : "Registration Unsuccessful",
    addcompRegErrorMsg : "<p>We&rsquo;re sorry, there was a problem <br>with your registration request.</p><br><p>Please try again later.</p>",
    addcompUserMsg : "Logged in as ",
    ajaxLoader : "<img src=\"/images/ajax-loader.gif\" border=\"0\" alt=\"loading...\" />",
    ajaxLoaderDark : '<img class="busy" src="/images/busy_dark.gif" alt="working..." />',
    dialogShowEffect : 'slide',
    dialogHideEffect : 'clip',
    requiredIndicator : "<em>*</em>",
    usernameCookie : "username",
    memberidCookie : "memberid",
    jSessionIdCookie : "JSESSIONID",
    sscscTokenCookie : "sscsctoken",
    checkoutPositionCookie : "checkout_wrapper_active_section",
    itemCountCookie : "item_count",
    searchDefaultValue : "search",
    tabNameSearch : "Search",
    tabNameMystuff : "My_Stuff",
    flashDuplicateClipping : 'That item is already in your My Stuff collection',
    flashAddItemSuccess : 'The item has been successfully added to your My Stuff collection',
    folderTitleTemplate : "Filter Clippings by ",
    clippingDeleteTitle : 'Delete Clipping',
    folderDeleteTitle : 'Delete Folder',
    mystuffItemTypes : ["Subscription","Document","Clipping"],
    folderEditTitle : 'Edit Folder Name',
    detailPageBehaviorPad : $.browser.msie === true ? 1000 : 500,
    tabNameMap : {
        "addcompanion" : "Addcompanion",
        "mystuff" : "My_Stuff",
        "search" : "Search",
        "userlibrary" : "My_Stuff",
        "mystuff" : "My_Stuff",
        "Mystuff" : "My_Stuff",
        "My_Stuff" : "My_Stuff",
        "memberlibrary" : "My_Stuff",
        "memberLibrary" : "My_Stuff",
        "faq" : "FAQ",
        "contact" : "Contact_Us",
        "sitemap" : "Site_Map",
        "forgotpassword" : "Forgot_Password"
    }
};

Coverleaf = (function(){
    var active_member = null;
    var variables = {};
    var primary_tabs = [];
    var primary_tab_ids = [];
    var tab_options = {
        ajaxOptions: { success: function(){}},
        cache: true,
        fx: { opacity: 'toggle', duration: Constants.tabAnimationDuration },
        select: select_tab,
        selected: get_starting_tab(),
        show: show_tab
    };

    function select_tab(event,ui){
        Coverleaf.Search.View.hideOpenOptionsMenu();
        Coverleaf.Account.View.hideSignInForm();
        Coverleaf.current_tab = ui;
    }

    function show_tab(event,ui){
        //change url hash if necessary -> history support
        if(document.location.hash.indexOf(ui.tab.hash)==-1){
            document.location.hash = ui.tab.hash;
            Coverleaf.updateHistory(location.hash);
        }

        Coverleaf.accordionize(ui.panel);
        Coverleaf.tabify(ui.panel);
        initialize_tab_class(ui.tab.id);
    }

    function parse_primary_tabs(){
        primary_tabs = [];
        primary_tab_ids = [];
        var tab_anchors = $("#nav_primary ul a");
        for(var i=0;i<tab_anchors.length;i++){
            primary_tabs.push({
                elem: $(tab_anchors[i]),
                href: $(tab_anchors[i]).attr("href"),
                url: $(tab_anchors[i]).attr("url"),
                title: $(tab_anchors[i]).attr("title")
            });
            primary_tab_ids.push($(tab_anchors[i]).attr("id").replace("tab_",""));
        }
    }

    function get_nav_primary_tab_index(opts){
        var options = opts || {};
        var tab_index = false;

        if(options.hasOwnProperty("url")){
            Coverleaf.tabs[i].data('tabs').anchors.each(function(n,i){
                if(n.data('load.tabs') == options.url){
                    tab_index = i;
                }
            });
        }else if(options.hasOwnProperty("name")){
            var tab_anchor = $("#nav_primary a[href*='#"+options.name+"']");
            if(tab_anchor.length){
                tab_index = $("#nav_primary a").index(tab_anchor) || 0;
            }
        }
        return tab_index;
    }

    function hash_matches_tabs(){
        //try to find the starting tab based on the hash value in the url
        //we try to pass any params tacked onto the hash through to the href
        var tab_match = new RegExp(primary_tab_ids.join("|"));
        var hash_matches = location.hash.match(tab_match);
        var matched_tab_name = false;
        if(hash_matches){
            matched_tab_name = hash_matches[0];
            var matched_tab = get_nav_primary_tab_index({name:matched_tab_name});
            if(matched_tab!==false){
                var tab_link = $("#nav_primary_tabs a:eq("+matched_tab+")");
                var tab_href = tab_link.attr("href");
                var new_href = tab_href.replace(/#.*/,"") + location.hash.replace("#"+matched_tab_name,"?") + "&autoload=true";
                if(tab_href.indexOf("Home")==-1){
                    tab_link.attr("href",new_href);
                }
            }
        }else{
            var lower_tab_match = new RegExp(primary_tab_ids.join("|").toLowerCase());
            var lower_hash_matches = location.hash.match(lower_tab_match);
            if(lower_hash_matches){
                matched_tab_name = capitalize(lower_hash_matches[0]);
                var matched_tab = get_nav_primary_tab_index({name:matched_tab_name});
                if(matched_tab!==false){
                    var tab_link = $("#nav_primary_tabs a:eq("+matched_tab+")");
                    var tab_href = tab_link.attr("href");
                    var new_href = tab_href.replace(/#.*/,"") + location.hash.replace("#"+lower_hash_matches[0],"?") + "&autoload=true";
                    if(tab_href.indexOf("Home")==-1){
                        tab_link.attr("href",new_href);
                    }
                }
            }
        }
        return matched_tab;
    }

    function hash_matches_alias(){
        var hash_pieces = location.hash.match(/#?([^&]+)&?/);
        var matched_tab = false;
        if(hash_pieces && hash_pieces.length > 1){
            if(Constants.tabNameMap.hasOwnProperty(hash_pieces[1])){
                var matched_tab_name = Constants.tabNameMap[hash_pieces[1]];
                matched_tab = get_nav_primary_tab_index({name:matched_tab_name});
                if(matched_tab!==false){
                    var tab_link = $("#nav_primary_tabs a:eq("+matched_tab+")");
                    var tab_href = tab_link.attr("href");
                    var new_href = tab_href.replace(/#.*/,"") + location.hash.replace("#"+matched_tab_name,"?") + "&autoload=true";
                    if(tab_href.indexOf("Home")==-1){
                        tab_link.attr("href",new_href);
                    }
                }
            }
        }
        return matched_tab;
    }

    function get_starting_tab(){
        if(TmpVars.hasOwnProperty("startingTab") && TmpVars.startingTab !== false){
            return get_nav_primary_tab_index(TmpVars.startingTab);
        }else{
            parse_primary_tabs();
            var hash = location.hash.replace("#","/");
            var pathname = location.pathname;
            var query_string = location.search;
            var starting_tab = 0;
            var urls = [];

            //see if we have a hard-coded match in our hash lookup (fastest)
            var hash_alias_match = hash_matches_alias();
            if(hash_alias_match!==false){
                return hash_alias_match;
            }

            //see if the hash matches one of the tab hrefs in nav_primary
            var hash_match = hash_matches_tabs();
            if(hash_match!==false){
                return hash_match;
            }

            //finally test the hash values or the location.pathname against the tab href's
            for(var i=0;i<primary_tabs.length;i++){
                //here we're matching against the href attribute on the tab's anchor tag
                if(primary_tabs[i].href.indexOf("#") != 0){
                    var query_string_start = primary_tabs[i].href.indexOf("?") != -1 ? primary_tabs[i].href.indexOf("?") : primary_tabs[i].href.length;
                    var test_url = primary_tabs[i].href.substring(0,query_string_start);
                }else{
                    //here we're matching against the custom url attribute on the tab's anchor tag
                    if(primary_tabs[i].url){
                        var query_string_start = primary_tabs[i].url.indexOf("?") != -1 ? primary_tabs[i].url.indexOf("?") : primary_tabs[i].url.length;
                        var test_url = primary_tabs[i].url.substring(0,query_string_start);
                    }
                }
                if(test_url){
                    var url_regexp = new RegExp("^\\"+test_url);
                    var query_string_regexp = /(document_id|category_id)=([^&]+)/;
                    if(url_regexp.test(hash) || url_regexp.test(pathname)){
                        var item_matches = query_string.match(query_string_regexp);
                        if(item_matches && item_matches.length == 3){
                            var item_type = capitalize(item_matches[1].replace("_id",""));
                            var item_id = item_matches[2];
                            location.hash = "#Home&"+item_type+"="+item_id;
                        }
                        starting_tab = i;
                        break;
                    }
                }
            }
            return starting_tab;
        }
    }

    function preload_tabs(){
        var t_len = Coverleaf.tabs.length;
        for(var i=0;i<t_len;i++){
            var x = 0;
            Coverleaf.tabs[i].data('tabs').anchors.each(function(){
                var that = $(this);
                var url = that.attr("url");
                var rel = that.attr("rel");
                var href = that.data('load.tabs') || "";
                if(rel=="preload" && href != "" && href.indexOf("#")!=0 && typeof $.data(that[0],'cache.tabs') != "boolean"){
                    var panel = $(Coverleaf.tabs[i].data('tabs').panels[x]);
                    if(panel.is(":visible")===false){
                        load_tab(href,that[0],panel);
                    }
                }else if (typeof url != "undefined"){
                    Coverleaf.tabs[i].tabs('url',x,that.attr("url"));
                    $.data(that[0],'cache.tabs',true);
                }
                x = x + 1;
            });
        }
    }

    function load_tab(href,anchor,panel,fn_callback){
        $.data(anchor,'cache.tabs',true);
        var panels = $("#tab_panels");
        var i_left = panels.width()/2 - 65;
        var i_top = panels.height()/2 - 50;
        var loading_img = $(Constants.ajaxLoader).css({top:i_top+"px",left:i_left+"px",position:"absolute"});
        panel.html(loading_img);

        var tab_controller = anchor.id.replace("tab_","");
        panel.load(href,{},function(){
            if(typeof fn_callback != "undefined"){
                fn_callback();
            }
            if(Coverleaf.hasOwnProperty(tab_controller) && typeof Coverleaf[tab_controller]["init"]=="function" && typeof Coverleaf[tab_controller]["reset"]=="function"){
                Coverleaf[tab_controller]["reset"]();
                Coverleaf[tab_controller]["init"]();
            }
        });
    }

    function initialize_tab_class(anchor_id){
        var tab_controller = anchor_id.replace("tab_","");
        if(Coverleaf.hasOwnProperty(tab_controller) && typeof Coverleaf[tab_controller]["init"]=="function"){
            Coverleaf[tab_controller]["init"]();
        }
    }

    function get_cookied_member(){
        var member_id_cookie = CookieManager.get(Constants.memberidCookie);
        var username_cookie = CookieManager.get(Constants.usernameCookie);
        if(member_id_cookie){
            Coverleaf.setActiveMember({
                member_id: member_id_cookie,
                username: username_cookie
            });
            Coverleaf.Account.View.updateMemberData();
            return true;
        }else{
            return false;
        }
    }

    function init_tab_selectors(){
        $("a.select_tab").live('click',function(){
            Coverleaf.tabs[0].tabs('select',$(this).attr("rel"));
            return false;
        })
    }

    /* TODO: need to expand this function into something more generic */
    function init_tab_reload_links(){
        $("a.reload_tab").live('click',function(){
            var tab_name = $(this).attr("rel");
            var tab_url = $(this).attr("href");
            var tab_anchor = $("a[href$='"+tab_name+"']",Coverleaf.primaryNav);
            var tab_index = $("#nav_primary a").index(tab_anchor);
            var anchors = Coverleaf.tabs[0].data('tabs').anchors;
            var anchor_url = $(anchors[tab_index]).data('load.tabs').replace(/\?.*/,"");
            Coverleaf.tabs[0].tabs('url',tab_index,tab_url).tabs('select',tab_name);
            return false;
        })
    }

    return {
        primaryNav : {},
        dialogs : {},
        popups : {},
        tabs : [],
        current_tab : null,
        redirect : false,
        hashdict : {},
        qsdict : {},

        init : function(){
            var preload_interval;
            var that = this;
            var cookied_member = get_cookied_member();

            this.primaryNav = $("#nav_primary");

            Constants.browserIe = $.browser.msie;
            if (navigator.userAgent.toLowerCase().indexOf("msie 6") != -1){
                Constants.browserIeSix = true;
            }
            Coverleaf.tabs.push(this.primaryNav.tabs(tab_options));
            Coverleaf.Account.Controller.init();
            Coverleaf.ReportingManager.init();
            Coverleaf.processLocationString();
            that.roundCorners();
            preload_interval = setInterval(function(){
                if(that.primaryNav.hasClass("ui-tabs")){
                    clearInterval(preload_interval);
                    preload_tabs();
                }
            },100);
            init_tab_selectors();
            init_tab_reload_links();
            setTimeout("$.ajaxHistory.initialize()",2000);
        },

        getVariable : function(svarname) {
            if (variables[svarname]){
                return variables[svarname]
            }
            return;
        },

        setVariable : function(svarname,value) {
            if(arguments.length == 2){
                variables[svarname] = value;
            }
        },

        removeVariable : function(svarname){
            if(variables[svarname]){
                delete variables[svarname];
            }
        },

        updateHistory : function(hash){
            if(Constants.browserIe){
                setTimeout(function(){$.ajaxHistory.update(hash);},500);
            }
        },

        processLocationString : function(){
            // Read from the query string
            var qs = location.search.substring(1);
            var qsdict = this.strToObj(qs);
            // Read from the hash path
            var hash = location.hash.substring(1);
            this.hashdict = this.strToObj(hash);
            this.redirect = false;
            // Move any history variables to the hash dict
            for (var key in qsdict) {
                if (qsdict[key] != null && this.hashdict[key] == null) {
                    this.redirect = true;
                    this.hashdict[key] = qsdict[key];
                    qsdict[key] = null;
                }
            }
            return this.hashdict;
        },

        setActiveMember : function(member_obj){
            active_member = member_obj;
        },

        getActiveMember : function(){
            return active_member;
        },

        markParentAsSelected : function(parent_selector){
            var selector = typeof parent_selector == "undefined" ? "li" : parent_selector;
            $(this).closest("div").find(".selected").removeClass("selected");
            $(this).closest(selector).addClass("selected");
        },

        reloadTab : function(tab_name,fn_callback){
            var tab = Coverleaf.tabs[0].data('tabs').anchors.each(function(x){
                var href = $(this).data('load.tabs') || "";
                if($(this).attr("id") == "tab_"+tab_name){
                    var panel = $(Coverleaf.tabs[0].data('tabs').panels[x]);
                    load_tab(href,$(this)[0],panel,fn_callback);
                }
            });
        },

        getBlogContent : function(){
            var blog = $.ajax({
                type: "GET",
                url: "/blog",
                success: function(blog_html) {
                    var blog_div = $("#blog");
                    blog_div.show();
                    $("#blog_entries",blog_div).html(blog_html);
                    Coverleaf.accordionize(blog_div);
                },
                error: function(){
                    $("#blog").remove();
                }
            });
        },

        schedule : function(functions, context){
            setTimeout(function(){
                var process = functions.shift();
                process.call(context);

                if (functions.length > 0){
                    setTimeout(arguments.callee, Constants.schedulerInterval);
                }
            }, Constants.schedulerInterval);
        },

        tabify : function(dom_element){
            var tab_me = $("ul.tabify",dom_element);
            if(tab_me.length){
                var subtab_options = $.extend({}, tab_options, {selected:0});
                tab_me.parent().tabs(subtab_options);
                tab_me.removeClass("tabify");
            }
        },

        tabNameMatch : function(name){
            if(Constants.tabNameMap.hasOwnProperty(name)){
                return Constants.tabNameMap[name];
            }
        },

        accordionize : function(dom_element){
            var accordionize_me = $("div.accordionize",dom_element);
            if(accordionize_me.length){
                accordionize_me.each(function(){
                    if($(this).is(":visible")){
                        accordionize_me.accordion();
                        accordionize_me.removeClass("accordionize");
                    }
                });
            }
        },

        roundCorners : function(context){
            var corner_class = "ui-corner";
            var class_mapping = {
              "ui-corner": "8px",
              "ui-corner-tl": "8px tl",
              "ui-corner-tr": "8px tr",
              "ui-corner-bl": "8px bl",
              "ui-corner-br": "8px br",
              "ui-corner-top": "8px top",
              "ui-corner-bottom": "8px bottom",
              "ui-corner-right": "8px right",
              "ui-corner-left": "8px left",
              "ui-corner-tl-4": "4px tl",
              "ui-corner-tr-4": "4px tr",
              "ui-corner-bl-4": "4px bl",
              "ui-corner-br-4": "4px br",
              "ui-corner-top-4": "4px top",
              "ui-corner-bottom-4": "4px bottom",
              "ui-corner-right-4": "4px right",
              "ui-corner-left-4": "4px left",
              "ui-corner-all-4": "4px",
              "ui-corner-all-5" : "5px"
            };

            if($.browser.msie){
                $("[class*='" + corner_class + "']",context).each(do_round_corners);
            }

            function do_round_corners(){
                var classes = $(this).attr("class");
                var start = classes.indexOf(corner_class);
                var end = classes.indexOf(" ",start) != -1 ? classes.indexOf(" ",start) : classes.length;
                var corner_type = classes.substr(start,(end-start));
                $(this).corner(class_mapping[corner_type] + " no-mozilla");
            }
        },

        processTemplate : function(template,properties,data){
          var retval = new String();
          var t = new Template(template);

          if(typeof data != "undefined"){
              var property_map = {};
              // if we're evaluating a template several times
              if(data.length){
                  $.each(data,function() {
                    var that = this;
                    $.each(properties,function() {
                        property_map[this] = that[this];
                    });
                    retval = retval + t.evaluate(property_map);
                  });
              // we're only evaluating the template once
              }else{
                  $.each(properties,function() {
                      property_map[this] = data[this];
                  });
                  retval = t.evaluate(property_map);
              }
          }else{
              retval = t.evaluate(properties);
          }
          return retval;
        },

        processListTemplates : function(list_template,item_template,list_data,document_data){
            var list_item_html = "";
            var list_html = "";
            var that = this;
            if(typeof list_data != "undefined "){
                $.each(list_data,function(k,v){
                    list_item_html = list_item_html + that.processTemplate(item_template,v);
                });
                if(typeof document_data != "undefined"){
                    group_template_data = document_data;
                    group_template_data.list_items = list_item_html;
                }else{
                    group_template_data = {list_items:list_item_html};
                }
                list_html = that.processTemplate(list_template,group_template_data);
            }
            return list_html;
        },

        objectFilter : function(data,key,val,inverse){
            var reverse = inverse || false;
            var retval = $.grep(data,function(a){
                    return reverse ? a[key] != val : a[key]==val
                });
                return reverse ? retval : retval[0];
        },

        arrayFilter : function(data,val,inverse){
            var reverse = inverse || false;
            var retval = $.grep(data,function(a){
                    return reverse ? a != val : a==val
                })
                return reverse ? retval : retval[0];
        },
        ucFirst : function( str ) {
            str += '';
            var f = str.charAt(0).toUpperCase();
            return f + str.substr(1);
        },
            height: function(element){
                 return element.height() || parseInt(element.css('height'));
            },
            width: function(element){
                 return element.width() || parseInt(element.css('width'));
            },
            error: function(desc,page,line,chr){
                Console.error(desc + " in " + page + " on line " + line);
                return true;
            },
            trueTypeOf: function(v) {
            if (typeof(v) == "object") {
                if (v === null) return "null";
                if (v.constructor == (new Array).constructor) return "array";
                if (v.constructor == (new Date).constructor) return "date";
                if (v.constructor == (new RegExp).constructor) return "regex";
                if (v.constructor == (new Boolean).constructor) return "boolean";
                return "object";
            }
            return typeof(v);
        },
        strToObj : function(str) {
            var rv = new Object();
            str = str.replace(/\+/g,' ');
            var args = str.split('&')

            for (var i = 0; i < args.length; ++i) {
                if (args[i] == "") continue;
                var pair = args[i].split('=');
                var next = i+1 < args.length ? args[i+1] : '';
                var name = unescape(pair[0]);
                var value = unescape(pair[1]);
                if (next && next.indexOf('=') < 0) {
                    value += '&' + unescape(next);
                    i++;
                }

                if (pair.length >= 2){
                    rv[name] = value;
                }
            }

            return rv;
        },
        flashMessage : function(msg) {
            var message = msg || this.getVariable('flash_message');
            if(message){
                var message_html = "<div class=\"flash_message\">"+message+"</div>";
                $(message_html).appendTo("body").dialog({
                    buttons: {
                        "Close": function() {
                            $(this).dialog("close");
                        }
                    },
                    resizable: false,
                    title: "Please wait...",
                    show: Constants.dialogShowEffect,
                    hide: Constants.dialogHideEffect,
                    open: function(){
                        var that = $(this);
                        setTimeout(function(){
                            that.dialog('close');
                        },5000);
                    },
                    close: function(){
                        $(this).dialog('destroy').remove();
                    }
                });
                Coverleaf.removeVariable('flash_message');
            }
        },
        buildPropertyString : function(oDefaults) {
            var popup_properties = '';

            for (prop in oDefaults) {
                if (popup_properties.length > 0) { popup_properties += ', '; }
                popup_properties += prop + '=' + oDefaults[prop];
            }

            return popup_properties;
        },
        isRightClick : function(e){
            if( typeof e.button != "undefined" && e.button >= 2 ){
                return true;
            }
            return false;
        }
    }
})();

Coverleaf.Account = {
    initialized : false,
    init: function(){
        if(Coverleaf.Account.initialized===false){
            Coverleaf.Account.Model.init();
            Coverleaf.Account.View.init();
            Coverleaf.Account.Controller.init();
            Coverleaf.Account.initialized = true;
        }
    },
    onSignIn : new Publisher,
    onSignOut : new Publisher
};

Coverleaf.Account.Model = (function(){
    return {

        init : function(){},

        getSignInForm : function(){
            return $("#navbar_signin_form",Coverleaf.primaryNav);
        },

        getSignInFormDiv : function(){
            return $("#navbar_signin_wrapper",Coverleaf.primaryNav);
        },

        getSignInLinks : function(){
            return $("a.sign_in");
        },

        getSignOutLinks : function(){
            return $("a.sign_out");
        },

        getMemberLinks : function(scope){
            return $(".member",scope);
        },

        getNonMemberLinks : function(scope){
            return $(".non_member",scope);
        },

        getAccountMenu : function(scope){
            return $("#account_menu",scope);
        },

        signinCallback : function(xml,textStatus){
            var elem = xml.documentElement;
            var new_username = CookieManager.get(Constants.usernameCookie);
            if (elem) {
                var new_member_id = elem.getAttribute('member_id');
                if (new_member_id) {
                    Coverleaf.setActiveMember({
                        member_id: new_member_id,
                        username: new_username
                    });
                    Coverleaf.Account.onSignIn.deliver();
                }
            }
        },

        doSignOut : function(){
            Coverleaf.Account.Controller.clearShoppingCart();
            Coverleaf.setActiveMember(null);
            Coverleaf.Account.onSignOut.deliver();
            CommunicationManager.resetForm($('form[name="signin"]',Coverleaf.primaryNav));
            CookieManager.remove(Constants.memberidCookie);
            CookieManager.remove(Constants.usernameCookie);
            CookieManager.remove(Constants.jSessionIdCookie);
            CookieManager.remove(Constants.sscscTokenCookie);
            CookieManager.remove(Constants.checkoutPositionCookie);
            CookieManager.remove(Constants.itemCountCookie);
        }

    }
})();

Coverleaf.Account.View = (function(){
    var m = Coverleaf.Account.Model;
    return {
        init : function(){
            this.hideSignInForm.subscribe(Coverleaf.Account.onSignIn);
            this.updateMemberData.subscribe(Coverleaf.Account.onSignIn);
            this.updateMemberData.subscribe(Coverleaf.Account.onSignOut);
        },
        hideSignInForm : function(){
           m.getSignInFormDiv().slideUp();
        },
        showSignInForm : function(){
            Coverleaf.Search.View.hideOpenOptionsMenu();
            m.getSignInFormDiv().slideDown();
        },
        updateMemberData : function(){
            var member = Coverleaf.getActiveMember();
            if(member && member !== false){
                $(".username").text(member.username);
                $(".member").removeClass("never_show");
                $(".non_member").addClass("never_show");
            }else{
                $(".username").text("Your Account");
                $(".member").addClass("never_show");
                $(".non_member").removeClass("never_show");
            }
        }
    }
})();

Coverleaf.Account.Controller = (function(){
    var m = Coverleaf.Account.Model;
    var v = Coverleaf.Account.View;


    function handle_sign_in_click(){
        if(m.getSignInFormDiv().is(":visible")){
            v.hideSignInForm();
        }else{
            $("html").smoothScroll();
            v.showSignInForm();
        }
        return false;
    }

    function handle_sign_out_click(){
        m.doSignOut();
        return false;
    }

    return {
        init : function(){
            m.init();
            v.init();

            m.getSignInLinks().live('click',handle_sign_in_click);
            m.getSignOutLinks().live('click',handle_sign_out_click);
            CommunicationManager.prepareForm("navbar_signin","/signin",Coverleaf.Account.Model.signinCallback)
        },

        clearShoppingCart : function(callback){
            if(Constants.hasOwnProperty('ecommerceUrl')){
                $("body").append('<iframe id="clear_cart_iframe" name="clear_cart_iframe" src="'+Constants.ecommerceUrl+'/CartClear.do" frameborder="0" width="0" height="0" scrolling="no"></iframe>');
                setTimeout(function(){
                    $("#clear_cart_iframe").remove();
                    Coverleaf.Home.View.setMiniCartHtml();
                },2000);
            }
        }
    }
})();

Coverleaf.Addcompanion = (function(){
    var addcompanion_wrapper;

    function initialize_slinky_form(){
        if(Coverleaf.getActiveMember()){
            $("#signin_passwd",addcompanion_wrapper).focus();
        }else{
            $("#username",addcompanion_wrapper).focus();
        }
        addcompanion_wrapper.slinky({
            error_position : "absolute",
            finishCallback : function(){
                var section = $(this);
                $("#addcompanion_form",section).trigger('submit');
            },
            stepCallbacks : {
                'addcompanion_register_signin' : function(button_id){
                    var section = $(this);
                    var retval = -1;
                    var member = Coverleaf.getActiveMember();
                    if(typeof button_id == "undefined"){
                        return false;
                    }else if(!section.data("ajax_request")){

                        $(Constants.ajaxLoaderDark).appendTo($("#"+button_id));

                        /* MAIN LOGIC SECTION */
                        switch(button_id){
                            case "loginFormSubmit":
                                var new_username = document.signin_form.username.value;
                                var new_passwd = document.signin_form.passwd.value;
                                CookieManager.remove(Constants.usernameCookie);
                                section.data("ajax_request", CommunicationManager.post(
                                    '/signin',
                                    "username=" + new_username + "&passwd=" + new_passwd,
                                    function(data,textStatus){
                                        var new_username = CookieManager.get(Constants.usernameCookie);
                                        var new_member_id = CookieManager.get(Constants.memberidCookie);
                                        section.removeData("ajax_request");
                                        $(".busy",section).remove();
                                        if(new_username != false){
                                            change_section_header(new_username);
                                            $("#addcompanion_email_address").val(new_username);
                                            $("#addcompanion_password").val(new_passwd);
                                            Coverleaf.setActiveMember({
                                                member_id: new_member_id,
                                                username: new_username
                                            });
                                            Coverleaf.Account.onSignIn.deliver();
                                            retval = 1;
                                        }else{
                                            $(Constants.addcompLoginErrorMsg).dialog({
                                                buttons: { "Close": function() { $(this).dialog("close"); } },
                                                resizable: false,
                                                title: Constants.addcompLoginErrorHeader,
                                                show: Constants.dialogShowEffect,
                                                hide: Constants.dialogHideEffect,
                                                open: function(){
                                                    var that = $(this);
                                                    $("#login_error_forgot").click(function(){that.dialog('close')});
                                                    setTimeout(function(){
                                                        that.dialog('close');
                                                    },10000);
                                                },
                                                close: function(){
                                                    $(this).dialog('destroy').remove();
                                                }
                                            });
                                            retval = 0;
                                        }
                                    }
                                ));
                                break;
                            case "registerFormSubmit":
                                var new_username = $("#registration_email_address",Coverleaf.Registration.panel).val();
                                var new_passwd = $("#registration_passwd",Coverleaf.Registration.panel).val();
                                var new_conf_passwd = $("#registration_passwd2",Coverleaf.Registration.panel).val();
                                var op = $("#registration_op",Coverleaf.Registration.panel).val();
                                var optInCheckbox = $("#registration_terms_opt_in",section);
                                var opt_in = optInCheckbox.is(":checked") ? optInCheckbox.val() : '';
                                CookieManager.remove(Constants.usernameCookie);
                                section.data("ajax_request", CommunicationManager.post(
                                    '/registration',
                                    "email_address=" + new_username + "&passwd=" + new_passwd + "&passwd2="+new_conf_passwd + "&op=" + op + "&terms_opt_in=" + opt_in,
                                    function(data,textStatus){
                                        var elem = data.documentElement;
                                        section.removeData("ajax_request");
                                        $(".busy",section).remove();
                                        if (elem) {
                                            var new_member_id = elem.getAttribute('member_id');
                                            if(new_member_id){
                                                var new_username = $("#registration_email_address",section).val();
                                                change_section_header(new_username);
                                                $("#addcompanion_email_address").val(new_username);
                                                $("#addcompanion_password").val(new_passwd);
                                                Coverleaf.setActiveMember({
                                                    member_id: new_member_id,
                                                    username: new_username
                                                });
                                                Coverleaf.Account.onSignIn.deliver();
                                                retval = 1;
                                            }else if(elem.getAttribute('error_msg')){
                                                var msg = elem.getAttribute('error_msg');
                                                $("#registration_other_form_errormsg_" + msg).clone().dialog({
                                                    buttons: { "Close": function() { $(this).dialog("close"); } },
                                                    resizable: false,
                                                    title: Constants.addcompRegErrorHeader,
                                                    show: Constants.dialogShowEffect,
                                                    hide: Constants.dialogHideEffect,
                                                    open: function(){
                                                        var that = $(this);
                                                        setTimeout(function(){
                                                            that.dialog('close');
                                                        },10000);
                                                    },
                                                    close: function(){
                                                        $(this).dialog('destroy').remove();
                                                    }
                                                });
                                                retval = 0;
                                            }
                                        }else{
                                            $(Constants.addcompRegErrorMsg).dialog({
                                                buttons: { "Close": function() { $(this).dialog("close"); } },
                                                resizable: false,
                                                title: Constants.addcompRegErrorHeader,
                                                show: Constants.dialogShowEffect,
                                                hide: Constants.dialogHideEffect,
                                                open: function(){
                                                    var that = $(this);
                                                    setTimeout(function(){
                                                        that.dialog('close');
                                                    },10000);
                                                },
                                                close: function(){
                                                    $(this).dialog('destroy').remove();
                                                }
                                            });

                                            retval = 0;
                                        }
                                    },
                                    'xml'
                                ));
                                break;
                        }

                        var authInterval = setInterval(function(){
                            if(retval >= 0){
                                clearInterval(authInterval);
                                section.data("step_callback_retval",!!retval);
                                $(".busy","#"+button_id).remove();
                            }
                        },50);
                        /* END MAIN LOGIC SECTION */

                        function change_section_header(username){
                            var change_link = $("h2 .change_section",section.parent());
                            var header = $("h2 span",section.parent())
                            header.data("previous_content",header.html()).html(Constants.addcompUserMsg + username).append(change_link);
                        }
                    }

                },
                'addcompanion_form_section' : function(e){
                    if($(this).data('checked')===true){
                        $(this).data("step_callback_retval",true);
                    }else{
                        $(this).data("step_callback_retval",false);
                    }
                }
            },
            afterCreate : function(){
                this.sections.each(function(i){
                    var section_number = i+=1;
                    $(this).data("header").prepend(section_number+"&nbsp;|&nbsp;");
                });
                $("#registration_other_form,#signin_form").unbind().bind('submit',function(){
                    $(".next",$(this)).trigger("click");
                    return false;
                });
            }
        });
    }

    /**
     * Sets an input field values for a form to make the field required
     * or not required.  Sets/removes class "required" and adds/removes
     * asterik UI indicator to the label.
     *
     * @param field_id HTML id of the field to set
     * @param context the form in which the field resides
     * @param turn_on boolean true = set the field to required
     */
    function set_required_field(field_id, context, turn_on) {
        var field_input = $("#"+field_id, context);
        var field_label = $('label[for="'+field_id+'"]', context);
        var label_html = field_label.html();

        if (turn_on) {
            field_input.addClass("required");
            field_label.addClass("required");
            if (label_html.indexOf(Constants.requiredIndicator) == -1) {
                label_html = Constants.requiredIndicator + label_html;
            }
        } else {
            field_input.removeClass("required");
            field_label.removeClass("required");
            label_html = label_html.replace(Constants.requiredIndicator, "");
        }
        field_label.html(label_html);
    }

    /**
     * Checks the country for US or Canada then displays/hides the Account Name
     * field appropriately (hide for US/CA) and marks fields as required or not.
     *
     * @param country the country code to check
     * @param country_id value to pass to updatestateinput
     * @param state_id value to pass to updatestateinput
     * @param classtag value to pass to updatestateinput
     */
    function check_for_non_us_country(country, country_id, state_id, classtag) {
        var us_ca = (country == "US" || country == "CA");

        set_required_field("addcompanion_matchcode", Coverleaf.Addcompanion.panel, !(us_ca));
        set_required_field("state", Coverleaf.Addcompanion.panel, us_ca);
        set_required_field("zip", Coverleaf.Addcompanion.panel, us_ca);

        var matchcode_wrapper = $("#addcompanion_matchcode_wrapper",Coverleaf.Addcompanion.panel);
        if (!(us_ca)) {
            matchcode_wrapper.slideDown();
        } else if(matchcode_wrapper.is(":visible")) {
            matchcode_wrapper.slideUp();
        }
        updatestateinput(country_id, state_id, classtag);
    }

    return {
        initialized: false,
        preventDefaultBehaviors: false,
        init : function() {
            if(this.preventDefaultBehaviors === false){
                this.panel = $("#panel_Addcompanion");
                addcompanion_wrapper = $("#addcompanion_form_wrapper");
                initialize_slinky_form();
                CommunicationManager.prepareForm(
                    "addcompanion_form",
                    "/addcompanion",
                    Coverleaf.Addcompanion.doneSubmit
                );
                Coverleaf.Home.View.restoreAddcompButton();
                initcountries("country", "state", "required");
                $("#country",this.panel).unbind().bind("change", function() {
                    check_for_non_us_country($("#country",this.panel).val(), "country", "state", "required");
                });
                $(".round-five",addcompanion_wrapper).corner("round 5px");
            }
        },

        refresh : function(){
            Coverleaf.Account.Model.doSignOut();
            window.location.href=window.location.href.replace(/#.*/,"") + "&type=companion";
        },

        submitting : function() {
            $("#addcompanion_form_errormsg").hide().children().fadeOut("normal");
            $("#addcompanion_form_errormsg_failure_instr").hide().children().fadeOut("normal");
        },

        doneSubmit : function(data, status) {
            if (typeof CookieManager == 'undefined') CookieManager = new CookieManagerBase();
            var new_member_id = CookieManager.get(Constants.memberidCookie);
            var new_username = CookieManager.get(Constants.usernameCookie);
            var elem = data.documentElement;

            if (new_member_id){
                Coverleaf.setActiveMember({
                    member_id: new_member_id,
                    username: new_username
                });
                Coverleaf.Account.onSignIn.deliver();
            }
            if (elem) {
                var error_msg = elem.getAttribute('error_msg');
                var success = elem.getAttribute('success');
                if (error_msg) {
                    $(".busy").remove();
                    if (error_msg == "failure") {
                        $("#Addcompanion > h1, #companion_p").css("display","none");
                        $("#addcompanion_matchcode_wrapper").fadeIn("normal",function(){
                            var matchcode_field = $("#addcompanion_matchcode",$(this));
                            var code_field_pos = matchcode_field.position();
                            var code_field_width = matchcode_field.outerWidth() + 10;
                            matchcode_field.addClass("required");
                            $("#addcompanion_error_reasons")
                                .css({
                                    top:code_field_pos.top-25,
                                    left:(code_field_pos.left+code_field_width)
                                }).fadeIn("normal")
                                    .find("span.txt_dialog_close").unbind().bind('click.txt_dialog_close',function(){
                                        $(this).parent().fadeOut("slow");
                                    });
                            $("#addcompanion_matchcode").bind("blur",function(){
                                $("#addcompanion_error_reasons").fadeOut("slow");
                            });
                        });
                        $("#addcompanion_form_errormsg_incorrect_password").css("display","none");
                        $("#addcompanion_form_errormsg_incorrect_member_password").css("display","none");
                        var pageName = $("#addcompanion_collection_url",this.panel).text() + "/addcompanion/submitted_successfully";
                        Coverleaf.ReportingManager.trackPage(pageName);
                    }
                }
            } else {
                $("#panel_Addcompanion").fadeOut("fast",function(){
                    $(this).html(data).fadeIn("normal");
                });
                $("html").smoothScroll();
                var pageName = $("#addcompanion_collection_url",this.panel).text() + "/addcompanion/submitted_successfully";
                Coverleaf.ReportingManager.trackPage(pageName);
            }
        }
    }
})();

Coverleaf.Registration = (function(){
    var qsParm = [];
    var reg_type = "";
    var xmlDoc;

    function parseLocationString(){
        var query = location.search.substring(1);
        var parms = query.split("&");

        for (var i=0; i<parms.length; i++) {
            var pos = parms[i].indexOf("=");
            if (pos > 0) {
                var key = parms[i].substring(0,pos);
                var val = parms[i].substring(pos+1);
                qsParm[key] = val;
            }
        }
    }

    function getElementFromXmlDoc(doc,name){
        if(doc==undefined) return "";

        var element = doc.getElementsByTagName(name)[0];
        if(element==undefined || element.childNodes[0] == undefined  || element.childNodes[0].nodeValue == undefined){
            return "";
        }else{
            return unescape(element.childNodes[0].nodeValue).replace(/\+/g," ");
        }
    }

    function checkForGatewayRequest(){
        var xml="";

        if(qsParm["xml_req"]!=undefined  ){
            reg_type="gateway";
            xml = unescape(qsParm["xml_req"]);

            try{ //Internet Explorer
                if(typeof window.ActiveXObject != "function") {
                    throw("using ie");
                }
                xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
                xmlDoc.async="false";
                xmlDoc.loadXML(xml);
            }catch(e){
                try{ //Firefox, Mozilla, Opera, etc.
                    parser=new DOMParser();
                    xmlDoc=parser.parseFromString(xml,"text/xml");
                }catch(e){}
            }
            makeGatewayRequest();
        }
    }

    function makeGatewayRequest(){
        CommunicationManager.get(
            "/registration",
            {
                reg_type: reg_type,
                email_address: getElementFromXmlDoc(xmlDoc,"email_address"),
                country: getElementFromXmlDoc(xmlDoc,"country"),
                first_name: getElementFromXmlDoc(xmlDoc,"first_name"),
                last_name: getElementFromXmlDoc(xmlDoc,"last_name"),
                address1: getElementFromXmlDoc(xmlDoc,"address1"),
                address2: getElementFromXmlDoc(xmlDoc,"address2"),
                city: getElementFromXmlDoc(xmlDoc,"city"),
                state: getElementFromXmlDoc(xmlDoc,"state"),
                zip: getElementFromXmlDoc(xmlDoc,"zip"),
                promocode: getElementFromXmlDoc(xmlDoc,"source"),
                start_date: getElementFromXmlDoc(xmlDoc,"start_date"),
                end_date: getElementFromXmlDoc(xmlDoc,"end_date"),
                publication: getElementFromXmlDoc(xmlDoc,"publication"),
                billmelater: getElementFromXmlDoc(xmlDoc,"billmelater"),
                passwd: getElementFromXmlDoc(xmlDoc,"passwd"),
                passwd2: getElementFromXmlDoc(xmlDoc,"passwd"),
                terms_opt_in: getElementFromXmlDoc(xmlDoc,"terms_opt_in"),
                op: getElementFromXmlDoc(xmlDoc,"op")
            },
            checkGatewayResponse
        );
    }

    function checkGatewayResponse(data,status){
        if(typeof data == "string"){
            Coverleaf.Registration.panel.html(data);
            init_registration_behaviors("GET");
            $("#registration_passwd",Coverleaf.Registration.panel).blur(function(){
                $("#registration_passwd2",Coverleaf.Registration.panel).val($(this).val());
            });
        }
        checkRedirect(data,status);
    }

    function checkRedirect(data,status){
        var elem = data.documentElement;
        if (elem) {
            var redir_url = elem.getAttribute("redir_url");
            var new_member_id = elem.getAttribute("member_id");
            if (member_id) {
                Coverleaf.setActiveMember({member_id:new_member_id});
                Coverleaf.Account.onSignIn.deliver();
                Coverleaf.tabs[0].tabs('select','Home');
            }else if (redir_url) {
                top.location = redir_url;
            }
        }
    }

    function init_registration_behaviors(type){
        var request_type = typeof type != "undefined" ? type : "POST";
        CommunicationManager.prepareForm(
            "registration_form",
            "/registration",
            Coverleaf.Registration.doneSubmit,
            request_type
        );
        $("#registerFormSubmit",this.panel).unbind().bind('click',function(){
            $(this).closest("form").submit();
        });
        Coverleaf.roundCorners(this.panel);
        initcountries("registration_country", "");
    }

    function redirect_if_already_logged_in(){
        if(Coverleaf.getActiveMember()){
            var doc_id = jQuery.url.setUrl(document.location.href).param("document_id");
            document.location.href = "/library?document_id="+doc_id;
        }
    }

    return {
        initialized: false,
        init : function() {
            redirect_if_already_logged_in();
            this.panel = $("#panel_Registration");
            init_registration_behaviors();
            parseLocationString();
            checkForGatewayRequest();
        },
        doneSubmit : function(data){
            var elem = data.documentElement;
            if (elem) {
                var new_username = $("#registration_email_address",this.panel).val();
                var new_member_id = elem.getAttribute('member_id');
                var redir_url = elem.getAttribute('redir_url');
                if (new_member_id) {
                    // if we are registering from the clip page dialog in the reader...
                    if(Coverleaf.hashdict['doc_url'] && Coverleaf.hashdict['page']){
                        Coverleaf.flashMessage("Please wait, you will be redirected momentarily");
                        Coverleaf.My_Stuff.Model.addClipping( Coverleaf.hashdict['doc_url'], Coverleaf.hashdict['page'] );
                    }
                    // if we need to redirect back to somewhere
                    if(Coverleaf.hashdict['redirect_back']){
                        setTimeout("location.href = Coverleaf.hashdict['redirect_back']",4500);
                    }
                    Coverleaf.setActiveMember({
                        member_id: new_member_id,
                        username: new_username
                    });
                    Coverleaf.Account.onSignIn.deliver();
                    CommunicationManager.resetForm($("form[name='registration_other_form']"));
                    Coverleaf.tabs[0].tabs('select','Home');
                }else if (redir_url) {
                    top.location = redir_url;
                }
            }
        }
    }
})();

Coverleaf.Search = {
    initialized: false,
    trackName : "search",
    init: function(){
        if(Coverleaf.Search.initialized===false){
            Coverleaf.Search.Model.init();
            Coverleaf.Search.View.init();
            Coverleaf.Search.Controller.init();
            Coverleaf.Search.initialized = true;
        }
    },
    reset: function(){
        //this is a placeholder but must be here for the class to get initialized
    }
};
Coverleaf.Search.Model = (function(){
    var default_search_url = "/search?";
    var is_default_value = true;
    var pending_request = false;
    var search_history = [];
    var search_param = "query";
    var search_url

    function get_search_results(fn_callback){
        if(pending_request !== false){
            pending_request.abort();
        }
        pending_request = $.ajax({
            beforeSend: Coverleaf.Search.View.toggleActivityIndicator,
            error: function(){
                Coverleaf.Search.View.toggleActivityIndicator();
                throw new SearchError("failed_request");
            },
            success: function(data,textStatus){
                pending_request=false;
                Coverleaf.Search.View.toggleActivityIndicator();
                Coverleaf.Search.View.populateSearchResults(data);
            },
            type: "GET",
            url: search_url
        });
    }

    function set_search_url(){
        var params = search_history[search_history.length-1];
        search_url = default_search_url;
        for(var param in params){
            search_url += param + "=" + params[param] + "&";
        }
    }

    function preload_check(){
        var search_arg_index = location.search.indexOf("query=");
        var hash_arg_index = location.hash.indexOf("query=");
        if(search_arg_index == -1 && hash_arg_index != -1){
            var hash_params = Coverleaf.strToObj(location.hash);
            process_preloaded_search(hash_params)
        }
    }

    function process_preloaded_search(params_obj){
        if(params_obj.hasOwnProperty("query") && params_obj.query.length > 0){
            is_default_value = false;
            search_history.push({});
            Coverleaf.Search.Model.getSearchInputs().val(params_obj.query);
            for(var param in params_obj){
                if(params_obj.hasOwnProperty(param)){
                    add_search_param(param,params_obj[param]);
                    switch(param){
                        case "query":
                            Coverleaf.Search.Model.getSearchInputs().val(params_obj[param]);
                            break;
                        case "category":
                            $("input[name='category']").removeAttr("checked");
                            var categories = params_obj[param].split(",");
                            for(var i=0;i<categories.length;i++){
                                Coverleaf.Search.View.checkFilterOptions(categories[i],"search_filter_scope");
                            }
                            break;
                        default:
                            Coverleaf.Search.View.checkFilterOptions(params_obj[param],"search_filter_scope");
                            break;
                    }
                }
            }
        }
    }

    function add_search_param(param,value){
        search_history[search_history.length-1][param] = value;
    }

    function remove_search_param(param){
        if(search_history[search_history.length-1].hasOwnProperty(param)){
            delete search_history[search_history.length-1][param];
        }
    }

    return {
        panel: {},

        init : function(){
            this.panel = $("#panel_Search");
            this.searchOptionTrigger = $("#search_option_trigger");
            this.searchOptions = $("#search_options");
            setTimeout(function(){preload_check()},500);
        },

        getSearchResultsDiv : function(){
            return $("#search_results",this.panel);
        },

        isDefaultValue: function(val){
            if(typeof val == "boolean"){
                is_default_value = val;
            }
            return is_default_value;
        },

        getSearchInputs: function(scope){
            return $("input[name='search_term']",scope);
        },

        getSearchSubmits: function(scope){
            return $(".search_submit",scope);
        },

        getSearchForms: function(scope){
            return $("form.search_form",scope);
        },

        getPaginationLinks: function(scope){
            return $("a.search_pagination_link");
        },

        getCategoryFilterLinks: function(scope){
            return $("a.search_filter_category_update");
        },

        getCategoryFilterInputs: function(scope){
            return $("#search_filter_categories input",scope);
        },

        getSearchFilterInputs: function(){
            return $("input.search_filter_input");
        },

        setSearchPubDate: function(){
            var pub_date = $("input[name='publish_date']:checked").val();
            if(pub_date != "all"){
                add_search_param("pub_date",pub_date);
            };
        },

        setSearchCategory: function(){
            var cat_inputs = $("input[name='category']");
            var cat_inputs_count = cat_inputs.length;
            var cat_inputs_checked = cat_inputs.filter(":checked");
            var cat_inputs_checked_count = cat_inputs_checked.length;
            if(cat_inputs_count){
              // we only add the category param if it's a subset (not all checked)
              if(cat_inputs_checked_count > 0 && cat_inputs_count != cat_inputs_checked_count){
                  var categories = [];
                  cat_inputs_checked.each(function(){
                      categories.push($(this).val());
                  });
                  add_search_param("category",categories.join(","));
              }else if(cat_inputs_checked_count === 0){
                  throw new SearchError("no_categories");
              }
            }
            return false;
        },

        setSearchScope: function(){
            var scope = $("input[name='scope']:checked").val();
            // need to update later to check for logged in user
            if(scope != "all"){
                var member = Coverleaf.getActiveMember();
                if(member){
                    add_search_param("scope",scope);
                    add_search_param("member_id",member.member_id);
                }
            }else{
                remove_search_param("scope");
                remove_search_param("member_id");
            }
        },

        getSearchQuery: function(){
            return search_history.length > 0
                ? search_history[search_history.length-1][search_param]
                : null;
        },

        setSearchQuery: function(query){
            if(query != "" && search_history.length == 0 || query != search_history[search_history.length-1][search_param]){
                search_history.push({});
                add_search_param(search_param,query);
            }
        },

        setSearchObject: function(query){
            if(this.isDefaultValue() === false){
                this.setSearchQuery(query);
                this.setSearchPubDate();
                this.setSearchCategory();
                this.setSearchScope();
            }
        },

        getSearchObject: function(){
            return search_history[search_history.length-1]
        },

        getSearchUrl: function(){
            return search_url;
        },

        getSearchResults: function(){
            if(this.isDefaultValue() === false){
                set_search_url();
                get_search_results();
            }
        },

        setSearchCursor: function(start){
            if(start!==false && search_history.length > 0){
                add_search_param("start",start);
                add_search_param("end",start+20);
            }
        },

        getSearchCursor: function(){
            return search_history.length > 0 && typeof search_history[search_history.length-1].hasOwnProperty("start")
                ? search_history[search_history.length-1]["start"]
                : 0;
        }
    }
})();

Coverleaf.Search.View = (function(){
    var m = Coverleaf.Search.Model;

    function create_categories_filter(){

    }

    return {

        init : function(){},

        populateSearchResults : function(data){
            Coverleaf.Search.Model.getSearchResultsDiv().html(data);
            Coverleaf.Search.Model.getSearchInputs().val(m.getSearchQuery());
        },

        isActivePanel : function(){
            return m.panel.is(":visible");
        },

        activateSearchPanel : function(){
            Coverleaf.tabs[0].tabs('select',Constants.tabNameSearch);
        },

        checkFilterOptions : function(val,scope_class){
            $('.'+scope_class+' input[value="'+val+'"]').each(function(){
                this.checked = true;
            });
        },

        hideOpenOptionsMenu : function(){
            if(Coverleaf.Search.Model.searchOptions){
                Coverleaf.Search.Model.searchOptions.slideUp();
            }
        },

        toggleOptionsMenu : function(){
            Coverleaf.Account.View.hideSignInForm();
            m.searchOptions.slideToggle();
        },

        toggleActivityIndicator : function(){
            $("#searching",m.panel).toggleClass("hidden");
        },

        showError : function(e){
            alert(e.message);
        }

    }
})();

Coverleaf.Search.Controller = (function(){
    var m = Coverleaf.Search.Model;
    var v = Coverleaf.Search.View;

    function handle_input_blur(){
        val = $.trim($(this).val());
        if(m.isDefaultValue() === false && val.length){
            m.setSearchObject(val);
        }else{
            var current_search_value = m.getSearchQuery();
            if(current_search_value){
                $(this).val(current_search_value);
            }else{
                $(this).val(Constants.searchDefaultValue);
            }
            m.isDefaultValue(true);
        }
    }

    function handle_input_focus(){
        if(!m.getSearchQuery() || m.isDefaultValue() === true){
            $(this).val("");
        }
    }

    function handle_input_keydown(){
        if(m.isDefaultValue() === true){
            m.isDefaultValue(false);
        }
    }

    function handle_form_submit(event){
        event.preventDefault();
        event.stopPropagation();
        Coverleaf.Search.View.hideOpenOptionsMenu();
        Coverleaf.Search.Controller.search(m.getSearchInputs($(this)).val());
    }

    function handle_submit_click(){
        Coverleaf.Search.View.hideOpenOptionsMenu();
        Coverleaf.Search.Controller.search(m.getSearchInputs().val());
    }

    function handle_pagination_click(){
        var direction = $(this).attr("rel");
        var cursor = Coverleaf.Search.Model.getSearchCursor();
        if(direction == "prev"){
            Coverleaf.Search.Model.setSearchCursor((cursor-21));
        }else if(direction == "next"){
            Coverleaf.Search.Model.setSearchCursor((cursor+21));
        }
        Coverleaf.Search.Model.getSearchResults();
        return false;
    }

    function handle_category_filter_update(){
        var checked_state = $(this).attr("rel") == "uncheck" ? false : true;
        var categories = m.getCategoryFilterInputs(m.panel);
        categories.each(function(){
            this.checked = checked_state;
        });
        return false;
    }

    function handle_filter_input_click(){
        var scope_class = $(this).parents("[class^='search_filter']").attr("class");
        var value = $(this).val();
        if($(this).is(":checked")){
            Coverleaf.Search.View.checkFilterOptions(value,scope_class);
        }
    }

    function get_new_history_entry(){
        var params = Coverleaf.Search.Model.getSearchObject();
        var retval = "#Search&"
        for(var param in params){
            retval += param + "=" + params[param] + "&";
        }
        return retval.substring(0,retval.length-1)
    }

    return {
        init : function(){
            m.getSearchInputs()
                .bind('focus',handle_input_focus)
                .bind('blur',handle_input_blur)
                .bind('keydown',handle_input_keydown);

            m.getSearchForms()
                .bind('submit',handle_form_submit);

            m.getSearchSubmits()
                .live('click',handle_submit_click);

            m.getPaginationLinks()
                .live('click',handle_pagination_click);

            m.getCategoryFilterLinks()
                .live('click',handle_category_filter_update);

            m.getSearchFilterInputs()
                .live('click',handle_filter_input_click);

            m.searchOptionTrigger.bind('click',v.toggleOptionsMenu)
        },

        search: function(query){
            try {
                query = $.trim(query);
                if(m.isDefaultValue() === false && query.length){
                    m.setSearchObject(query);
                    m.getSearchResults();
                    //tab_anchor.attr("href",orig_href);
                    var history_hash = get_new_history_entry();
                    location.hash = history_hash;
                    Coverleaf.updateHistory(history_hash);
                }
            }catch(e){
                if(e instanceof SearchError){
                    v.showError(e);
                    return true;
                }
            }finally{
                if(v.isActivePanel()===false){
                    v.activateSearchPanel();
                }
            }
        }
    }
})();

function SearchError(message){
    this.message = message;
}

SearchError.prototype = new Error();


/*###############Copyright##################
 *####   Copyright 2009 Texterity, Inc  ####
 *###############Copyright##################
 */