$(document).ready(function()
{
    var optionsTimeouts   = {};
    var optionsSizes      = {};
    var optionsHeights    = {};
    var animationTimeouts = {};
    var buttonsReady      = false;
    
    function show(options, onlyIfOpen)
    {
        return function()
        {
            if (optionsTimeouts[options.id])
            {
                clearTimeout(optionsTimeouts[options.id]);
                optionsTimeouts[options.id] = null;
            }
            
            if ((optionsHeights[options.id] == 0 || options.className.match(/\bcurrent\b/)) && onlyIfOpen)
                return;
        
            for (var i = 0; ; ++i)
            {
                if (!document.getElementById("button" + i))
                    break;
                
                var otherOptions = document.getElementById("options" + i);
    
                if (!otherOptions || otherOptions.id == options.id)
                    continue;
                    
                hide(otherOptions, true)();
            }
            
            animateOptions(options, optionsSizes[options.id], 1, 3);
        };
    }
    
    function hide(options, now)
    {
        return function()
        {
            if (options.className.match(/\bcurrent\b/))
                return;
                
            if (!now)
            {
                // Hide the options in six seconds.
                optionsTimeouts[options.id] = setTimeout
                (
                    hide(options, true),
                    10000
                );
            }
            else
                animateOptions(options, 0, 2, 3);
        };
    }
    
    function animateOptions(options, endSize, sizeIncrement, timeInterval, startSize, startTime)
    {
        if (animationTimeouts[options.id])
            clearTimeout(animationTimeouts[options.id]);
            
        if (timeInterval == 0)
            optionsHeights[options.id] = endSize;
            
        options.style.height  =  optionsHeights[options.id] + "px";
        options.style.display = (optionsHeights[options.id] <= 0 ? "none" : "");
        
        if (optionsHeights[options.id] == endSize)
        {
            animationTimeouts[options.id] = null;
            return;
        }
        
        if (typeof startSize == "undefined")
        {
            startSize = optionsHeights[options.id];
            startTime = new Date().getTime();
        }
      
        var timeNeeded   = Math.abs(endSize - startSize) * timeInterval / sizeIncrement;
        var elapsedTime  = new Date().getTime() - startTime;
        var expectedSize = startSize + (endSize - startSize) * elapsedTime / timeNeeded;
        
        if (options.className.match(/\bcurrent\b/))
            return;
            
        if (startSize < endSize && expectedSize > endSize) expectedSize = endSize;
        if (startSize > endSize && expectedSize < endSize) expectedSize = endSize;
            
        optionsHeights   [options.id] = expectedSize;
        animationTimeouts[options.id] = setTimeout
        (
            function()
                { animateOptions(options, endSize, sizeIncrement, timeInterval, startSize, startTime); },
            
            timeInterval
        );
    }

    for (var i = 0; ; ++i)
    {
        var button  = document.getElementById("button"  + i);
        var options = document.getElementById("options" + i);
        
        if (!button)  break;
        if (!options) continue;
    
        button .onclick     = show(options, false);
        button .onmouseover = show(options, true);
        button .onmouseout  = hide(options, false);
        options.onclick     = show(options, false);
        options.onmouseover = show(options, true);
        options.onmouseout  = hide(options, false);
    }

    for (var i = 0; ; ++i)
    {
        var button  = document.getElementById("button"  + i);
        var options = document.getElementById("options" + i);
        
        if (!button)  break;
        if (!options) continue;
    
        optionsSizes  [options.id] = options.offsetHeight;
        optionsHeights[options.id] = options.offsetHeight;
        
        var newHeight = options.className.match(/\bcurrent\b/)
                          ? optionsSizes[options.id]
                          : 0;
        
        animateOptions(options, newHeight, Number.POSITIVE_INFINITY, 0);
    }
});