/**
    SCL SOFTWARE.
    Santiago Corredoira Lascaray
    Copyright (C) SCL SOFTWARE 1999/2009.  All rights reserved.
    
    Menu desplegable con subMenus.
    version: 1.0
    
    Ejemplo para menu vertical:    
               
            new Scl.Menu('menu').render(
            {
                yMargin:5
            });
    
    
    Ejemplo para menu lateral:
                
            new Scl.Menu('menuModule').render(
            {
                yMargin:5,
                direction:'right',
                menuXIndent:-40
            });
*/

(function() {
    if (typeof Scl.Menu == "undefined") {
        Scl.Menu = function(mainMenuElement) {
            var mainMenu;
            var instance = this;
            var displayedMenu = null; // referencia al menu que se esta mostrando en cada momento.
            this.parameters = null;

            /**
            *  Procesa la lista y sus descendientes recursivamente
            */
            function parseNode(element, isRoot) {
                // Añadir el estilo
                if (isRoot == null) {
                    isRoot = true;
                }

                // Crear el menu    
                var parsedMenu =
                {
                    isRoot: isRoot,
                    element: element, // referencia al elemento del DOM
                    items: new Array()
                };

                // Añadir el estilo
                if (!isRoot) {
                    Scl.addClass(element, instance.parameters.childClass);
                }

                // Procesa los elementos del menu
                Scl.each(Scl.getChildNodes(element, "li"), function(item) {
                    var menuItem =
                    {
                        element: item,
                        menu: parsedMenu,
                        childMenu: null
                    };

                    // Añadir el estilo
                    if (!isRoot) {
                        Scl.addClass(item, instance.parameters.childItemClass);

                        // Eliminar el float y el margen de los miembros de los desplegables para que 
                        // ocupen todo el ancho y alto de su posicion en el desplegable.
                        var itemStyle = item.style;
                        itemStyle.float = "none";
                        itemStyle.margin = 0;
                    }

                    // Procesar los submenus si existen
                    var childNodes = Scl.getChildNodes(item, "ul");
                    if (childNodes.length > 0) {
                        menuItem.childMenu = parseNode(childNodes[0], false);
                    }

                    // Añade la opcion del menu al menu
                    parsedMenu.items.push(menuItem);
                });

                return parsedMenu;
            }

            /**
            *  Inicializa el menu eliminando los submenus y enganchando los eventos para
            *  mostrarlos y esconderlos cuando se pase el ratón por encima.
            */
            function init() {
                // Procesar la lista y todos sus elementos recursivamente
                mainMenu = parseNode(Scl.get(mainMenuElement));

                // Ocultar submenus y enlaza eventos.
                initMenu(mainMenu);
            }

            /**
            *  Oculta submenus y enlaza eventos.
            */
            function initMenu(menu) {
                Scl.each(menu.items, function(item) {
                    if (item.childMenu) {
                        item.childMenu.element.style.display = "none";

                        // Enganchar los eventos para mostrar el submenu
                        Scl.bind(item.element, 'mouseover', function() {
                            showMenu(item);
                        });

                        Scl.bind(item.element, 'mouseout', function() {
                            hideMenu(item);
                        });

                        // Si el menu tiene submenu, inicialiarloz tambien
                        initMenu(item.childMenu);
                    }
                });
            }

            function showMenu(menuItem) {
                // Si estaba pendiente de ocultarse el menu, cancelarlo.
                if (menuItem.hideThreadId) {
                    clearTimeout(menuItem.hideThreadId);
                    menuItem.hideThreadId = null;
                }

                // Obtener una referencia a los estilos del menu que se va a desplegar para agilizar los calculos.
                var style = menuItem.childMenu.element.style;

                // Posicionar y hacer visible el menu
                if (!menuItem.childMenu.layoutReady) {
                    // Obtener la posición del elemento padre del menu
                    var position = Scl.getPosition(menuItem.element);

                    var parentElementSize = Scl.getSize(menuItem.element);

                    style.position = "absolute";

                    style.zIndex = instance.parameters.zIndex;

                    // El menu raiz no se indenta, pero los hijos si, para que se distingan.
                    var xIndent = menuItem.menu.isRoot ? instance.parameters.menuXIndent : instance.parameters.childMenuXIndent;
                    var yIndent = menuItem.menu.isRoot ? instance.parameters.menuYIndent : instance.parameters.childMenuYIndent;

                    switch (instance.parameters.direction) {
                        case "right":

                            style.left = (position.x + xIndent + parentElementSize.width + instance.parameters.xMargin) + "px";
                            style.top = (position.y + yIndent + instance.parameters.yMargin) + "px";
                            break;

                        case "bottom":
                            style.left = (position.x + xIndent + instance.parameters.xMargin) + "px";
                            if (!window.XMLHttpRequest) { style.left = (position.x + xIndent + (-100)) + "px"; }
                                
                            
                                     
                            style.top = (position.y + yIndent + parentElementSize.height + instance.parameters.yMargin) + "px";
                            break;
                    }

                    // Establecer el layout como listo, para que no vuelva a calcularse en sucesivas veces.
                    menuItem.childMenu.layoutReady = true;
                }

                // mostrar el submenu
                style.display = "block";


                // Si hay otro visible, ocultarlo inmediatamente.
                if (displayedMenu != null && displayedMenu != menuItem) {
                    displayedMenu.childMenu.element.style.display = 'none';
                }

                // Guardar una referencia al menu para poder ocultarlo inmediatamente si se muestra otro.
                displayedMenu = menuItem;
            }

            function hideMenu(menuItem) {
                menuItem.hideThreadId = setTimeout(
                    function() {
                        menuItem.childMenu.element.style.display = "none";

                        if (displayedMenu == menuItem) {
                            displayedMenu = null;
                        }
                    },
                    instance.parameters.hideDelay);
            }

            function initParameters(menuParams) {
                if (!menuParams) menuParams = {};

                if (!menuParams.hideDelay) menuParams.hideDelay = 300;

                if (!menuParams.xMargin) menuParams.xMargin = 0;

                if (!menuParams.yMargin) menuParams.yMargin = 0;

                if (!menuParams.zIndex) menuParams.zIndex = 3000;

                // Indica lo que se indentan los menus principales al desplegarse
                if (!menuParams.menuXIndent) menuParams.menuXIndent = 0;
                if (!menuParams.menuYIndent) menuParams.menuYIndent = 0;

                // Indica lo que se indentan los menus hijos al desplegarse
                if (!menuParams.childMenuXIndent) menuParams.childMenuXIndent = 160;
                if (!menuParams.childMenuYIndent) menuParams.childMenuYIndent = -25;

                if (!menuParams.direction) {
                    menuParams.direction = 'bottom';
                }
                else {
                    menuParams.direction = menuParams.direction.toLowerCase();
                }

                if (!menuParams.childClass) menuParams.childClass = 'childMenu';

                if (!menuParams.childItemClass) menuParams.childItemClass = 'childMenuItem';

                instance.parameters = menuParams;
            }

            this.render = function(menuParams) {
                initParameters(menuParams);

                // Iniciar el proceso cuando el documento este cargado
                init();
                //Scl.onLoad(function(){ init(); });
            }
        }
    }
})(); 