(function($){
	$.fn.menu = function(options) {
		var defaults = {
			xml_path:"/xml/default.asp",
			direction:"down",
			hOffset:0,
			vOffset:0,
			currentL1:0,
			speed:500,
			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);
			if(options.sid != undefined){
				buildMenus();
			}else{
				if(options.debug){$.log("School ID is not set.");}
			}//end if(sid)
			
			if(options.speed == 0){
				options.speed = 1;
			}
			
			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"));
							
							var L1id = $(this).attr("tid");
							if(L1id == options.currentL1){
								$("#"+$menuHolder.attr("id")+"_"+L1id).addClass("on");
							}
							
							var $subMenu;
							var $linkHolder;
							var hasL2s = false;					
							
							$(this).find("L2").each(function(i){
								if(!hasL2s){
									$menuHolder.after("<div id='L2"+menuid+"_"+L1id+"' class='submenu"+options.direction+"'></div>");
									$subMenu = $("#L2"+menuid+"_" + L1id);
									$linkHolder = $("<div class='link-holder'></div>");
									$subMenu.append($linkHolder);
									$subMenu.css("display","none");
								}
								
								var target = $(this).find('target:first').text() == true ? "_blank":"_self";
																							
								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(){							
									//check for L3s
									var pageid = $(this).attr("id").split("_")[1];
									animateAllL3Out(pageid);
									if($("#L3"+menuid+"_"+pageid).length > 0){
										animateL3HolderIn(pageid);
									}
									
								},function(){
									//empty now, yay
								});
								
								//append new L2
								$linkHolder.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);
									    	if(options.debug){$.log("CLEARED TIMEOUT");}
									    },function(){
									    	dataStore.currentActive = 0;
									    	dataStore.timeout = setTimeout(function(){ animateAllOut()}, 100);
									    	if(options.debug){$.log("L3 OUT!");}
									    });
									    
										//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);
									}
								}
								hasL2s = true;
							});//end find L2s
							//get the right offsets....
							if(hasL2s){
								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;
								    	}
								    }
								}
									$linkHolder.children(":first").addClass('first-link');
									$linkHolder.children(":last").addClass('last-link');
								
								
								$linkHolder.hover(function(){
									dataStore.currentActive = L1id;
									clearTimeout(dataStore.timeout);
								},function(){
								    dataStore.currentActive = 0;
								    dataStore.timeout = setTimeout(function(){ animateAllOut()}, 100);
								    if(options.debug){$.log("L2 HOLDER OUT");}
								});
							
								
									
								$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"){						
									/*
									$linkHolder.html($linkHolder.children().get().reverse());
									
									$linkHolder.children().hover(function(){							
										//check for L3s
										var pageid = $(this).attr("id").split("_")[1];
										animateAllL3Out(pageid);
										if($("#L3"+menuid+"_"+pageid).length > 0){
											animateL3HolderIn(pageid);
										}
										
									},function(){
										//empty now, yay
									});								
									*/
								}
								
								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);
								});
								
								//=========start test
								
								var $tempMenuItems = $itemHolder.children().filter(function(){  
								    return $(this).attr("id") != "menu-header" || $(this).attr("id") != "menu-footer";
								});
								
								if(options.debug){$.log("tempx = " + $tempMenuItems.length);}
								
								$tempMenuItems.filter("div:first").addClass("menufirst");							
								
								var mylength = $itemHolder.children().filter(function(){  
								    return $(this).attr("id") != "menu-header" || $(this).attr("id") != "menu-footer";
								}).length;
								if(options.debug){$.log("childrenx : "+mylength);}
								
								//====================end test
								
								$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);
					$obj.data("pageID",$(this).attr("id").substring($menuHolder.attr("id").length+1,$(this).attr("id").length));
				});
				
				$menuItems.hover(function () {
					killCurrentL2();
					
					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);
				if(options.debug){$.log("SPEED:" + options.speed);}
				//alert(options.direction);
				switch (options.direction){
					case "up":
						$subHolder.animate({top: 0},options.speed);
						break;
					case "down":
						$subHolder.animate({top: 0},options.speed);
						//$subHolder.css("top",0);
						break;
					case "left":
					case "right":
						$subHolder.animate({left: 0},options.speed);
						break;
					case "horizontal":
						$subHolder.animate({top: 0},options.speed);
						break;
					default:
						$subHolder.animate({top: 0},options.speed);
						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",options.speed);
				$subHolder.queue("fx", []).stop();
				switch (options.direction){
					case "up":
						top = $subMenu.height();
						$subHolder.animate({top: top},options.speed);
					break;
					case "down":
						top = parseInt($subMenu.height()) * -1;
						$subHolder.animate({top: top},options.speed); 
						//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},options.speed);
					break;
					case "left":
						left = parseInt($subMenu.width()) * 2;
						$subHolder.animate({left: left},options.speed);
					break;
					case "horizontal":
						top = parseInt($subMenu.height()) * -1;
						$subHolder.animate({top: top},options.speed); 
						break;
					default:
						top = parseInt($subMenu.height()) * -1;
						$subHolder.animate({top: top},options.speed); 
						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().parent();
				if(options.debug){$.log(parentOffset.top +" : "+offset.top);}
				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.css("top"));
					left = parseInt(offset.left) + parseInt(parentOffset.css("left")) + $menuButton.width();	
					break;
				case "down":
					top = parseInt(offset.top) + parseInt(parentOffset.css("top"));
					left = parseInt(offset.left) + parseInt(parentOffset.css("left")) + $menuButton.width();	
					break;
				case "left":
				case "right":			
					top = parseInt(offset.top) + parseInt(parentOffset.css("top"));
					left = parseInt(offset.left) + parseInt(parentOffset.css("left")) + $menuButton.width();	
					break;
				case "horizontal":
					top = parseInt(offset.top) + parseInt(parentOffset.css("top")) + $menuButton.height();
					left = parseInt(offset.left) + parseInt(parentOffset.css("left"));
					break;
				default:
					top = parseInt(offset.top) + parseInt(parentOffset.css("top"));
					left = parseInt(offset.left) + parseInt(parentOffset.css("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},options.speed);
						break;
					case "down":
						$subHolder.animate({left: 0},options.speed);
						break;
					case "left":
					case "right":
						$subHolder.animate({left: 0},options.speed);
						break;
					case "horizontal":
						$subHolder.animate({top: 0},options.speed);
						break;
					default:
						$subHolder.animate({left: 0},options.speed);
						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",options.speed);
				$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},options.speed);
						}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},options.speed);
						}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},options.speed);
						}else{
							$subHolder.css("left",left+"px");
						}
						break;
					case "left":
						left = parseInt($subMenu.width()) * 2;
						$subHolder.animate({left: left},options.speed);
						break;
					case "horizontal":
						top = parseInt($subMenu.height()) * -1;
						if(animate){
							$subHolder.animate({top: top},options.speed);
						}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},options.speed);
						}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);


 }
};