/******************************************************************************
 * G L O B A L S **************************************************************
 *****************************************************************************/
 /** File: vegui.sk.dropdownmenu.js
   *
   * Allows you to integrate drop down navigation menus into your site
   * easily
   *
   * Dependencies:
   *
   *	<vegui.sk.std.js>
   *
   * Optional Depencencies for full functionality:
   *
   *	<vegui.sk.ani.js>, <vegui.sk.ani.morph.js>, <vegui.sk.ani.fade.js>,
   *	<vegui.sk.ani.shadow.js>
   *
   */

var VSK_MENU_TIMER = 0;

/** Constant: VSK_MENU_CLOSE_TIME
  * Time it takes for a menu to close after the mouse pointer has left it (ms)
  * , default = 1000 ms (1 sec)
  */

var VSK_MENU_CLOSE_TIME = 1000;

/*****************************************************************************/
/** Function: ddmnu_init
  * Initialize one or more drop down menues by submitting one or more node
  * ids to the function.
  *
  * Parameters:
  *
  *	array menus - array holding menu node ids of menus that you want
  *	to initialize
  *	int nMarg - margin between nested menus and their parent menu (px)
  *	<string useFx> - define which effect to use for menu opening
  *	<int fxTime> - time of the menu opening effect (ms)
  *	<bool shad> - if true the shadow affect (<vegui.sk.ani.shadow.js>) will
  *	be applied to each menu
  *	<int shadX> - x offset of the shadow (px)
  *	<int shadY> - y offset of the shadow (px)
  *	<string shadC> - color of the shadow (valid css color string)
  *	<int shadT> - shadow transparency (1-100)
  *
  * useFX values:
  *
  *	'fade' - fade effect of <vegui.sk.ani.fade.js> is used
  *	'morph' - morph effect of <vegui.sk.ani.morph.js> is used
  *	null - no effect us used
  *
  */

function ddmnu_init(menus, nMarg, useFx, fxTime, shad, shadX, shadY, shadC, shadT) {
  var i,m,O,o,n;
  for(i = 0; i < menus.length; i++) {
    
    if(!(m = V(menus[i])))
      continue;


    /* make sure the menu starts out hidden */

    m.s.visibility = 'hidden';
    m.s.display = 'inline';
    m.set_pos('absolute', 1000);
    m.b.vskMenuFriends = menus;

    /* set up the onmouseout event to trigger the closing of the menu */

    m.b.onmouseout = function(e) {
      var m = v(this), rt = vsk_rel_target(e || event);
      if(v(rt).has_parent(m.b) || rt == this)
        return;
      m.b.vskMenuFocus = false;
      if(this.vskParentMenu && (rt == this.vskParentMenu.b || v(rt).has_parent(this.vskParentMenu.b)))
        this.vskParentMenu.b.vskMenuFocus = true;
      if(this.vskOpenMenu && (v(rt).has_parent(this.vskOpenMenu.b) || rt == this.vskOpenMenu.b))
        return;
      VSK_MENU_TIMER = clearTimeout(VSK_MENU_TIMER);
      VSK_MENU_TIMER = setTimeout(function() {m.ddmenu_close()}, 1000);
    };

    m.b.onmouseover = function(e) {
      var m = v(this);
      m.b.vskMenuFocus = true;
    };
    
    m.b.vskUseFx = useFx;
    m.b.vskFxTime = fxTime;
    m.dock(document.body);

    /* apply shadow if needed */

    if(shad) {
      m.fx_shadow(shadT, shadC, shadX, shadY);
    }
 
    /* collect menu options */

    O = m.b.getElementsByTagName('a');
     
    /* set up sub menu links */
    
    for(n = 0; n < O.length; n++) {
      o = v(O[n]), c = m.b.className;
      o.b.vskParentMenu = m;
      o.s.cursor = 'pointer';
      o.s.display = 'block';
      o.s.whiteSpace = 'nowrap';
      o.b.className = c+'_item';

      if(o.b.getAttribute('vsk_nested')) {
        o.b.onmouseover = function() {
	  this.className = c+'_item_hover';
	  var M = this.getAttribute('vsk_nested');
	  var y = v(this).y();
	  var a = this.getAttribute('vsk_align') || 'r';
	  V(M).b.vskParentMenu = this.vskParentMenu;
	  if(this.vskParentMenu.b.vskOpenMenu) {
	    if(this.vskParentMenu.b.vskOpenMenu.b != V(M).b)
	      this.vskParentMenu.b.vskOpenMenu.ddmenu_close();
            else
	      return;
	  }
	  if(a == 'r') 
	    this.vskParentMenu.ddmenu_open(M, 'r', -nMarg, y);
	  else
	    this.vskParentMenu.ddmenu_open(M, 'l', nMarg, y);
	  this.vskParentMenu.b.vskOpenMenu = V(M);
	}
      } else {
        o.b.onmouseover = function() { this.className = c+'_item_hover'; };
      }

      o.b.onmouseout = function() { this.className = c+'_item'; };
    
    }
    
  }
}

/******************************************************************************
 ** E X T E N D  V S K  N O D E ***********************************************
 *****************************************************************************/
 /** Class: VSK_Node */

/*****************************************************************************/
/** Method: ddmenu_open
  * Opens an existing drop down menu and aligns it to the element
  *
  * Parameters:
  *
  *	var id - node id of the drop down menu
  *	string align - defines how the dropdown menu is aligned to the
  *	element
  *	<int x> - x offset (px)
  *	<int y> - y offset (px)
  *
  * Align Values:
  *
  *	'b' - bottom alignment, menu will be opened below element
  *	't' - top alignment, menu will be opened above element
  *	'l' - left alignment, menu will be openend on the left side of the
  *	element
  *	'r' - right alignment, menu will be openend on the right side of the
  *	element
  *
  * See Also:
  *
  *	<ddmenu_close>
  *
  * Returns:
  *
  *	VSK_Node - self
  */

VSK_Node.prototype.ddmenu_open = function(id, align, x, y) {
  var m = V(id);
  if(!m.b)
    return this;

  /* if menu is already opening bail */
  
  if(m.fx_active('morph'))
    return this;

  VSK_MENU_TIMER = clearTimeout(VSK_MENU_TIMER);
  
  /* if menu is a root menu (it has no parent menus) check it's
   * befriended menus and close them
   */

  if(!m.b.vskParentMenu && m.b.vskMenuFriends) {
    var i;
    for(i = 0; i < m.b.vskMenuFriends.length; i++) {
      if(i == id || V(m.b.vskMenuFriends[i]).b.vskParentMenu)
        continue;
      V(m.b.vskMenuFriends[i]).ddmenu_close(1);
    }
  }
  
  var par = m.b.vskParentMenu;
  while( par ) {
    if(!par.v())
      return this;
    par = par.b.vskParentMenu;
  }
  
  if(!x)
    var x =0;
  if(!y)
    var y =0;
  
  switch(align) {
    case 'b': 
      m.move(this.abs_x()+x, this.abs_y()+this.h()+y);
    break;
    case 'r':
      m.move(this.abs_x()+this.w()+x, this.abs_y()+y);
    break;
    case 'l':
      m.move((this.abs_x()-m.w())+x, this.abs_y()+y);
    break;
    case 't':
      m.move(this.abs_x()+x, (this.abs_y()-m.h()) + y);
    break;
  }
  
  /* make menu visible, dont use hide() method to do so because
   * it only deletes the visibility property
   */

  m.s.visibility = 'visible';
  
  if(m.b.vskUseFx) {
    if(m.b.vskUseFx == 'fade') {
      m.fade(1).fx_fade_in(m.b.vskFxTime);
    } else if(m.b.vskUseFx == 'morph') {
      m.s.overflow = 'hidden';
      m.s.padding = '0px';
      var w = m.w(), h = m.h(), oX = m.x(), oY = m.y();
      m.resize(1,1).fx_morph(w,h,oX,oY,m.b.vskFxTime).onhalt = function() {
        m.s.height = '';
	m.s.padding = '';
      };
    }
  }

  
  return this;
};

/*****************************************************************************/
/** Method: ddmenu_close
  * Close menu and all open nested menus
  *
  * Parameters:
  *
  *	<bool force> - force closing
  *
  * Returns:
  *
  *	VSK_Node - self
  */

VSK_Node.prototype.ddmenu_close = function(force) {
  
  VSK_MENU_TIMER = clearTimeout(VSK_MENU_TIMER);
  var m = this;
  
  while( m.b.vskOpenMenu )
    m = m.b.vskOpenMenu;

  if(!m)
    return this;

  while( m ) {
    if(m.b.vskMenuFocus && !force)
      break;
    m.hide(1);
    if( (m = m.b.vskParentMenu) )
      m.b.vskOpenMenu = null;
  }
  
  return this;
};
