var PieMenu = new Class ({
    /* Implements */
    Implements: Events,
    
    /* Default private vars */
    itemHeight: 32,
    itemWidth: 32,
    visible: false,
    effects: true,
    
    /* Functions */
    initialize: function(classNames, menuName, settings) {        
        this.containerClass = classNames;
        this.menu = menuName;
        
        if ($chk(settings))
        {
            this.itemHeight = settings.height;
            this.itemWidth = settings.width;
            if (settings.effects != null)
            {
                this.effects = settings.effects;
            }
        }
        
        // Setup onDomReady event to hookup menu events and stuff
        window.addEvent('domready', this.domReady.bind(this));
        this.fireEvent('onInitialize', [classNames, menuName]);
    },
    
    /* Does funky CSS/Javascript stuff on the <li> elements in our menu. */
    initMenu: function(elemName) {
        var elem = $(elemName);
        elem.style.position = "absolute";
        elem.style.margin = "0px";
        elem.style.padding = "0px";
        elem.style.listStyleType = "none";
        
        var children = elem.getElements('li');
        
        var step = (2.0 * Math.PI) / children.length;
        var rotation = (90 / 180) * Math.PI;
        var radius = this.itemWidth + (children.length * Math.PI);
        
        var i = 0;
        children.each(function(item) {
            var x = Math.cos(i*step - rotation) * radius - (this.itemWidth / 2);
            var y = Math.sin(i*step - rotation) * radius - (this.itemHeight / 2);
            item.style.position = "absolute";
            item.style.display = "block";
            item.style.fontSize = "0px";
            item.style.left = Math.round(x) + "px";
            item.style.top = Math.round(y) + "px";
            i++;
        }, this);
        
        // Since MooTools is a bit picky, we need to set it as hidden *this* way first.
        // This is so we get a transition when we do elem.fade('in') the first time around.
        if (this.effects)
        {
            elem.fade('hide');
        }
    },

    /* Fired after init; runs all the init functions on our private variables. */
    domReady: function() {
        // Setup menu
        this.initMenu(this.menu);
        this.attach();
    },
    
    /*  Attach the onclick handlers and stuff to the containers. */
    attach: function() {
        var selector = "." + this.containerClass;
        var elements = $$(selector);
        
        elements.each(function(elem) {
            elem.addEvent('click', this.show.bind(this));
            window.addEvent('click', this.hide.bind(this));
        }, this);
        
        this.fireEvent('onAttach', elements);
    },
    
    show: function(event) {
        if (this.visible && this.lastContainer == event.target)
        {
            this.hide();
            return true;
        }
        
        // Get scroll and mouse positions.
        var mouse = event.page;
        
        // Setup absolute positions for element and display
        elem = $(this.menu);
        elem.style.left = mouse.x + 'px';
        elem.style.top = mouse.y + 'px';
        
        if (this.effects)
        {
            elem.style.display = 'block';
            elem.fade('in');
        }
        else
        {
            elem.fade('show');
            elem.style.display = 'block';
        }
        
        this.visible = true;
        this.lastContainer = event.target;
        
        this.fireEvent('onShown');
        
        // Return false so window.onclick doesn't get called, and hide the thing automatically.
        return false;
    },
    
    hide: function() {
        elem = $(this.menu);
        
        if (this.effects)
        {
            elem.style.display = 'block';
            elem.fade('out');
        }
        else
        {
            elem.fade('show');
            elem.style.display = 'none';
        }
        
        this.visible = false;
        this.fireEvent('onHide');
    }
});
