/*
 * Treeview 1.4 - jQuery plugin to hide and show branches of a tree
 *
 * http://bassistance.de/jquery-plugins/jquery-plugin-treeview/
 * http://docs.jquery.com/Plugins/Treeview
 *
 * Copyright (c) 2007 Jörn Zaefferer
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: $Id: jquery.treeview.js 4684 2008-02-07 19:08:06Z joern.zaefferer $
 *
 */
 (function($){
$.extend($.fn,{
swapClass: function(c1,c2){
var c1Elements=this.filter('.'+c1)
this.filter('.'+c2).removeClass(c2).addClass(c1)
c1Elements.removeClass(c1).addClass(c2)
return this
},
replaceClass: function(c1,c2){
return this.filter('.'+c1).removeClass(c1).addClass(c2).end()
},
hoverClass: function(className){
className=className || "hover"
return this.hover(function(){
$(this).addClass(className)
},function(){
$(this).removeClass(className)
})
},
heightToggle: function(animated,callback){
animated ?
this.animate({height: "toggle"},animated,callback):
this.each(function(){
jQuery(this)[ jQuery(this).is(":hidden")? "show" : "hide" ]()
if(callback)
callback.apply(this,arguments)
})
},
heightHide: function(animated,callback){
if(animated){
this.animate({height: "hide"},animated,callback)
}else{
this.hide()
if(callback)
this.each(callback)}
},
prepareBranches: function(settings){
if(!settings.prerendered){
this.filter(":last-child:not(ul)").addClass(CLASSES.last)
this.filter((settings.collapsed ? "" : "."+CLASSES.closed)+":not(."+CLASSES.open+")").find(">ul").hide()}
return this.filter(":has(>ul)")
},
applyClasses: function(settings,toggler){
this.filter(":has(>ul):not(:has(>a))").find(">span").click(function(event){
toggler.apply($(this).next())
}).add($("a",this)).hoverClass()
if(!settings.prerendered){
this.filter(":has(>ul:hidden)")
.addClass(CLASSES.expandable)
.replaceClass(CLASSES.last,CLASSES.lastExpandable)
this.not(":has(>ul:hidden)")
.addClass(CLASSES.collapsable)
.replaceClass(CLASSES.last,CLASSES.lastCollapsable)
this.prepend("<div class=\""+CLASSES.hitarea+"\"/>").find("div."+CLASSES.hitarea).each(function(){
var classes=""
$.each($(this).parent().attr("class").split(" "),function(){
classes+=this+"-hitarea "
})
$(this).addClass(classes)
})}
this.find("div."+CLASSES.hitarea).click(toggler)
},
treeview: function(settings){
settings=$.extend({
cookieId: "treeview"
},settings)
if(settings.add){
return this.trigger("add",[settings.add])}
if(settings.toggle){
var callback=settings.toggle
settings.toggle=function(){
return callback.apply($(this).parent()[0],arguments)}}
function treeController(tree,control){
function handler(filter){
return function(){
toggler.apply($("div."+CLASSES.hitarea,tree).filter(function(){
return filter ? $(this).parent("."+filter).length : true
}))
return false}}
$("a:eq(0)",control).click(handler(CLASSES.collapsable))
$("a:eq(1)",control).click(handler(CLASSES.expandable))
$("a:eq(2)",control).click(handler())}
function toggler(){
$(this)
.parent()
.find(">.hitarea")
.swapClass(CLASSES.collapsableHitarea,CLASSES.expandableHitarea)
.swapClass(CLASSES.lastCollapsableHitarea,CLASSES.lastExpandableHitarea)
.end()
.swapClass(CLASSES.collapsable,CLASSES.expandable)
.swapClass(CLASSES.lastCollapsable,CLASSES.lastExpandable)
.find(">ul")
.heightToggle(settings.animated,settings.toggle)
if(settings.unique){
$(this).parent()
.siblings()
.find(">.hitarea")
.replaceClass(CLASSES.collapsableHitarea,CLASSES.expandableHitarea)
.replaceClass(CLASSES.lastCollapsableHitarea,CLASSES.lastExpandableHitarea)
.end()
.replaceClass(CLASSES.collapsable,CLASSES.expandable)
.replaceClass(CLASSES.lastCollapsable,CLASSES.lastExpandable)
.find(">ul")
.heightHide(settings.animated,settings.toggle)}}
function serialize(){
function binary(arg){
return arg ? 1 : 0}
var data=[]
branches.each(function(i,e){
data[i]=$(e).is(":has(>ul:visible)")? 1 : 0
})
$.cookie(settings.cookieId,data.join(""))}
function deserialize(){
var stored=$.cookie(settings.cookieId)
if(stored){
var data=stored.split("")
branches.each(function(i,e){
$(e).find(">ul")[ parseInt(data[i])? "show" : "hide" ]()
})}}
this.addClass("treeview")
var branches=this.find("li").prepareBranches(settings)
switch(settings.persist){
case "cookie":
var toggleCallback=settings.toggle
settings.toggle=function(){
serialize()
if(toggleCallback){
toggleCallback.apply(this,arguments)}}
deserialize()
break
case "location":
var current=this.find("a").filter(function(){
return this.href.substring(0,(this.href.indexOf("?")==-1)? this.href.length: this.href.indexOf("?")).toLowerCase()==location.href.substring(0,(location.href.indexOf("?")==-1)? location.href.length: location.href.indexOf("?")).toLowerCase()
})
if(current.length){
current.addClass("selected").parents("ul, li").add(current.next()).show()}
break}
branches.applyClasses(settings,toggler)
if(settings.control){
treeController(this,settings.control)
$(settings.control).show()}
return this.bind("add",function(event,branches){
$(branches).prev()
.removeClass(CLASSES.last)
.removeClass(CLASSES.lastCollapsable)
.removeClass(CLASSES.lastExpandable)
.find(">.hitarea")
.removeClass(CLASSES.lastCollapsableHitarea)
.removeClass(CLASSES.lastExpandableHitarea)
$(branches).find("li").andSelf().prepareBranches(settings).applyClasses(settings,toggler)
})}
})
var CLASSES=$.fn.treeview.classes={
open: "open",
closed: "closed",
expandable: "expandable",
expandableHitarea: "expandable-hitarea",
lastExpandableHitarea: "lastExpandable-hitarea",
collapsable: "collapsable",
collapsableHitarea: "collapsable-hitarea",
lastCollapsableHitarea: "lastCollapsable-hitarea",
lastCollapsable: "lastCollapsable",
lastExpandable: "lastExpandable",
last: "last",
hitarea: "hitarea"}
$.fn.Treeview=$.fn.treeview
})(jQuery)

