//arrays of expanded objects
var item_click_expanded                   = [],
    item_click_exclusive_sibling_expanded = [],
    item_hover_exclusive_global_expanded  = [];
    
var item_hover_exclusive_global_closing_timer;

//note that jQuery also supports merge and unique
Array.prototype.remove = function remove(me){
    var i = $.inArray(me, this);
    if (i != -1) this.splice(i,1);
    return i; //-1 if not found
}

function item_click() {
    var self = this;
    var targets = $(this).children(".item_contents").children();
    if (targets.filter(":hidden").length) {
        show.apply(this, [function(){$(self).trigger("expanded");}]);
        item_click_expanded.push(this);
    } else {
        hide.apply(this, [function(){$(self).trigger("compacted");}]);
        item_click_expanded.remove(this);
    }
    return false; /* supress bubble up */
}

function item_click_exclusive_sibling() {
    //only one sibling can be expanded at a time (not global)
    var self = this;
    var targets = $(this).children(".item_contents").children();
    if (targets.filter(":hidden").length) {
        show.apply(this, [function(){$(self).trigger("expanded");}]);
        //close siblings
        $(this).siblings().each(function(){
            hide.apply(this);
            item_click_exclusive_sibling_expanded.remove(this);
        });
        item_click_exclusive_sibling_expanded.push(this);
    } else {
        hide.apply(this, [function(){$(self).trigger("compacted");}]);
        item_click_expanded.remove(this);
    }
    return false; /* supress bubble up */
}

function item_hover_exclusive_global() {
    //global singular item_contents (hover over menus)
    var self = this;
    var targets = $(this).children(".item_contents").children();
    show.apply(this, [function(){$(self).trigger("expanded");}]);
    //close anything that is not an ancestor of this
    var elementtoclose, ancestor;
    for (var i = 0; i < item_hover_exclusive_global_expanded.length; i++) {
        ancestor       = this;
        elementtoclose = item_hover_exclusive_global_expanded[i];
        while (ancestor && ancestor != elementtoclose) ancestor = ancestor.parentNode;
        if (!ancestor) {
            hide.apply(elementtoclose);
            item_hover_exclusive_global_expanded.remove(this);
        }
    }
    clearTimeout(item_hover_exclusive_global_closing_timer); //prevent closing if in process
    item_hover_exclusive_global_expanded.push(this);
    return false; /* supress bubble up */
}

//basic show hide toggle functionality
function show(callback) {
  var targets = $(this).children('.item_contents').children();
  $(this).addClass("expanded");
  if (targets.filter(":hidden").length) 
    if (callback) targets.slideDown("fast", callback);
    else          targets.slideDown("fast");
    targets.attr("compact", "compact"); //indicate compact
  //hide the excluded contents (when expanded)
  targets = $(this).children('.item_contents_exclude').children();
  targets.slideUp("fast").attr("compact", "compact"); //indicate compact
  //change plus / minus
  var exp_img = $(this).find(".item_click_image");
  if (exp_img && exp_img.attr("src")) exp_img.attr("src", exp_img.attr("src").replace(/plus/gi, 'minus'));
}

function hide(callback) {
    var targets = $(this).children(".item_contents").children();
    $(this).removeClass("expanded");
    if (targets.filter(":visible").length) {
        if (callback) targets.slideUp("fast", callback);
        else          targets.slideUp("fast");
        targets.removeAttr("compact");
    }
    //show the excluded contents (when collapsed)
    targets = $(this).find('.item_contents_exclude').children();
    targets.slideDown("fast").removeAttr("compact"); //indicate compact
    //change plus / minus
    var exp_img = $(this).find(".item_click_image");
    if (exp_img && exp_img.attr("src")) exp_img.attr("src", exp_img.attr("src").replace(/minus/gi, 'plus'));
}

//global hide and show functions
function expandAll() {
    alert('not implemented');
}
function hideAll() {
    hideAll_item_click();
    hideAll_item_click_exclusive_sibling();
    hideAll_item_hover_exclusive_global();
}
function hideAll_item_click() {
  for (var i = 0; i < item_click_expanded.length; i++) hide.apply(item_click_expanded[i]);
  item_click_expanded = [];
}
function hideAll_item_click_exclusive_sibling() {
  for (var i = 0; i < item_click_exclusive_sibling_expanded.length; i++) hide.apply(item_click_exclusive_sibling_expanded[i]);
  item_click_exclusive_sibling_expanded = [];
}
function hideAll_item_hover_exclusive_global() {
  for (var i = 0; i < item_hover_exclusive_global_expanded.length; i++) hide.apply(item_hover_exclusive_global_expanded[i]);
  item_hover_exclusive_global_expanded = [];
}

//setup
$(document).ready(function(){
    //attach the click events for show/hide
    $(".item_click").click(item_click);
    $(".item_click_exclusive_sibling").click(item_click_exclusive_sibling);
    $(".item_hover_exclusive_global").mouseover(item_hover_exclusive_global);
    
    //initially hide the expandable elements
    $(".item_click, .item_click_exclusive_sibling, .item_hover_exclusive_global").find('.item_contents').children().hide(); 
    
    //hide all of the menus if the mouse is over the document or is clicked (IE fucks up the document.mouseover)
    if (isie) $(document).click(hideAll);
    else $(document).mouseover(function (){
        if (item_hover_exclusive_global_closing_timer) clearTimeout(item_hover_exclusive_global_closing_timer);
        item_hover_exclusive_global_closing_timer = setTimeout(hideAll_item_hover_exclusive_global, 1000);
    });
});
