/**
 * AUDI JavaScript library: Simple Layer
 * 
 * @projectDescription	Layer class providing functionalities for simple layers such as "send a friend", "success", "error" 
 * @namespace			layer.simple
 *
 * @author 				$Author: hhoettecke $
 * @version				$Revision: 9429 $
 * @copyright			NEUE DIGITALE GmbH, Berlin
 * 
 * @jslint: 2008-10-01
 * 
 * @file:				audi_ngw.layer.simple.js
 * $URL: https://svn.pvtool.org/svn/day_audi_ngw/trunk/ngw_base/frontend/js/audi/audi.layer.simple.js $
 */

/* create namespace */
audi_ngw.namespace(audi_ngw,'layer.simple');

/**
 * Set up Environment
 * @method _setUp
 * @return {Void}
 * @private
 */
audi_ngw.layer.simple._setUp = function(){
	var _sSelector = "#";
	_sSelector += this._options.sIdLayer;
	
	if (!jQuery(_sSelector).size()) {
		jQuery('<div>').attr('id',this._options.sIdLayer).hide().addClass(this._options.sIClassNamesLayer).appendTo('body');
	}
	this._$elLayer = jQuery(_sSelector);
	this._$elLayer.css({
		zIndex: 9500,
		position: 'absolute'
	}).hide();

//	var _$elLayerClone = document.getElementById(this._options.sIdLayer).cloneNode(true);
//	
//	this._$elLayerClone = jQuery(_$elLayerClone)
//					.attr('id',this._options.sIdLayer+'_clone')
//					.show()
//					.css({
//						'visibility':'hidden',
//						'left': '-9999em',
//						'top': '0'
//					})
//					.appendTo('body');
//	_$elLayerClone = null;
};


 

/**
 * Hides simple layer, bridge to _doHide
 * @return {void}
 */
audi_ngw.layer.simple.hide = function(){
	// get element reference
	var _$element = audi_ngw.layer.simple._$elLayer;
	// hide
	audi_ngw.layer.simple._doHide(_$element);
};

/**
 * Hides simple layer 
 * @param {HTMLELement} $element
 * @return {void}
 * @private
 * 
 */
audi_ngw.layer.simple._doHide = function($element){
 	// set scope
	var scope = audi_ngw.layer.simple;	
	// clear timer 
	scope._oTimers.hideDelayed = audi_ngw.clearTimer(scope._oTimers.hideDelayed);
	// delete reference
	delete scope._oTimers.hideDelayed;
	// remove iframe
	audi_ngw.layer.unsetIE6Fix();
	// remove global listener (hasOutsideClick)
//	jQuery(document).unbind('click');
	// set element properties
	$element
	// remove element before resetting
	.hide()
	.audi_unsetLoading()
	.audi_unsetUnique()
	.empty()
	.attr('className','')
	.addClass('template_d')
	// reset all css properties to guarantee constant experience
	.css({
		height: '',
		width: '',
		top: '',
		right: '',
		bottom: '',
		left: '',
		opacity: 1
	});
	// reset clone
	if(audi_ngw.layer.simple._$elLayerClone) {
		audi_ngw.layer.simple._$elLayerClone
			.empty()
			.remove();
		audi_ngw.layer.simple._$elLayerClone = null;
	}
 
//	if (scope._$elLayer.parent()[0].id == 'audi_modal_super_wrapper') {
 
//		jQuery('body').append(scope._$elLayer.remove());
//		jQuery('body').append(scope._$elLayerClone.remove());
//	}

	// Add resize event listener
//	if (scope._oLayerOptions.sPosition === 'center') {
		jQuery(window).unbind('resize.simple', audi_ngw.layer.simple._doCenterPosition);
//	}
	this._$eventElement = null;
	// clear options
	this._oLayerOptions = {};
};

/**
 * Shows simple layer, bridge to _doShow
 * @param {Event} event
 * @return {void}
 */
audi_ngw.layer.simple.show = function(event){
	if (arguments[0].preventDefault) {
		event.preventDefault();
	}

	// get element reference 
	var _$element = audi_ngw.layer.simple._$elLayer;
	// set scope
	var scope = audi_ngw.layer.simple;	
	var oOptions = oOptions || {};
	// extract event element 
	scope._$eventElement = jQuery(event.target);
	var _$eventElement = jQuery(event.target);
	// get options from event element
	scope._oLayerOptions = audi_ngw.layer.getOptions(_$eventElement,'simple');
	// show
	audi_ngw.layer.simple._doShow(_$element, _$eventElement, scope._oLayerOptions);
};

/**
 * Shows simple layer
 * - width: 	1 -2 col
 * - height: 	flexible
 * - modal: 	no 
 * - close:		outside click, automatically
 * - multiple: 	no
 * - history: 	no
 * 			
 * @param {HTMLelement} $element
 * @param {EventElement} $eventElement
 * @param {Object} oOptions
 * @return {void}
 * @private
 */
audi_ngw.layer.simple._doShow = function($element,$eventElement,oOptions){
	// cache scope
	var scope = audi_ngw.layer.simple;	
	var _oPos = {};
	// check for running / open element
	if (audi_ngw.dom.getUnique($element.attr('id')) === true) { return; }

	// add iframe covering the whole body
	audi_ngw.layer.setIE6Fix('body',{});
	
	if (audi_ngw.layer.modal._$elModal.css('display') !== 'none') {
		$element.addClass('hasModal');
	}
//	if (audi_ngw.layer.modal._$elModal.css('display') !== 'none') {
 
//		audi_ngw.layer.modal._$elLayerWrapper.append(scope._$elLayer.remove());
//		audi_ngw.layer.modal._$elLayerWrapper.append(scope._$elLayerClone.remove());
//	}
	
	// prepare element
	$element
		.audi_setUnique()
		.audi_setLoading();

	// set fixed if requested
	if (oOptions.sWidth) { $element.width(oOptions.sWidth); }
	if (oOptions.sHeight) { $element.height(oOptions.sHeight); }

	// set content using class or default method
	if (typeof scope._doSetContent == 'function') {
		_oPos = scope.setContent($element,'simple',oOptions);
	} else {
		_oPos = audi_ngw.layer._doSetContent($element,$eventElement,'simple',oOptions);
	}

	// use default or scope method to calculate position
	if (typeof scope._calculatePosition == 'function') {
		_oPos = scope._calculatePosition($element,oOptions.sPosition,$eventElement);
	} else {
		_oPos = audi_ngw.layer._calculatePosition($element,oOptions.sPosition,$eventElement);
	}
	
	// set css properties using the calculated position
	audi_ngw.layer.simple.setPosition($element,_oPos);
	

	// bind custom "events"
	// bind "timed fade out" after displaying the content (xhr callback, @see audi_ngw.layer.simple._doXhrReallocationComplete)
	if (scope._oLayerOptions.hasHideDelayed && scope._oLayerOptions.sContentType !== 'ajax') {
		audi_ngw.layer.bind('hideDelayed','simple');
	}
	// hide element if the user clicks somewhere except inside the layer
	if (oOptions.hasOutsideClick) {
		window.setTimeout(
		function () {
			audi_ngw.layer.bind('outsideClick','simple');
		},50);
	}
	
	// show element
	$element
 		.show();
};
 


audi_ngw.layer.simple._calculatePosition = function ($element,sPosition,$eventElement) {
 
	var _top, _right, _bottom, _left;
	switch(sPosition) {
		case 'element':
			// cache scope
			var _scope = audi_ngw.layer.simple;	
		
			// cache wrapper height 
			var $elWrapperHeight = jQuery('body').outerHeight();
			
			// get link position
			var _oLinkPos =  _scope._$eventElement.offset(); // $eventElement.offset()
 
			// calculate left related to link
			_left = _oLinkPos.left;
			// calculate bottom related to link
			_bottom  = $elWrapperHeight - _oLinkPos.top + 10;
			_top = _oLinkPos.top - $element.outerHeight();
		break;

		case 'center':
//			_left = Math.floor(((jQuery('#audi_container_page').outerWidth() / 2) - ($element.outerWidth() / 2)));
			_left = Math.floor(((jQuery('body').outerWidth() / 2) - ($element.outerWidth() / 2)));
//			_top =Math.floor( (jQuery('#audi_container_page').outerHeight() / 2) - ($element.outerHeight() / 2) );
			_top = ((jQuery('body').innerHeight() / 2) - ($element.height() / 2));
			_bottom =Math.floor( (jQuery('#audi_container_page').outerHeight() / 2) + ($element.outerHeight()) );
		break;
	} 

	// add units
	_left += 'px';
	_top  += 'px';
	_bottom  += 'px';
 
	return {
		iHeight: $element.outerHeight() ,
		iWidth: $element.outerWidth(),
		sLeft:_left ,
		sTop:_top,
		sBottom:_bottom
	};
};

/**
 * Sets layer position depending on supplied position type such as "center", "element"
 * @param {HTMLElement} $element / layer
 * @param {Object} _oPos
 * @return {Void}
 * @private
 */
audi_ngw.layer.simple.setPosition = function($element, _oPos, sPosition){
	var scope = audi_ngw.layer.simple;
	sPosition = sPosition || scope._oLayerOptions.sPosition;

	switch (sPosition) {

		// center layer according to content wrapper
		case 'center':
			$element.css({
				height: $element.height()+'px',
				left: _oPos.sLeft,
				top: _oPos.sTop,
				position: 'absolute',
				opacity: 1
			});
			// Add resize event listener
//			jQuery(window).bind('resize.simple',audi_ngw.layer.simple._doCenterPosition);
		break;

		// center layer according to content wrapper
		case 'centerOnResize':
			$element.css({
				height: $element.height()+'px',
				position: 'absolute',
				opacity: 1
			})
			.stop().animate({
				top: _oPos.sTop,
				left: _oPos.sLeft,
				easing: 'linear'
			}, 150);
 
		break;

		// set layer position above event element
		case 'element':
			$element.css({
				height: $element.height()+'px',
				left: _oPos.sLeft,
				bottom: _oPos.sBottom,
				position: 'absolute',
				opacity: 1
			});
		break;
	}
			jQuery(window).bind('resize.simple',audi_ngw.layer.simple._doCenterPosition);
};

/**
 * wrapper for _doShow
 * @method show
 * @constructor
 * @param {Object} Options 
 * @return {Void}
 */
audi_ngw.layer.simple._doCenterPosition = function(){
	var scope = audi_ngw.layer.simple;
	scope.setPosition(scope._$elLayer, scope._calculatePosition(scope._$elLayer, scope._oLayerOptions.sPosition), 'centerOnResize');

};
 
/**
 * Set layer position / dimensions after succesfully loaded content via xhr
 * @param {HTMLElement} $element / layer
 * @param {Object} _oPos
 * @return {Boolean}
 * @private
 */
audi_ngw.layer.simple._doXhrReallocation = function ($element,_oPos) {
	
	var scope = audi_ngw.layer.simple;
	
	// check if layer ain't visible (e.g. outside click closed element during xhr)
	if (audi_ngw.dom.getUnique($element.attr('id')) !== true) {
		// reset using hide
		scope._doHide($element);
		return false;
	}
	
	// skip reposition if fixed with is requested
	if (scope._oLayerOptions.sWidth || scope._oLayerOptions.sHeight) {
		// callback, pass element
		audi_ngw.layer.simple._doXhrReallocationComplete($element);
		return false;
	}
	switch (scope._oLayerOptions.sPosition) {
	
		// center layer according to content wrapper
		case 'center':
			$element.animate({
				width: _oPos.iWidth + 'px',
				height: _oPos.iHeight + 'px',
				left: _oPos.sLeft,
				top: _oPos.sTop
			}, 'fast', '', audi_ngw.layer.simple._doXhrReallocationComplete);
		break;
			
		// set layer position above event element
		case 'element':
			$element.animate({
				width: _oPos.iWidth + 'px',
				height: _oPos.iHeight + 'px',
				left: _oPos.sLeft,
				bottom: _oPos.sBottom
			}, 'fast', '', audi_ngw.layer.simple._doXhrReallocationComplete);
		break;
	}
	
	return true;
};

/**
 * OnComplete callback for repaint after xhr, set content further options
 * @return {Void}
 * @private
 */

audi_ngw.layer.simple._doXhrReallocationComplete = function(){

	var scope = audi_ngw.layer.simple;	
	// get extended element, either supplied or passed as callback argument (this)
	$element = arguments[0] || jQuery(this);
	// delay content to get a smoother transition
	window.setTimeout( 
		function () {
			// check if layer ain't visible (e.g. outside click closed element during xhr)
			if (audi_ngw.dom.getUnique($element.attr('id')) !== true) {
				// reset everyting using _doHide
				audi_ngw.layer.simple._doHide($element);
				return;
			}
			// handle layer
			$element
				// remove loading state
				.audi_unsetLoading()
				// insert content from cloned element
				.html(audi_ngw.layer.simple._$elLayerClone.html());
			// handle clone
			audi_ngw.layer.simple._$elLayerClone
				// empty clone
				.empty()
				.remove();
			audi_ngw.layer.simple._$elLayerClone = null;
			
			// bind custom "event"
			if (scope._oLayerOptions.hasHideDelayed) {
				audi_ngw.layer.bind('hideDelayed','simple');
			}
		},300);
};

/**
 * Closes element in case of click outside simple layer.
 * @param {Event} event
 * @private
 * @return {Void}
 */
audi_ngw.layer.simple._doOutsideClick = function(event){
	// cache scope 
	var scope = audi_ngw.layer.simple;	
	// grab event element
	var _$eventElement = jQuery(event.target);
	// check if the click event ain't a click on the simple layer or it's childrens
	if (_$eventElement.attr('id') === scope._options.sIdLayer || _$eventElement.parents('#'+scope._options.sIdLayer).size()) { 
		return;
	} else {
		// remove eventlistener
		jQuery(document).unbind('click.simple');
		// reset using hide 
		audi_ngw.layer.simple.hide();
	}
};


/**
 * Initialize
 * @method initialize
 * @constructor
 * @param {Object} Options 
 * @return {Void}
 */
audi_ngw.layer.simple.initialize = function(options){
	
	this.__className =  'audi_ngw.layer.simple';
	this.__classVersion= '1.2';
	this._oTimers = {};
	this._options = {};
	this._$elLayer = null;
	this._$eventElement = null;
	this._$elLayerClone = null;
	this._options.sIdLayer = 'audi_layer_simple';
	this._options.sIdToClone = 'audi_layer_simple';
	this._options.sIClassNamesLayer = 'template_d';
	this._oLayerOptions = {};
	this._setUp();

	this.oDefaults = {
		hasOutsideClick: true,
		hasHideDelayed: false,
		iHideDelayedMs: 4000,
		iFadeOutMS: 600,
		sContentType: 'text',
		sPosition: 'center',
		sContent: '[DEFAULT TEXT]'
	};
};




