// vim: set fdm=marker encoding=utf-8:

/**
 * NSF
 *
 * LICENSE
 *
 * Dr. Maté GmbH License ?
 *
 * @category	Nsf
 * @package		Nsf.Effects
 * @copyright	(c) 2007 by Dr. Maté GmbH
 * @license		http://www.netdoktor.at/license/
 * @author		Thomas Subera <thomas.subera@gmail.com>
 * @version		$Id: nsf.effects.js 8790 2009-03-09 10:47:38Z soestreicher $
 */

if (!window.nsf) {
	nsf = {
	}
}

/**
 * nsf Effects Class
 */
nsf.Effects = { // {{{
	/*
	 * Menu Effects
	 */
	Menu : { // {{{
		/*
		 * Blind Menu Effects
		 */
		Blind : { // {{{
			/*
			 * Simple Blind Up/Down Effect used first in
			 * oegp.at
			 *
			 * It uses an list system like this example:
			 * <div id="mainmenu">
			 *	<ul>
			 *		<li class="sub">
			 *			<a href="#">MenuTitle</a>
			 *			<div style="display: none;">
			 *				<ul>
			 *					<li><a href="#">Title</a></li>
			 *				</ul>
			 *			</div>
			 *		</li>
			 *
			 * WARNING: is a global Effect, there cannot be used more than one
			 * per document.
			 */
			Simple : { // {{{
				/*
				 * Defines how the Css Class is called if
				 * there is a submenu.
				 */
				sCssSubMenu : 'sub',
				/*
				 * Defines how the Css Class is called if
				 * the submenu is open.
				 */
				sCssOpen : 'open',
				/*
				 * Defines how long the menu will appear open
				 * before it closes.
				 */
				iDelay : 0.5,
				/*
				 * Close Menu's that are open at setup time?
				 */
				bCloseActive : false,
				/*
				 * Defines how the Css Class is called if
				 * the submenu is active.
				 */
				sCssActive : 'on',
				/*
				 * Duration Speed for Up
				 */
				iDurationUp : 0.5,
				/*
				 * Duration Speed for Down
				 */
				iDurationDown : 0.5,
				/*
				 * Mouseout on Single Element (li) or the whole Menu Div
				 */
				bSingle : false,
				/*
				 * Save Mouseout from Single Elements when mouseout event from
				 * Menu Div occurs.
				 */
				aElements : new Array(),
				/*
				 * Setup
				 */
				Setup : function(domLi, domMenu) { // {{{
					if (nsf.Effects.Menu.Blind.Simple.bCloseActive == false
						&& domLi.className == nsf.Effects.Menu.Blind.Simple.sCssActive) {
						return;
					}
					/*
					 * Check for submenus
					 */
					// do we have a submenu? else ignore everything
					// get submenu div
					var domDiv = domLi.getElementsByTagName('div')[0] || false;
					if (domDiv == false) {
						return;
					}

					/*
					 * Save vars we need later
					 */
					// save it in the element so we can get it later fast
					domLi._domDiv = domDiv;
					// set menu state
					domLi._sState = 'up';
					// save height if we cancel an effect
					domDiv._iOrigHeight = Element.getHeight(domDiv);
					domDiv.style.height = 0;

					// Set Mouseout for Single Element?
					if (nsf.Effects.Menu.Blind.Simple.bSingle) {
						domLi._oParent = domLi;
						var aChildren = domLi.getElementsByTagName('*');
						for (var i=0, l=aChildren.length; i<l; i++) {
							aChildren[i]._oParent = domLi;
						}

						domLi.onmouseout = nsf.Effects.Menu.Blind.Simple.Up;
						domLi.onblur = nsf.Effects.Menu.Blind.Simple.Up;
					} else {
						// Set Mouseout for Menu Div
						domLi._onUp = nsf.Effects.Menu.Blind.Simple.Up;

						if (domMenu._set != true) {
							domMenu._oParent = domMenu;
							var aChildren = domMenu.getElementsByTagName('*');
							for (var i=0, l=aChildren.length; i<l; i++) {
								aChildren[i]._oParent = domMenu;
							}
							
							Event.observe(domMenu, 'mouseout', nsf.Effects.Menu.Blind.Simple.MenuOut);
							domMenu._set = true;
						}
					}

					domLi.onmouseover = nsf.Effects.Menu.Blind.Simple.Down;
					domLi.onfocus = nsf.Effects.Menu.Blind.Simple.Down;
				}, // }}}
				/*
				 * Open Menu (onmouseover)
				 */
				Down : function() { // {{{
					// if we are in the middle of blindUp cancel Effect
					// and set state to down so the BlindDown Effect will be
					// applied.
					if (this._sState == 'blindUp') {
						this._Effect.cancel();
						this._sState = 'up';
					}
					// if menu is not closed stop right here
					if (this._sState != 'up') {
						return;
					}
					// save element for closure
					var domLi = this;
					// set the startpoint in percent
					this._domDiv._scaleFrom = Math.round((parseInt(this._domDiv.style.height)/this._domDiv._iOrigHeight) * 100);

					nsf.Effects.Menu.Blind.Simple.aElements.push(domLi);

					// Start BlindDown Effect with Callbacks which set the
					// states
					this._Effect = Effect.BlindDown(
						this._domDiv,
						{
							beforeStart : function() {
								domLi._sState = 'blindDown';
								domLi.className = nsf.Effects.Menu.Blind.Simple.sCssOpen;
							},
							afterFinish : function() {
								domLi._sState = 'down';
							},
							duration : nsf.Effects.Menu.Blind.Simple.iDurationDown,
							// Additional Parameters
							scaleFrom: this._domDiv._scaleFrom,
							scaleMode: {originalHeight: this._domDiv._iOrigHeight, originalWidth: Element.getWidth(this._domDiv)},
							restoreAfterFinish: false
						}
					);
				}, // }}}
				/*
				 * Close Menu (onmouseout)
				 */
				Up : function(ev) { // {{{
					if (nsf.Effects.Menu.Blind.Simple.bSingle) {
						if (nsf.Effects.Menu.Blind.Simple.MouseOut(ev) == false) {
							return;
						}
					}
					// if we are in the middle of blindDown cancel Effect
					// and set state to down so the BlindUp Effect will be
					// applied.
					if (this._sState == 'blindDown') {
						this._Effect.cancel();
						this._sState = 'down';
					}
					// if menu is not open stop right here
					if (this._sState != 'down') {
						return;
					}
					// save element for closure
					var domLi = this;

					// Start BlindUp Effect with Callbacks
					this._Effect = Effect.BlindUp(
						this._domDiv,
						{
							beforeStart : function() {
								domLi._sState = 'blindUp';
							},
							afterFinish : function() {
								domLi._sState = 'up';
								domLi._domDiv.style.height = 0;
								domLi.className = nsf.Effects.Menu.Blind.Simple.sCssSubMenu;
							},
							duration : nsf.Effects.Menu.Blind.Simple.iDurationUp,
							delay : nsf.Effects.Menu.Blind.Simple.iDelay
						}
					);
				}, // }}}
				/*
				 * MouseOut function 
				 */
				MouseOut : function (ev) { // {{{
					var el = ev.target || ev.srcElement;
					el = el._oParent;
					var aOffset = Position.realOffset(el);
					Position.prepare(el);
					if (Position.withinIncludingScrolloffsets(el, ev.clientX+aOffset[0], ev.clientY+aOffset[1])) {
						return false;
					}
					return true;
				}, // }}}
				/*
				 * Menu Out (onmouseout)
				 */
				MenuOut : function (ev) { // {{{
					if (nsf.Effects.Menu.Blind.Simple.MouseOut(ev) == false) {
						return;
					}
					if (nsf.Effects.Menu.Blind.Simple.aElements.length == 0) {
						return;
					}
					for (var i=0,l=nsf.Effects.Menu.Blind.Simple.aElements.length; i<l; i++) {
						nsf.Effects.Menu.Blind.Simple.aElements[i]._onUp();
					}
				} // }}}
			} // }}}
		} // }}}
	} // }}}
} // }}}
