/**
 * The MSFlyout Class handles the Flyout Menus on the website.
 * It offers timeout values that can be different for each
 * flyout type. This class depends on the daimler_basic.js!
 * 
 * @author Stefan.Bechtold(at)namics.com
 * @version 1.0
 * @requires daimler_basic.js
 * @requires navigation.js
 */

// Class MSFlyout, Constructor
function MSFlyout(/*String*/ id, /*int*/ type) {
	
	LOG('MSFlyout: called constructor. id: ' + id + ', type: ' + type);
	
	this.id = id;
	this.type = type;
	this.active = false;
	
	// Get Layer for this Flyout
	if (id) {
		this.flyout = getLayer(id);
	}

	if (!this.flyout || this.flyout == undefined) {
		LOG('MSFlyout: no flyout,  id: ' + id + '   type: ' + type);
		return false;
	}	
	// Check and extend global MSFlyout list if necessary
	if (!MSFlyout.flyouts[type]) {
		MSFlyout.flyouts[type] = new Array();
	}

	// Add flyout to global MSFlyout object
	MSFlyout.flyouts[type][id] = this;
	
	// Add event listener for this flyout
	LOG('MSFlyout: flyout is available,  id: ' + id + '   type: ' + type);
	addEvent(this.flyout, "mouseover", function(e) { MSFlyout.flyouts[type][id].activate(e) }, true);
	addEvent(this.flyout, "mouseout", function(e) { MSFlyout.flyouts[type][id].deactivate(e) }, true);
}

// Static Flyout Types
MSFlyout.TYPE_CORENAV1 = 1;
MSFlyout.TYPE_CORENAV2 = 2;
MSFlyout.TYPE_PCN_BUTTON = 3;
MSFlyout.TYPE_PCN_MENU = 4;
MSFlyout.TYPE_METANAVLOGIN = 5;
MSFlyout.TYPE_METANAVRSI = 6;
MSFlyout.TYPE_PCN_BUTTON_2 = 3;
MSFlyout.TYPE_PCN_BUTTON_3 = 3;

// Static Timeout Settings
MSFlyout.ACTIVATION_TIMEOUT = new Array();
MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_CORENAV1] = 200;
MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_CORENAV2] = 500;

MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_PCN_BUTTON] = 100;
MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_PCN_BUTTON_2] = 100;
MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_PCN_BUTTON_3] = 100;

MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_PCN_MENU] = 50;
MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_METANAVLOGIN] = 250;
MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_METANAVRSI] = 250;
// deactivate
MSFlyout.DEACTIVATION_TIMEOUT = new Array();
MSFlyout.DEACTIVATION_TIMEOUT[MSFlyout.TYPE_CORENAV1] = 200;
MSFlyout.DEACTIVATION_TIMEOUT[MSFlyout.TYPE_CORENAV2] = 200;

MSFlyout.DEACTIVATION_TIMEOUT[MSFlyout.TYPE_PCN_BUTTON] = 100;
MSFlyout.DEACTIVATION_TIMEOUT[MSFlyout.TYPE_PCN_BUTTON_2] = 100;
MSFlyout.DEACTIVATION_TIMEOUT[MSFlyout.TYPE_PCN_BUTTON_3] = 100;

MSFlyout.DEACTIVATION_TIMEOUT[MSFlyout.TYPE_PCN_MENU] = 50;
MSFlyout.DEACTIVATION_TIMEOUT[MSFlyout.TYPE_METANAVLOGIN] = 200;
MSFlyout.DEACTIVATION_TIMEOUT[MSFlyout.TYPE_METANAVRSI] = 200;

// Static CSS Settings
MSFlyout.CSS_CLASS_ACTIVE = "ms-active";
MSFlyout.CSS_CLASS_HOVER = "ms-fly-hover";

// Static Vars
MSFlyout.flyouts = new Array();
MSFlyout.openFlyout = new Array();
MSFlyout.changeTimeout = new Array();
MSFlyout.closeTimeout = new Array();

// Static Methods
MSFlyout.change = function(/*String*/ id, /*int*/ type) {
	LOG('MSFlyout in change():  type: ' + type + '   id: ' + id);
	// Close open MSFlyout Menu
	if (MSFlyout.openFlyout[type]) {
		MSFlyout.openFlyout[type].handleDeactivate();
	}
	
	// Open new MSFlyout Menu
	if (MSFlyout.flyouts[type][id]) {
		MSFlyout.flyouts[type][id].handleActivate();
	}
};

MSFlyout.closeAll = function(/*int*/ type) {
	// Close all open MSFlyout Menus
	for (var flyout in MSFlyout.flyouts[type]) {
		if (MSFlyout.flyouts[type][flyout].active) {
			MSFlyout.flyouts[type][flyout].handleDeactivate();
		}
	}
	LOG('MSFlyout in CloseAll():  type: ' + type);

	// Reset openFlyout Reference
	MSFlyout.openFlyout[type] = undefined;
};

MSFlyout.pushClass = function(object, className) {
	var /*String*/ objClasses = getClassName(object);
	if (objClasses.indexOf(className) == -1) {
		objClasses += " " + className;
	}
	setClass(object, objClasses);
};

//push class for the MetaNavigation
MSFlyout.pushClassMN = function(object) {
	object.style.display = "block";
};

MSFlyout.popClass = function(object, className) {
	var /*String*/ objClasses = getClassName(object);
	var /*int*/ posClassName = objClasses.indexOf(className);
	if (posClassName != -1) {
		if (posClassName + className.length < objClasses.length) {
			objClasses = objClasses.substring(0, posClassName) + objClasses.substring(posClassName + className.length);
		} else {
			objClasses = objClasses.substring(0, posClassName);
		}
	}
	setClass(object, objClasses);
};

//pop class for the MetaNavigation
MSFlyout.popClassMN = function(object) {
	object.style.display = "none";
};



// Methods
MSFlyout.prototype.activate = function(/* event */ evnt) {
	
	LOG('MSFlyout in activate(): flyout id:' + this.id);
	// Clear Closing Timeout
	clearTimeout(MSFlyout.changeTimeout[this.type]);
	clearTimeout(MSFlyout.closeTimeout[this.type]);

	// Closing all independend, open menus
	for (var type in MSFlyout.openFlyout) {
		var /*boolean*/ isIndependend = true;
		switch (this.type) {
			// Core Navigation flyouts
			case MSFlyout.TYPE_CORENAV1:
			case MSFlyout.TYPE_CORENAV2:
				isIndependend = ((type != MSFlyout.TYPE_CORENAV1) && (type != MSFlyout.TYPE_CORENAV2));
				break;
			
			// PCN Flyouts
			case MSFlyout.TYPE_PCN_BUTTON:
			case MSFlyout.TYPE_PCN_BUTTON_2:
			case MSFlyout.TYPE_PCN_BUTTON_3:
			case MSFlyout.TYPE_PCN_MENU:
				isIndependend = ((type != MSFlyout.TYPE_PCN_BUTTON) &&(type != MSFlyout.TYPE_PCN_BUTTON_2)&&(type != MSFlyout.TYPE_PCN_BUTTON_3)
						&& (type != MSFlyout.TYPE_PCN_MENU));
				break;

			case MSFlyout.TYPE_METANAVLOGIN:
				break;
				
			case MSFlyout.TYPE_METANAVRSI:
				break;
		}
		
		// If current flyout type is independend and flyout is opened, close them
		if (isIndependend && MSFlyout.openFlyout[type] && type != this.type) {
			LOG('MSFlyout call CloseAll(): flyout id:' + this.id + ',   isIndependend: ' + isIndependend + ',  type: ' + type + ',   This type: ' + this.type);
			MSFlyout.closeAll(type);
		}
	}

	if (MSFlyout.openFlyout[this.type] == undefined) {
		LOG('MSFlyout: This type: ' + this.type + '     call handleActivate() in activate');
		// If no MSFlyout Menu is open, strictly open the current one
		this.handleActivate();
	} else if (MSFlyout.openFlyout[this.type] != this) {
		LOG('MSFlyout: This type: ' + this.type + '    setTimeout->change() in activate');
		MSFlyout.changeTimeout[this.type] = setTimeout("MSFlyout.change(\"" + this.id + "\", \"" + this.type + "\")", MSFlyout.ACTIVATION_TIMEOUT[this.type]);
	}
};

MSFlyout.prototype.handleActivate = function() {
	// Call Ajax Request for Core Navigation 2 Flyout
	if (this.type == MSFlyout.TYPE_CORENAV2) {
		var /*String[]*/ values = this.id.split("@");
		var /*String*/ elementId = values[0];
		var /*String*/ handle = values[1];
		ms_corenav_loadFlyoutData(elementId, handle);
	} else {
		ms_setIFrameHeight(this.flyout.id);
	}
	
	
	// Activate MSFlyout
	if (this.type == MSFlyout.TYPE_METANAVLOGIN) {
		this.active = true;
		MSFlyout.pushClassMN(this.flyout);
	}
	else {
		this.active = true;
		MSFlyout.pushClass(this.flyout, MSFlyout.CSS_CLASS_HOVER);
	}
	
	// Set openFlyout Reference
	MSFlyout.openFlyout[this.type] = this;
	LOG('MSFlyout in handleActivate():  type: ' + this.type + '   id: ' + this.id);
	/* ********************************************* */
	// Avoiding, that the flyout becomes hidden 
	// behind the bottom border of the browser.
	/* ********************************************* */
	// Only for PCN and SUBNAVIGATION
	if (this.type == MSFlyout.TYPE_PCN_BUTTON || this.type == MSFlyout.TYPE_PCN_BUTTON_2 || this.type == MSFlyout.TYPE_PCN_BUTTON_3 || this.type == MSFlyout.TYPE_PCN_MENU) {
		if (this.flyout && this.flyout.getElementsByTagName("div") && 
				this.flyout.getElementsByTagName("div").length > 0) {
			// Check for IE
			var isIE = (document.all && !window.opera);
			
			// Calculate flyoutTop position
			var flyoutOffset = 0;
			var flyoutMenu = this.flyout.getElementsByTagName("div")[0];
			if (flyoutMenu.lastChild && flyoutMenu.lastChild.childNodes.length > 0) {
				var childNodes = flyoutMenu.lastChild.childNodes;
				for (var i = 0; i < childNodes.length; i++) {
					if (childNodes[i].nodeName == "LI") {
						flyoutOffset += childNodes[i].offsetHeight;
					}
				}
			}

			// Get positions of page elements			
			var buttonTop = getAbsTop(this.flyout);
			var footerHeight = getLayer("ms-footer").offsetHeight;
			if (isIE) {
				var innerHeight = document.documentElement.clientHeight - footerHeight;
				var pageOffset = document.documentElement.scrollTop;
			} else {
				var innerHeight = window.innerHeight - footerHeight;
				var pageOffset = window.pageYOffset;
			}
			
			// Check if flyout menu would be visibile
			var lowestY = buttonTop + flyoutOffset - pageOffset;
			if (lowestY > innerHeight) {
				// Set position from the button
				flyoutMenu.style.bottom = "0px";
				flyoutMenu.style.top = "auto"; // need to overwrite!
				
				// IE needs a height for the outer element to work correctly
				if (isIE && (getIEVersion()>0)&& (getIEVersion()<7) && this.flyout) {
					this.flyout.style.height = this.flyout.offsetHeight + "px";
				}
			} else {
				// Remove inline styles
				if (isIE) {
					flyoutMenu.style.removeAttribute("bottom", false);
					flyoutMenu.style.removeAttribute("position", false);
					flyoutMenu.style.removeAttribute("top", false);
				} else {
					flyoutMenu.style.bottom = "";
					flyoutMenu.style.position = "";
					flyoutMenu.style.top = "";
				}
			}
		}
	}
	/* ********************************************* */
	// Avoiding, that the flyout becomes hidden  
	// behind the bottom border of the browser.   
	/* ********************************************* */
};

function getIEVersion() {
	try {
		if (navigator.appName=="Microsoft Internet Explorer" && navigator.appVersion.indexOf("MSIE")>0) {		
			var str = navigator.appVersion;
			var ind = parseInt(str.indexOf("MSIE"))+5;
			var ver = parseInt(str.substring(ind, ind+1));
			return ver;
		} else {
			return 0;
		}
	} catch(e) {}
}

MSFlyout.prototype.deactivate = function(/* event */ evnt) {
	LOG('MSFlyout in deactivate() set CloseAll: flyout id:' + this.id + ',   This type: ' + this.type);
	// Set Closing Timeout
	MSFlyout.closeTimeout[this.type] = setTimeout("MSFlyout.closeAll(\"" + this.type + "\")", MSFlyout.DEACTIVATION_TIMEOUT[this.type]);

};

MSFlyout.prototype.handleDeactivate = function() {
	LOG('MSFlyout in handleDeactivate(): flyout id:' + this.id + ',   This type: ' + this.type);

	// Deactivate MSFlyout
	if (this.type == MSFlyout.TYPE_METANAVLOGIN && !overMsNaviMeta && !hasInputFocus) {
		this.active = false;
		MSFlyout.popClassMN(this.flyout);
	}
	else{
		this.active = false;
		MSFlyout.popClass(this.flyout, MSFlyout.CSS_CLASS_HOVER);
	}
	
};


// Helper Methods
function getAbsTop(element) {
	if (element.offsetParent) {
		return element.offsetTop + getAbsTop(element.offsetParent);
	} else {
		return element.offsetTop;
	}
}
