var laf = new Object();

/*
 *  laf.LSlideMenu 
 */
laf.LSlideMenu = function (rootUL, slideStepSize, slidePixel, sync) {
	if (typeof(rootUL) == "string") rootUL = document.getElementById(rootUL);
	
	this.menuItems = new Array();
	this.menuIndex = -1;
  this.foldedMenuIndex = -1;
	this.sync = sync;
	
	// this is callback from close action
	this.onStateChange = function(state, slideMenuObj) {
		if (state == 4 && slideMenuObj.foldedMenuIndex != slideMenuObj.menuIndex) {
		  slideMenuObj.menuItems[callbackArgs.menuIndex].slideObj.slide();
		  slideMenuObj.menuItems[callbackArgs.menuIndex].SPAN.className = "Lopen";
		  slideMenuObj.unfoldedMenuIndex = slideMenuObj.menuIndex;
  	}
	}
	
	// make menu items
	var cnt = 0;
	for (var i=0; i<rootUL.childNodes.length; i++) {
    if (rootUL.childNodes[i].tagName == "LI") {
	    var SPAN = rootUL.childNodes[i].getElementsByTagName("SPAN")[0];
	    var UL = rootUL.childNodes[i].getElementsByTagName("UL")[0];
	    var callback = (sync) ? this.onStateChange : null;
	    var callbackArgs = this;
	    var slideObj = new laf.LSlide(UL, slideStepSize, slidePixel, callback, callbackArgs);
    	this.menuItems[cnt] = new laf.LSlideMenuItem(SPAN, UL, slideObj, cnt);
      SPAN.slideMenu = this;
      SPAN.index = cnt;
    	cnt++;
    }
	}
	
	// get unfolded menu index
	this.unfoldedMenuIndex = -1;
  for (var i=0; i<this.menuItems.length; i++) {
    if (this.menuItems[i].UL && this.menuItems[i].UL.style.display == "block") { this.unfoldedMenuIndex = i;}
	}
	
	this.change = function(menuIndex) {
		this.menuIndex = menuIndex;
		this.foldedMenuIndex = -1;
		if (this.unfoldedMenuIndex >= 0) { 
			this.menuItems[this.unfoldedMenuIndex].slideObj.close();
			this.menuItems[this.unfoldedMenuIndex].SPAN.className = "Lclosed";
			this.foldedMenuIndex = this.unfoldedMenuIndex;
			this.unfoldedMenuIndex = -1;
		}

		if (this.foldedMenuIndex < 0 || (this.foldedMenuIndex != menuIndex && !this.sync)) {  // if sync mode, callback is available.(set before)
			this.menuItems[menuIndex].slideObj.slide();
			this.menuItems[menuIndex].SPAN.className = "Lopen";
			this.unfoldedMenuIndex = menuIndex;
		}
  }	
  
  // attach onclick event to SPAN
	for (var i=0; i<this.menuItems.length; i++) {
  	this.menuItems[i].SPAN.onclick = function() {
  		this.slideMenu.change(this.index);
  	}
	}
}

laf.LSlideMenuItem = function (SPAN, UL, slideObj, index) {
	this.SPAN = SPAN;
	this.UL = UL;
	this.slideObj = slideObj;
	this.index = index;
}

/*
 *  laf.LSlide 
 */
laf.LSlide = function (element, slideStepSize, slidePixel, callback, callbackArgs) {
	this.slideElement = (typeof(element) == "string") ? document.getElementById(element) : element;
	this.slideStepSize = slideStepSize; // px
	this.slidePixel = slidePixel;
	this.slideTimer = null;
	this.slideHeight = 0;
	this.nowSlideHeight = 0;
	this.callback = callback;   // state def. : 0:none, 1:opening, 2:opened, 3:closing, 4:closed
  this.callbackArgs = callbackArgs;
	this.listIndex = laf.LSlide.list.length;
	laf.LSlide.list[this.listIndex] = this;
	
	this.change = function() {
  	if (this.slideElement.style.display == "none") this.slide();
  	else this.close();
	}
	
  this.slide = function() {
  	if (this.slideTimer) return;
		if (this.callback) this.callback(0, this.callbackArgs);
	 	var element = this.slideElement;
	 	var oldPosition = element.style.position;
	 	var oldVisibility = element.style.visibility;
	 	var oldDisplay = element.style.display;
	 	
    element.style.position = "absolute";  // absolute°¡ ¾Æ´Ò°æ¿ì È­¸é¿µ¿ªÀ» Â÷ÁöÇÏ°Ô µÊ
    element.style.visibility = "hidden";  // È­¸é¿¡ ¿µ¿ªÀ» Â÷ÁöÇÏ°Ô ÇÏ¿© ³ôÀÌ¸¦ ±¸ÇÔ
	 	element.style.display = "block";
	 	this.slideHeight = element.offsetHeight;
    element.style.position = oldPosition;
    element.style.visibility = oldVisibility;
    element.style.overflow = "hidden";    // ÁöÁ¤µÈ height¸¸Å­¸¸ º¸¿©Áöµµ·Ï ÇÔ
	 	element.style.height = "0px";
	 	element.style.display = "block";
	 	this.slideTimer = setInterval("laf.LSlide.list["+this.listIndex+"].slideOneStep()", this.slidePixel);
  }
  
  this.slideOneStep = function() {
	  this.nowSlideHeight += this.slideStepSize;
	  
    if (this.nowSlideHeight >= this.slideHeight) {
    	this.slideElement.style.height = this.slideHeight+"px";
    	this.stopSlide();
		  if (this.callback) this.callback(2, this.callbackArgs);
    } else {
	    this.slideElement.style.height = this.nowSlideHeight+"px";
		  if (this.callback) this.callback(1, this.callbackArgs);
    }
  }
  
  this.close = function() {
  	if (this.slideTimer) return;
		if (this.callback) this.callback(0, this.callbackArgs);
	 	this.nowSlideHeight = this.slideElement.offsetHeight;
    this.slideElement.style.overflow = "hidden";
	 	this.slideTimer = setInterval("laf.LSlide.list["+this.listIndex+"].closeOneStep()", this.slidePixel);
  }
  
  this.closeOneStep = function () {
	  this.nowSlideHeight -= this.slideStepSize;
	  
    if (this.nowSlideHeight <= 0) {
    	this.slideElement.style.height = "";
    	this.slideElement.style.display = "none";
    	this.stopSlide();
		  if (this.callback) this.callback(4, this.callbackArgs);
    } else {
	    this.slideElement.style.height = this.nowSlideHeight+"px";
		  if (this.callback) this.callback(3, this.callbackArgs);
    }
  }
  
  this.stopSlide = function() {
	  clearInterval(this.slideTimer);
	  this.slideTimer = null;
	  this.nowSlideHeight = 0;
  }
} 

laf.LSlide.list = new Array();


