(function($){
	$.fn.menu = function(options) {
		var defaults = {
			css_path:"/css/menu.css",
			xml_path:"/xml/default.asp",
			direction:"down",
			hOffset:0,
			vOffset:0,
			currentL1:0,
			showL3s:true,
			debug:false
		};
		var dataStore = {
			currentActive:0,//currently active L1
			timeout:"",//the timout that hides the menus when a user rolls off them.
			L3Divs:0 //object of L3 Menus
		};
		var options = $.extend(defaults, options);
		
		return this.each(function() {
			var menuid = $.getNextID();
			var $menuHolder = $(this);
			//$("<link rel='stylesheet' type='text/css' href='"+options.css_path+"'/>").appendTo("head");
			if(options.sid != undefined){
				buildMenus();
			}else{
				if(options.debug){$.log("School ID is not set.");}
			}//end if(sid)
			
			function buildMenus(){
				var L1String;
				for(h=0; h<options.settings.length; h++){
					if(h == 0){
						L1String = options.settings[h].pageid;
					}else{
						L1String += "|" + options.settings[h].pageid;
					}
				}
				$.ajax({
					type: "GET",
					url: options.xml_path+"?sid="+options.sid+"&type=menu2&id="+L1String,
					dataType: "xml",
					success: function(xml) {
						$(xml).find('L1').each(function(){
							var $menuButton = $("#"+$menuHolder.attr("id")+"_"+$(this).attr("tid"));
							$menuHolder.after("<div id='L2"+menuid+"_"+$(this).attr("tid")+"' class='submenu"+options.direction+"'></div>");
							var L1id = $(this).attr("tid");
							if(L1id == options.currentL1){
								$("#"+$menuHolder.attr("id")+"_"+L1id).addClass("on");
							}
							var $subMenu = $("#L2"+menuid+"_" + L1id);
							$subMenu.css("display","none")
							.hover(function(){
							    dataStore.currentActive = L1id;
							    clearTimeout(dataStore.timeout);
							},function(){
								dataStore.currentActive = 0;
								dataStore.timeout = setTimeout(function(){ animateAllOut()}, 100);
							});
							if(options.debug){$.log("L2 Holder Built:"+ $subMenu.attr("id"));}
							//get the L2s
							$(this).find("L2").each(function(){
								var target = $(this).find('target:first').text() == true ? "_blank":"_self";
								
								var link = $(this).find('url:first').text();
								if(typeof pdGlobal != "undefined"){
									if(pdGlobal.userLoggedIn){
										var link = "javascript:__pdL('"+$(this).find('id:first').text()+"','"+$(this).find('title:first').text()+"', '2', '', 'pbContent', 'True', '0', '', 'default.aspx')";
									}
								}
								
								var $aTag = $(document.createElement("a"))
											.addClass("subMenuItems"+options.direction)
											.attr("href", $(this).find('url:first').text())
											.attr("target",target)
											.attr("id","L2Item"+menuid+"_"+$(this).find('id:first').text())
											.append("<span>"+$(this).find('title:first').text()+"</span>");
												
								$aTag.hover(function(){
									
									dataStore.currentActive = L1id;
									clearTimeout(dataStore.timeout);
									
									//check for L3s
									var pageid = $(this).attr("id").split("_")[1];
									animateAllL3Out(pageid);
									if($("#L3"+menuid+"_"+pageid).length > 0){
										animateL3HolderIn(pageid);
									}
									
								},function(){
									var $obj = $(this);
									var pageID = $obj.data("pageID");
									
									if($obj.data("hasMenu")){
										dataStore.currentActive = L1id;
										clearTimeout(dataStore.timeout);
									} else {
										dataStore.currentActive = 0;
										dataStore.timeout = setTimeout(function(){ animateAllOut()}, 100);
									}
									var pageid = $(this).attr("id").split("_")[1];
								});
								
								//append new L2
								$subMenu.append($aTag); 
								//look for L3s
								if(options.showL3s){
									var hasL3s = false;
									var $L3Menu;
									
									$(this).find("L3").each(function(){
										if(!hasL3s){
											//just do this the first time through the loop...
											$menuHolder.after("<div id='L3"+menuid+"_"+$(this).find("parentid").text()+"' class='L3Menu"+options.direction+"'></div>");
											$L3Menu = $("#L3"+menuid+"_" + $(this).find("parentid").text());
											$L3Menu.css("display","none");
										}
										var target = $(this).find('target:first').text() == true ? "_blank":"_self";
										var $L3Tag = $(document.createElement("a"))
													.addClass("L3MenuItems"+options.direction)
													.attr("href", $(this).find('url:first').text())
													.attr("target",target)
													.append("<span>"+$(this).find('title:first').text()+"</span>");
													
										$L3Tag.hover(function(){
											dataStore.currentActive = L1id;
									    	clearTimeout(dataStore.timeout);
									    },function(){
									    	dataStore.currentActive = 0;
									    	dataStore.timeout = setTimeout(function(){ animateAllOut()}, 100);
									    });
									    
										//append new L3
										$L3Menu.append($L3Tag); 
										hasL3s = true;
									});//end find L3s
									
									if(hasL3s){
										$L3Menu.prepend("<div id='L3menu-header'><!-- --></div>")
								    	.append("<div id='L3menu-footer'><!-- --></div>")
								    	.wrapInner("<div id='holder'></div>")
								    	.css("overflow","hidden");
										var $itemHolder = $L3Menu.children();
										
										$itemHolder.children().filter(function(){  
										    return $(this).attr("id") == "L3menu-header" || $(this).attr("id") == "L3menu-footer";
										})
										.hover(function(){
										    dataStore.currentActive = L1id;
										    clearTimeout(dataStore.timeout);
										},function(){
										    dataStore.currentActive = 0;
										    dataStore.timeout = setTimeout(function(){ animateAllOut()}, 100);
										});
										$aTag.data("hasMenu",true);
										positionL3MenuHolder($L3Menu);
									}
								}
								
							});//end find L2s
							//get the right offsets....
							var hOffset = options.hOffset;
							var vOffset = options.vOffset;		
							for(d=0; d<options.settings.length; d++){
							    if(options.settings[d].pageid == L1id){
							    	if(options.settings[d].hoffset != undefined){
							    		hOffset = options.settings[d].hoffset;
							    	}
							    	if(options.settings[d].voffset != undefined){
							    		vOffset = options.settings[d].voffset;
							    	}
							    }
							}
							
							$subMenu.prepend("<div id='menu-header'><!-- --></div>")
							    .append("<div id='menu-footer'><!-- --></div>")
							    .wrapInner("<div id='holder'></div>")
							    .css("overflow","hidden")
							    .data("hOffset",hOffset)
							    .data("vOffset",vOffset);
							
							if(options.direction == "up"){						
								/*
								$.log($($subMenu.attr("id")+" #holder").html());
								
								var $L2s = $($subMenu.attr("id")+" #holder").html().get();
								$L2s.each(function(){
									$.log("testing...")
								});
								//$.log($L2s);
								
								$subMenu.children().filter(function(){  
							    	return $(this).hasClass("subMenuItems"+options.direction);
								}).remove();
								
								var $reversedL2s = $L2s.reverse();
								$($subMenu.attr("id") + " #holder").html($reversedL2s);
								*/
							}
							
							var $itemHolder = $subMenu.children();
							
							$itemHolder.children().filter(function(){  
							    return $(this).attr("id") == "menu-header" || $(this).attr("id") == "menu-footer";
							})
							.hover(function(){
							    dataStore.currentActive = L1id;
							    clearTimeout(dataStore.timeout);
							},function(){
							    dataStore.currentActive = 0;
							    dataStore.timeout = setTimeout(function(){ animateAllOut()}, 100);
							});
							
							$menuButton.data("hasMenu",true);
							positionSubMenuHolder($subMenu);
						});//end find L1s
						//did this here so it happened AFTER the menus were written to the page
						buildMenuAction();
						dataStore.L3Divs = $(".L3Menu"+options.direction);
						//if horizontal, open current L2
						if(options.direction == "horizontal"){
							$obj = $("#"+$menuHolder.attr("id")+"_"+options.currentL1);
							if($obj.data("hasMenu")){
								var pageID =  $obj.data("pageID");
								animateSubMenuHolderIn(pageID);
							}
						}
					},
					error: function(request,tStatus,eThrown){
						if(options.debug){$.log("Error loading XML: "+eThrown);}
					}
				});
			}//end buildMenus()
			
			function buildMenuAction(){
				var $menuItems = $("#"+$menuHolder.attr("id")+" li a");
				$menuItems.each(function(){
					$obj = $(this);
					if(options.debug){$.log($(this).attr("id"));}
					$obj.data("pageID",$(this).attr("id").substring($menuHolder.attr("id").length+1,$(this).attr("id").length));
				});
				
				$menuItems.hover(function () {
					killCurrentL2();
					if(options.debug){$.log("Show Menu!");}
					var $obj = $(this);
					$obj.addClass("on");
					if($obj.data("hasMenu")){
						var pageID =  $obj.data("pageID");
						dataStore.currentActive = pageID;
						animateSubMenuHolderIn(pageID);
					}
				}, 
				function () {
					var $obj = $(this);
					var pageID = $obj.data("pageID");
										
					if($obj.data("hasMenu")){
						dataStore.currentActive = 0;
						dataStore.timeout = setTimeout(function(){ animateAllOut()}, 50);
					} else {
						if(options.currentL1 != pageID)
							$obj.removeClass("on");
					}
					if(options.direction == "horizontal" && !$obj.data("hasMenu")){
						dataStore.timeout = setTimeout(function(){ animateAllOut()}, 50);
					}
					
				});
				if(options.debug){$.log("Menu Actions Built");}
			}//end buildMenuAction
			
			/*-------------------ANIMATE ALL FUNCTIONS--------------------*/
			
			function killCurrentL2(){
				killAllL3Out();
				//dataStore.currentActive = 0;
				if(options.direction == "horizontal"){
					animateSubMenuHolderOut(options.currentL1);
				}
			}			
			
			function animateAllOut(){
				killAllL3Out();
				var $menuItems = $("#"+$menuHolder.attr("id")+" li a");
				$menuItems.each(function(){
					var pageid = $(this).attr("id").split("_")[1];
					if(pageid != dataStore.currentActive){
						animateSubMenuHolderOut(pageid);
					}
					
					if(options.direction == "horizontal" && (options.currentL1 == pageid && dataStore.currentActive == 0)){
						animateSubMenuHolderIn(options.currentL1);
					}
				});
			}
			
			function killAllL3Out(){
				$L3s = dataStore.L3Divs;
				$L3s.each(function(){
					var pageid = $(this).attr("id").split("_")[1];
					animateL3HolderOut(pageid,false);
				});
			}
			
			function animateAllL3Out(currentActiveL2){
				$L3s = dataStore.L3Divs;
				$L3s.each(function(){
					var pageid = $(this).attr("id").split("_")[1];					
					if(pageid != currentActiveL2)
						animateL3HolderOut(pageid);
				});
			}
			
			/*-------------------L2 FUNCTIONS--------------------*/
			
			function positionSubMenu($menuButton, $subMenu){
				var offset = $menuButton.getTopLeft();
				var top = 0;
				var left = 0;
				switch (options.direction){
				case "up":
					top = parseInt(offset.top) - parseInt($subMenu.height()) + parseInt($subMenu.data("vOffset"));
					left = parseInt(offset.left) + parseInt($subMenu.data("hOffset"));
					break;
				case "down":
					top = parseInt(offset.top) + $menuButton.height() + parseInt($subMenu.data("vOffset"));
					left = parseInt(offset.left) + parseInt($subMenu.data("hOffset"));	
					break;
				case "left":
				case "right":
					top = parseInt(offset.top) + parseInt($subMenu.data("vOffset"));
					left = parseInt(offset.left) + $menuButton.width() + parseInt($subMenu.data("hOffset"));	
					break;
				case "horizontal":
					//set to the left positon of the main ul container
					var offset = $menuHolder.getTopLeft();
					top = parseInt(offset.top) + $menuHolder.height() + parseInt($subMenu.data("vOffset"));
					left = parseInt(offset.left) + parseInt($subMenu.data("hOffset"));
					break;
				default:
					top = parseInt(offset.top) + $menuButton.height() + parseInt($subMenu.data("vOffset"));
					left = parseInt(offset.left) + parseInt($subMenu.data("hOffset"));
					break;
				}
				$subMenu.css("top", top+"px");
				$subMenu.css("left", left+"px");
			}//end positionSubMenu
			
			function positionSubMenuHolder($subMenu){
				var top = 0;
				var left = 0;
				switch (options.direction){
					case "up":
						top = $subMenu.height();
						left = 0;
						break;
					case "down":
						top = $subMenu.height() * -1;
						left = 0;
						break;
					case "right":
						top = 0;
						left = 0 - $subMenu.width();
						break;
					case "left":
						top = 0;
						left = $subMenu.width() * 2;
						break;
					case "horizontal":
						top = $subMenu.height() * -1;
						left = 0;
						break;
					default:
						top = $subMenu.height() * -1;
						left = 0;
						break;
				}
				var $subMenuHolder = $subMenu.children("#holder");
				$subMenuHolder.css("top",top).css("left",left).css("position","relative");
			}//end positionSubMenuHolder			
						
			function animateSubMenuHolderIn(pageID) {
				if(options.debug){$.log("animate menu");}
				var $menuButton = $("#"+$menuHolder.attr("id")+"_"+pageID);
				var $subMenu =  $("#L2"+menuid+"_" + pageID);
				var $subHolder = $("#L2"+menuid+"_" + pageID+" div:first");
				var top = 0;
				var left = 0;
				
				if(options.debug){$.txt($subHolder);}
				positionSubMenu($menuButton, $subMenu);
				
				$menuButton.addClass("on");
				$subHolder.queue("fx", []).stop();
				$subMenu.show().css("z-index",1000);
				
				//alert(options.direction);
				switch (options.direction){
					case "up":
						$subHolder.animate({top: 0},500);
						break;
					case "down":
						$subHolder.animate({top: 0},500);
						//$subHolder.css("top",0);
						break;
					case "left":
					case "right":
						$subHolder.animate({left: 0},500);
						break;
					case "horizontal":
						$subHolder.animate({top: 0},500);
						break;
					default:
						$subHolder.animate({top: 0},500);
						break;
				}
			}//end animateSubMenuHolderIn
			
			function animateSubMenuHolderOut(pageID) {
				//if(options.debug){$.log("animate OUT");}
				var $menuButton = $("#"+$menuHolder.attr("id")+"_"+pageID);
				var $subMenu =  $("#L2"+menuid+"_" + pageID);
				
				//if(options.debug){$.log("menuid:"+menuid);}
				//if(options.debug){$.log("#L2"+menuid+"_" + pageID+" #holder");}
				var $subHolder = $("#L2"+menuid+"_" + pageID+" div:first");
			//	if(options.debug){$.log($menuButton);}
				var top = 0;
				var left = 0;
				
				if(options.currentL1 != pageID)
					$menuButton.removeClass("on");
				
				
				$subMenu.css("z-index",500);
				$subHolder.queue("fx", []).stop();
				switch (options.direction){
					case "up":
						top = $subMenu.height();
						$subHolder.animate({top: top},500);
					break;
					case "down":
						top = parseInt($subMenu.height()) * -1;
						$subHolder.animate({top: top},500); 
						//if(options.debug){$.log("TOP: "+top);}
						//if(options.debug){$.log("object = "+$subHolder.attr("id"));}
						//$subHolder.css({"top":top + "px"});
					break;
					case "right":
						left = 0 - parseInt($subMenu.width());
						$subHolder.animate({left: left},500);
					break;
					case "left":
						left = parseInt($subMenu.width()) * 2;
						$subHolder.animate({left: left},500);
					break;
					case "horizontal":
						top = parseInt($subMenu.height()) * -1;
						$subHolder.animate({top: top},500); 
						break;
					default:
						top = parseInt($subMenu.height()) * -1;
						$subHolder.animate({top: top},500); 
						break;
			
				}
				
				$subHolder.queue(function () {
					$(this).parent().hide();
					$(this).dequeue();
				});
					
			}//end animateSubMenuHolderOut
			
			/*-------------------L3 FUNCTIONS--------------------*/
			
			function positionL3Menu($menuButton, $subMenu){
				var offset = $menuButton.getTopLeft();
				var parentOffset = $menuButton.parent().parent().getTopLeft();
				var top = 0;
				var left = 0;
				//the only one done so far is down, up, and horizontal. right and left are very very wrong!
				switch (options.direction){
				case "up":
					top = parseInt(offset.top) + parseInt(parentOffset.top);
					left = parseInt(offset.left) + parseInt(parentOffset.left) + $menuButton.width();	
					break;
				case "down":
					top = parseInt(offset.top) + parseInt(parentOffset.top);
					left = parseInt(offset.left) + parseInt(parentOffset.left) + $menuButton.width();	
					break;
				case "left":
				case "right":			
					top = parseInt(offset.top) + parseInt(parentOffset.top);
					left = parseInt(offset.left) + parseInt(parentOffset.left) + $menuButton.width();	
					break;
				case "horizontal":
					top = parseInt(offset.top) + parseInt(parentOffset.top) + $menuButton.height();
					left = parseInt(offset.left) + parseInt(parentOffset.left);
					break;
				default:
					top = parseInt(offset.top) + parseInt(parentOffset.top);
					left = parseInt(offset.left) + parseInt(parentOffset.left) + $menuButton.width();
					break;
				}
				$subMenu.css("top", top+"px");
				$subMenu.css("left", left+"px");
			}//end positionL3Menu
			
			function positionL3MenuHolder($subMenu){
				var top = 0;
				var left = 0;
				switch (options.direction){
					case "up":
						top = 0;
						left = 0 - $subMenu.width();
						break;
					case "down":
						top = 0;
						left = 0 - $subMenu.width();
						break;
					case "right":
						top = 0;
						left = 0 - $subMenu.width();
						break;
					case "left":
						top = 0;
						left = $subMenu.width() * 2; 
						break;
					case "horizontal":
						top = $subMenu.height() * -1;
						left = 0;
						break;
					default:
						top = 0;
						left = 0 - $subMenu.width();
						break;
				}
				var $subMenuHolder = $subMenu.children("#holder");
				$subMenuHolder.css("top",top).css("left",left).css("position","relative");
			}//end positionL3MenuHolder
			
			function animateL3HolderIn(pageid){
				var $menuButton = $("#L2Item"+menuid+"_"+pageid);
				var $subMenu =  $("#L3"+menuid+"_" + pageid);
				var $subHolder = $("#L3"+menuid+"_" + pageid+" div:first");
				var top = 0;
				var left = 0;
				
				positionL3Menu($menuButton, $subMenu);
				
				$menuButton.addClass("on");
				$subHolder.queue("fx", []).stop();
				$subMenu.show().css("z-index",1000);
				switch (options.direction){
					case "up":
						$subHolder.animate({left: 0},500);
						break;
					case "down":
						$subHolder.animate({left: 0},500);
						break;
					case "left":
					case "right":
						$subHolder.animate({left: 0},500);
						break;
					case "horizontal":
						$subHolder.animate({top: 0},500);
						break;
					default:
						$subHolder.animate({left: 0},500);
						break;
				}
			}//end animateL3HolderIn
			
			function animateL3HolderOut(pageid,animate){
				//checks to see if i need to animate the L3s or just hide them
				animate = typeof(animate) != 'undefined' ? animate : true;
								
				var $menuButton = $("#L2Item"+menuid+"_"+pageid);
				var $subMenu =  $("#L3"+menuid+"_" + pageid);
				var $subHolder = $("#L3"+menuid+"_" + pageid+" div:first");
				var top = 0;
				var left = 0;
				
				$menuButton.removeClass("on");
				$subMenu.css("z-index",500);
				$subHolder.queue("fx", []).stop();
				switch (options.direction){
					case "up":		
						left = 0 - parseInt($subMenu.width());
						//figure out a cleaner way to do this....
						if(animate){
							$subHolder.animate({left: left},500);
						}else{
							$subHolder.css("left",left+"px");
						}
						break;
					case "down": 
						left = 0 - parseInt($subMenu.width());
						//figure out a cleaner way to do this....
						if(animate){
							$subHolder.animate({left: left},500);
						}else{
							$subHolder.css("left",left+"px");
						}
						break;
					case "right":
						left = 0 - parseInt($subMenu.width());
						//figure out a cleaner way to do this....
						if(animate){
							$subHolder.animate({left: left},500);
						}else{
							$subHolder.css("left",left+"px");
						}
						break;
					case "left":
						left = parseInt($subMenu.width()) * 2;
						$subHolder.animate({left: left},500);
						break;
					case "horizontal":
						top = parseInt($subMenu.height()) * -1;
						if(animate){
							$subHolder.animate({top: top},500);
						}else{
							$subHolder.css("top",top+"px");
						}
						break;
					default:
						left = 0 - parseInt($subMenu.width());
						//figure out a cleaner way to do this....
						if(animate){
							$subHolder.animate({left: left},500);
						}else{
							$subHolder.css("left",left+"px");
						}
						break;
			
				}
				$subHolder.queue(function () {
					$(this).parent().hide();
					$(this).dequeue();
				});	
			}//end animateL3HolderOut
			
		});//end return this.each function
	};//end menu function
})(jQuery);

(function($){
	var count = 0;
	jQuery.getNextID = function() {
		return count++;
	};
})(jQuery);

jQuery.txt = function() {
	return this.each(function(){
		$.log(this);
	});
};

//for debug/log stuff
jQuery.log = function(message) {
 if(window.console && $.browser.mozilla) {
 var str = message;

    if( typeof(message) == 'object' ){
				str = '&lt;';
				//str += message.nodeName.toLowerCase();
				for( var i = 0; i < message.attributes.length; i++ ){
					str += ' ' + message.attributes[i].nodeName.toLowerCase() + '="' + message.attributes[i].nodeValue + '"';
				}
				str += '&gt;';
			}
			console.debug(str);


 }
};
