/**
 * AUDI JavaScript library: core
 * 
 * @projectDescription	Animation class handling the iphone like behaviour on distribution pages
 * @namespace			animation.slideDistributor
 *
 * @author 				$Author: hhoettecke $
 * @version				$Revision: 5674 $
 * @copyright			NEUE DIGITALE GmbH, Berlin
 * 
 * @jslint: 2008-10-31
 * 
 * @TODO	refactor
 * 
 * @file:				audi_ngw.animation.slideDistributor.js
 * $URL: https://svn.pvtool.org/svn/day_audi_ngw/trunk/ngw_base/frontend/js/audi/audi.animation.slideDistributor.js $
 */

/* create namespace */
audi_ngw.namespace(audi_ngw,'animation.slideDistributor');

/**
 * Set wrappers height to cummulated child height if necessary.
 * @method _balanceWrapperHeight
 * @private
 * @return {Void}
 */
audi_ngw.animation.slideDistributor._balanceWrapperHeight = function () {
	// construct selector
	var _sSelector = this._options.sIdWrapper;
	_sSelector += ' *';
	
	// get cumulated child node height
	var _iComputedHeight = jQuery(_sSelector).height();
	// compare wrapper's css height with needed height, balance if necessary
	if ( _iComputedHeight > jQuery(this._options.sIdWrapper).height()) {
		jQuery(this._options.sIdWrapper).height(_iComputedHeight);
	}
//	if (jQuery('#audi_content_wrapper').height()) {
//		jQuery(this._options.sIdWrapper).css('height', jQuery('#audi_content_wrapper').height() + 'px');
//	}
};

/**
 * Add Click events to navigation elements
 * @method _addClickEvents
 * @deprecated
 * @private
 * @return {Void}
 */
audi_ngw.animation.slideDistributor._addClickEvents = function () {
	// store reference
	var _self = this;
	// construct selector
	var _sSelector = this._options.sIdWrapper;
	_sSelector += ' ul li ';
	
	// add click event to first level navigation anchors
 	jQuery(_sSelector).parent('ul.first').children().children('a').click(function(event){
		_self.animate(this);
	});

	// add click event to second level navigation anchors
 	jQuery(_sSelector).parent('ul.second').children().children('a').click(function(event){
		_self.animate(this);
	});

	// add click event to third level navigation anchors
 	jQuery(_sSelector).parent('ul.third').children().children('a').click(function(event){
		_self.animate(this);
	});

};

/**
 *  Bridges _doAnimate: prevents default event action, construcots animation options (pixel, element)
 * @method animate
 * @param {Element} 
 
 * @return {Void}
 */
audi_ngw.animation.slideDistributor.animate = function(element){
	var scope = audi_ngw.animation.slideDistributor;
 
	// check for running animations
	if (scope.getRunning() === true) {return;}
	
	if (!scope._options) {
			audi_ngw.animation.slideDistributor.initialize({});
	}
	
	var _oFx = {};
	var _sSelector = '';
	if (element.length === 0) {
//		console.log('NO ELEMENT')
//			var scope = audi_ngw.animation.slideDistributor;
			// construct selector for animation element
			_sSelector =  scope._options.sIdWrapper;
			_sSelector +=" ul:first";
			
			// force display block on .viewport
			jQuery('.viewport').css('display', 'block');
			// set animation options for reset slide
			_oFx = {
				$elAnimate: jQuery(_sSelector),
				_iToDepth: 0,
				onComplete: 
					// set callback to initialize new slide
					function(){
					jQuery('.viewport').removeClass('viewport');
					// console.log('// SET VIEWPORT ')
					jQuery('ul.first').css('display','block').addClass('viewport');
					scope.unsetRunning(scope);
				}
			};
			// call jQuery.animate
			this._doTransformation(_oFx);
			_oFx.onComplete = null;
		return;
	}
	// stop default behaviour
//	event.preventDefault();
//	var scope = audi_ngw.animation.slideDistributor;
	// construct selector
	_sSelector =  scope._options.sIdWrapper;
	_sSelector +=" ul:first";
	// construct effect options
	_oFx = {
		$elAnimate: jQuery(_sSelector),
		curElement: element
	};
	// call animation 
	scope._doAnimate(_oFx);
};

/**
 * does sliding
 * @method _doAnimate
 * @param {Object} Animation options: element, left, 
 * @private
 * @return {Void}
 */
audi_ngw.animation.slideDistributor._doAnimate = function(oFx){
	// set scope
	var scope = this;
	// check for running animations
	if (scope.getRunning()  === true) {return;}

	// set running flag
	scope.setRunning(scope);

	// create jQuery object
	var $curElement = jQuery(oFx.curElement);

	// get depth to go to
 	oFx._iToDepth = this._getDesiredDepth($curElement);

	// nowhere to go
	if (oFx._iToDepth === false) {return;}
	
	// set callback
	oFx.onComplete = function(){
		// hide all second / third level ul's except my parents	
 
		jQuery(scope._options.sIdWrapper+' ul')
			.not($curElement.parents('ul'))
			.css('display','none');
		jQuery('.current').removeClass('current');
		$curElement.parents('li').addClass('current');
//		$curElement.parents('a').addClass('current');
//		$curElement.addClass('current');
// console.log('added CURRENT to ',$curElement.parents('li'),$curElement.parents('a'))
		jQuery('.viewport').css('display','block');
		// console.log(jQuery('.viewport')," => ",jQuery('.viewport').parents('ul'))

		scope._onComplete(scope);
	};
	
	// call jQuery.animate
	this._doTransformation(oFx);
	oFx.onComplete = null;
};
/**
 * Slides ul.first by calling jQuery.animate
 * @param {Object} Effect options
 * @return {Void}
 * @private
 */
audi_ngw.animation.slideDistributor._doTransformation = function (oFx) {
	// set scope
	var scope = this;

	audi_ngw.animation.slideDistributor.setRunning(scope);
	// calculate pixel
// console.warn("## DEPTH: ",+oFx._iToDepth )
	var iToPixel =  -1 * (oFx._iToDepth) * (this._options.iNavWidth);
	oFx.$elAnimate.animate(
		{
			left: iToPixel+'px'
		},
	'normal', 'swing', oFx.onComplete);
};

/**
 * Default jQuery.animate onComplete callback
 * @param {Object} scope
 * @return {Void}
 * @private
 */
audi_ngw.animation.slideDistributor._onComplete = function(scope){
	scope.unsetRunning(scope);

};


/**
 * Calculates navigation depth to show after animation has completed.
 * Several possibilities:
 * 	element has been clicked: it's part of the current visible naviagtion level.
 * 	action: hide all siblings, hide all hildrens, show, next level, set.viewport, slide down
 * 
 * 	element is part of a bookmark / history element. no click event has been dispatched & element ain't visible
 * 	- if element's parent."viewport", the element is part of the current branch and the current viewport is _above_ desired element. move down (slide left)
 * 	  action: hide all uls below.viewport, show all element's parent uls, set .viewport, slide down 
 *  - if element's child(rens)."viewport", the element is part of the current branch and the current viewport is _below_ the desired element. move up (slide right)
 * 	  action: show all element's parent uls, hide all siblings.next uls, set .viewport, slide up, hide all element's children uls
 *	- else the element is part of another branch. reset slide navigation and repeat the whole animation process.
 *	  action: slide to 0, set viewport to first, hide all uls except elements parents, return depht on complete
 * @param {HTMLElement} element
 * @private
 * @return {Number || Bool}
 */
// problem: someone opens a bookmark on the bookmarked page => will be handeld as a click event 
audi_ngw.animation.slideDistributor._getDesiredDepth = function (element) {
 	var scope = audi_ngw.animation.slideDistributor;
	// create jQuery object 
	var $element = jQuery(element);

	// console.log("viewport: ", jQuery('.viewport'),' => ',($element).parents('.viewport'),"<- PARENTS ",$element," CHILDREN ->",($element).next('.viewport'),($element).next().children('viewport'), ($element).next().children().children('.viewport'))

 	// current elements parent ain't visible
//	 console.info("visible:",$element.parent().parent().hasClass('viewport'), $element.parent().parent(),'.hasClass(\'.viewport\')',$element.parent().parent().hasClass('viewport'))
 	if ( $element.parent().parent().hasClass('viewport') === false) {
//		 console.warn('-> not visible (no click)')
// console.log("first",$element.parents('ul.first').length ," second",$element.parents('ul.second').length ," third",$element.parents('ul.third').length)
		// element is part of the same branch, current viewport is above target element, move down
		if (($element).parents('.viewport').length !== 0) {
			// console.log('--> same tree, PARENT has.viewport get depth, slide left ')
			// hide all second / third level ul's except my parents	
//			jQuery('ul').not($element.parents('ul')).css('display','none')
			
			jQuery(scope._options.sIdWrapper+' ul').not($element.parents('ul')).css('display','none');
			// show parents ul
			$element.parents('ul').css('display', 'block');
			// remove .viewport
			jQuery('.viewport').removeClass('viewport');
			// show nessecary parents, add class viewport 
			$element.parent().parent().css('display', 'block').addClass('viewport');
//			// console.log("element: ", $element, " added viewport to: ", $element.parent().parent(), " successfull: ", $element.parent().parent().hasClass('viewport'))
// show parents
			$element.parents('ul').css('display', 'block');
			// show next level ul
			$element.next('ul').css('display', 'block');
			// remove class viewport
			jQuery('.viewport').removeClass('viewport');
			// show nessecary sibling, add class viewport
			$element.next().css('display', 'block').addClass('viewport');
			// return animation depth
			if ($element.parents('ul.third').length !== 0) {
				return 2;
			}
			if ($element.parents('ul.second').length !== 0) {
				return 2;
			}
			if ($element.parents('ul.first').length !== 0) {
				return 1;
			}
		}
		// part of the same branch, current viewport is below target element , move up
		else if ( ($element).next('.viewport').length !== 0 || ($element).next().children('.viewport').length !== 0 || ($element).next().children().children('.viewport').length !== 0) {
			// console.log($element,'--> same tree, CHILDREN has.viewport get depth, slide right ')
			// hide all second level ul's except my parents, don't hide third level elements due to animation 
			jQuery('.second').not($element.parents('ul')).css('display','none');
			// show parents
			$element.parents('ul').css('display', 'block');
			// show next level ul
			$element.next('ul').css('display', 'block');
			// remove class viewport
			jQuery('.viewport').removeClass('viewport');
			// show nessecary sibling, add class viewport
			$element.next().css('display', 'block').addClass('viewport');
 // console.log("element: ", $element, " added viewport to: ", $element.next(), " successfull: ", $element.next().hasClass('viewport'))
			
			// return animation depth 

			if ($element.parents('ul.third').length !== 0) {
				return 3;
			}
			if ($element.parents('ul.second').length !== 0) {
				return 2;
			}
			if ($element.parents('ul.first').length !== 0) {
				return 1;
			}
		}
		// element is part of another branch
		else {
			// console.log('--> another tree')
			// console.log('---> go to level 0')
			// set scope 
//			var scope = audi_ngw.animation.slideDistributor;

			// hide all second / third level ul's except my parents	
			jQuery('ul.second').not($element.parents('ul')).css('display','none');
			jQuery('ul.third').not($element.parents('ul')).css('display','none');

			// construct selector for animation element
			var _sSelector =  scope._options.sIdWrapper;
			_sSelector +=" ul:first";
			
			// force display block on .viewport
			jQuery('.viewport').css('display', 'block');
			// set animation options for reset slide
			var _oFx = {
				$elAnimate: jQuery(_sSelector),
				_iToDepth: 0,
				onComplete: 
					// set callback to initialize new slide
					function(){
					// show next step ul 
					jQuery(scope._options.sIdWrapper+' ul').not($element.parents('ul')).css('display','none');
//					jQuery('ul').not($element.parents('ul')).css('display','none');
					jQuery('.viewport').removeClass('viewport');
					$element.parents('ul.first').css('display','block').addClass('viewport');
 // console.log("element: ",$element," added viewport to: ",$element.parents('ul.first')," successfull: ",$element.parents('ul.first').hasClass('viewport'))
					// console.log('slide again')
					scope.unsetRunning(scope);
					audi_ngw.animation.slideDistributor.animate($element);
				}
			};
			// call jQuery.animate
			this._doTransformation(_oFx);
			_oFx.onComplete = null;

//			// construct effect options
//			var oFx = {
//				$elAnimate: jQuery(_sSelector)
//			}
//						oFx.$elAnimate.animate({
//							left: 0+ 'px'
//						}, 'normal', 'swing', function () {
							//// show next step ul 
							//jQuery('.viewport').removeClass('viewport');
							//$element.parents('ul.first').css('display','block').addClass('viewport');
							//console.log("element: ",$element," added viewport to: ",$element.parents('ul.first')," successfull: ",$element.parents('ul.first').hasClass('viewport'))
							//			console.log('slide again')
							//			scope.unsetRunning(scope);
							//audi_ngw.animation.slideDistributor.slide($element);
			//			}
//			)
			return false;
		}
	}
	// element ist visible, should be a click event
	else {
//		console.warn('-> click')
		// hide all uls
		jQuery(scope._options.sIdWrapper+' ul').not($element.parents('ul')).css('display','none');
		// force block on parents ul 
		$element.parents('ul').css('display','block');
		// remove viewport indicator
		jQuery('.viewport').removeClass('viewport');
		// show next step ul , set .viewport 
		$element.next().css('display','block').addClass('viewport');
//		console.log("element: ",$element," added viewport to: ",$element.next()," successfull: ",$element.next().hasClass('viewport'))

		// return desired animation depth
		if ($element.parents('ul.third').length !== 0) { return 3; }
		if ($element.parents('ul.second').length !== 0) { return 2; }
		if ($element.parents('ul.first').length !== 0) { return 1; }
	}
	
};

/**
 * Returns selector for current element
 * @param {Object} $element
 * @private
 * @return {String}
 * @deprecated 
 */
//audi_ngw.animation.slideDistributor._getMyLevelSelector = function ($element) {
// 	if ($element.parents('ul.third').length !== 0) { return 'ul.third'; }
//	if ($element.parents('ul.second').length !== 0) { return 'ul.second'; }
//	if ($element.parents('ul.first').length !== 0) { return  'ul.first'; }
//}


/**
 * Gets running flag
 * @method getRunning
 * @return {Boolean}
 */
audi_ngw.animation.slideDistributor.getRunning = function(){
	return audi_ngw.animation.getRunning(audi_ngw.animation.slideDistributor.__className);
};

/**
 * Removes running flag
 * @method unsetRunning
 * @return {Void}
 */
audi_ngw.animation.slideDistributor.unsetRunning = function(){
	audi_ngw.animation.unsetRunning(audi_ngw.animation.slideDistributor.__className);
};

/**
 * Sets running flag
 * @method setRunning
 * @return {Void}
 */
audi_ngw.animation.slideDistributor.setRunning = function(){
	audi_ngw.animation.setRunning(audi_ngw.animation.slideDistributor.__className);
};


/**
 *Initialize animation "slideDistributor"
 * @method initialize
 * @constructor
 * @param {Object} Options 
 * @return {Void}
 */
audi_ngw.animation.slideDistributor.initialize = function(options){
	
	this.__className =  'audi_ngw.animation.slideDistributor';
	this.__classVersion= '1.2';
	
	this.unsetRunning();
	this._options = {};
	this._options.sIdWrapper = '#'+options.sIdWrapper;
	this._options.sClassNameVisible = ".visible";
	this._options.iNavWidth = "242";
	this._balanceWrapperHeight();
};

/*
audi_ngw.animation.slideDistributor.TEST = function() {
	this._addClickEvents();
	jQuery('#link-test1').click(
		function(){
			audi_ngw.animation.slideDistributor.animate(jQuery('#test1'));
 		})
	jQuery('#link-test2').click(
		function(){
			audi_ngw.animation.slideDistributor.animate(jQuery('#test2'));
 		})
	jQuery('#link-test3').click(
		function(){
			audi_ngw.animation.slideDistributor.animate(jQuery('#test3'));
 		}
	)
}
*/


	
