/**
 * 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){
    this.id = id;
    this.type = type;
    this.active = false;
    
    // Get Layer for this Flyout
    if (id) {
        this.flyout = getLayer(id);
    }
    
    // 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
    if (this.flyout) {
        addEvent(this.flyout, "mouseover", function(){
            MSFlyout.flyouts[type][id].activate()
        }, true);
        addEvent(this.flyout, "mouseout", function(){
            MSFlyout.flyouts[type][id].deactivate()
        }, 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;

// 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] = 200;
MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_PCN_MENU] = 250;
MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_METANAVLOGIN] = 250;
MSFlyout.ACTIVATION_TIMEOUT[MSFlyout.TYPE_METANAVRSI] = 250;

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] = 200;
MSFlyout.DEACTIVATION_TIMEOUT[MSFlyout.TYPE_PCN_MENU] = 200;
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){
    // 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();
        }
    }
    
    // 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(){
    // 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_MENU:
                isIndependend = ((type != MSFlyout.TYPE_PCN_BUTTON) &&
                (type != MSFlyout.TYPE_PCN_MENU));
                break;
                
            case MSFlyout.TYPE_METANAVLOGIN:
                break;
                
            case MSFlyout.TYPE_METANAVRSI:
                break;
        }
        
        // If current flyout type is independend and has open flyouts, close them
        if (isIndependend && MSFlyout.openFlyout[type]) {
            MSFlyout.closeAll(type);
        }
    }
    
    if (MSFlyout.openFlyout[this.type] == undefined) {
        // If no MSFlyout Menu is open, strictly open the current one
        this.handleActivate();
    }
    else 
        if (MSFlyout.openFlyout[this.type] != this) {
            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;
    
    /* ********************************************* */
    // 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_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(){
    // Set Closing Timeout
    MSFlyout.closeTimeout[this.type] = setTimeout("MSFlyout.closeAll(\"" + this.type + "\")", MSFlyout.DEACTIVATION_TIMEOUT[this.type]);
}

MSFlyout.prototype.handleDeactivate = function(){
    // 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);
    }
}



