﻿
/*======================================================================
  Javascript Menu 1.0
  Copyright (c) 2008 SCL Software (http://www.sclsoftware.com) 
  You can use it freely as long as all copyright messages are intact.   
======================================================================*/

if (typeof Scl == "undefined") 
{
    var Scl = {};
}

(function()
{
    Scl.MenuItem = function(text, link, target, cssClass)
    {
        this.text = text;
        this.link = link;
        this.target = target;
        this.cssClass = cssClass;
    };

    Scl.Menu = function(menuWidth)
    {
        var instance = this;
        var menuDiv;
        var menuItems = new Array();
        var dockElement;
        var left = 0;
        var top = 0;
        var width = menuWidth ? menuWidth : 200;
        var height = 0;
        var hideThread;
        var fullVisible = false;
        var animationThread;
        var animationStart = 0;
        var animationEnd = 0;
        var ANIMATION_NONE = 0;
        var ANIMATION_VERTICAL = 1;
        this.animationType = ANIMATION_VERTICAL;
        this.animationSpeed = 10;
        this.animationStep = 15;
        this.margin = 10;
        this.menuCssClass = 'menu';
        this.menuItemCssClass = 'menuItem';
        this.rightToLeft = false;
        this.bottomToTop = false;
        this.hideTimeOut = 120;

        this.addItem = function(text, link, target, cssClass)
        {
            menuItems.push(new Scl.MenuItem(text, link, target, cssClass));
        };

        this.dockTo = function(element)
        {
            addEvent(window, 'load', function() { dockToElement(element); }, false);
        };

        this.showAt = function(element)
        {
            initialize();

            var position = getPosition(element);
            position.y += (instance.bottomToTop) ? (height + instance.margin) * -1 : instance.margin + element.offsetHeight;

            show(position.x, position.y);
        };

        this.showAtPosition = function(x, y)
        {
            initialize();
            show(x, y);
        };

        this.hide = function()
        {
            hideThread = setTimeout(hideMenu, instance.hideTimeOut);
        };

        function dockToElement(element)
        {
            if (typeof (element) == 'string')
            {
                element = document.getElementById(element);
            }

            dockElement = element;
            addEvent(element, 'mouseover', showAtDockElement, false);
            addEvent(element, 'mouseout', instance.hide, false);
        };

        function showAtDockElement()
        {
            instance.showAt(dockElement);
        };

        function initialize()
        {
            if (menuDiv == null)
            {
                createMenu();
            }
        };

        function show(x, y)
        {
            cancelHide();

            menuDiv.style.left = x + 'px';
            menuDiv.style.top = y + 'px';

            // Asignar para la animacion
            left = x;
            top = y;

            switch (instance.animationType)
            {
                case ANIMATION_NONE:
                    menuDiv.style.display = 'block';
                    break;

                default:
                    startAnimation(0, height);
                    break;
            }
        };

        function createMenu()
        {
            menuDiv = document.createElement('div');
            menuDiv.style.position = 'absolute';

            var innerDiv = document.createElement('div');
            menuDiv.appendChild(innerDiv);

            innerDiv.className = instance.menuCssClass;
            innerDiv.style.width = width + 'px';

            addEvent(menuDiv, 'mouseover', cancelHide, false);
            addEvent(menuDiv, 'mouseout', instance.hide, false);

            // Add items
            for (var i = 0; i < menuItems.length; i++)
            {
                var menuItemDiv = createMenuItem(menuItems[i]);
                innerDiv.appendChild(menuItemDiv);
            }

            // Add to the document	
            document.body.appendChild(menuDiv);

            height = menuDiv.offsetHeight;
        };

		function createMenuItem(menuItem)
        {
            var menuItemDiv = document.createElement('div');
            menuItemDiv.className = menuItem.cssClass != null ? menuItem.cssClass : instance.menuItemCssClass;

            if (menuItem.link != null)
            {
                menuItemDiv.link = menuItem.link;
                menuItemDiv.onclick = function()
                {
                    window.open(menuItem.link,
                                (menuItem.target ? menuItem.target : "_self"),
                                "location=0,status=0,scrollbars=0,width=900,height=740"); 
                };
                menuItemDiv.appendChild(document.createTextNode(menuItem.text));
            }

            return menuItemDiv;
        };

        function cancelHide()
        {
            clearTimeout(hideThread);
            hideThread = null;
        };

        function hideMenu()
        {
            switch (instance.animationType)
            {
                case ANIMATION_NONE:
                    menuDiv.style.display = 'none';
                    break;

                default:
                    startAnimation(parseStyle(menuDiv.style.height), 0);
                    break;
            }
        };

        function parseStyle(value)
        {
            return parseInt(value.substring(0, value.length - 2));
        };

        function getPosition(element)
        {
            var posx = 0;
            var posy = 0;

            if (element.offsetParent)
            {
                do
                {
                    posx += element.offsetLeft;
                    posy += element.offsetTop;

                    if (!element.offsetParent)
                    {
                        break;
                    }
                }
                while (element = element.offsetParent)
            }
            else if (element.x)
            {
                posx += element.x;
                posy += element.y;
            }

            return { x: posx, y: posy };
        };

        function addEvent(element, evType, functionName, useCapture)
        {
            if (element.addEventListener)
            {
                element.addEventListener(evType, functionName, useCapture);
            }
            else if (element.attachEvent)
            {
                element.attachEvent('on' + evType, functionName);
            }
            else
            {
                element['on' + evType] = functionName;
            }
        };

        function startAnimation(start, end)
        {
            var showing = end > start;

            if (showing & fullVisible)
            {
                return;
            }

            menuDiv.style.zIndex = showing ? 20 : 1;

            animationStart = start;
            animationEnd = end;
            menuDiv.style.overflow = 'hidden';
            menuDiv.style.display = 'block';
            menuDiv.style.height = animationStart + 'px';

            fullVisible = false;

            clearInterval(animationThread);

            switch (instance.animationType)
            {
                case ANIMATION_VERTICAL:
                    if (instance.bottomToTop)
                    {
                        menuDiv.style.top = (top + height - menuDiv.offsetHeight) + 'px';
                    }
                    animationThread = setInterval(animateVertical, instance.animationSpeed);
                    break;
            }
        };

        function animateVertical()
        {
            var showing = animationEnd > animationStart;

            var strHeight = menuDiv.style.height;
            var animationHeight = parseInt(strHeight.substring(0, strHeight.length - 2));

            if ((showing & animationHeight >= animationEnd) || (!showing & animationHeight <= animationEnd))
            {
                clearInterval(animationThread);

                if (showing)
                {
                    fullVisible = true;
                }
                else
                {
                    menuDiv.style.display = 'none';
                }
            }
            else
            {
                animationHeight += showing ? instance.animationStep : -instance.animationStep;

                if ((showing & animationHeight > animationEnd) || (!showing & animationHeight < animationEnd))
                {
                    animationHeight = animationEnd;
                }

                menuDiv.style.height = animationHeight + 'px';

                if (instance.bottomToTop)
                {
                    menuDiv.style.top = (top + height - animationHeight) + 'px';
                }
            }
        };
    };
})();



