
    var ButtonStore = {
        buttons:[],

        getButtonNumber:function()
        {
            return this.buttons.length;
        },

        //-> REGISTER A BUTTON
        register:function(buttonInstance)
        {
            this.buttons.push(buttonInstance);
        },

        //-> UNREGISTER A BUTTON
        unRegister:function(buttonInstance)
        {
            this.buttons = this.buttons.reject(function(d){
                return d == buttonInstance;
            });
        },
        
        create:function(id, _event, _function)
        {
            var button = new ActionButton(id);
            button.addListener(id + "Action", _event, _function);
	        button.enable();
	        
	        return button;
        
        },
        
        destroy:function(buttonInstance)
        {
            if(!Object.isUndefined(buttonInstance))
            {
                buttonInstance.disable();
                buttonInstance.removeAllListeners();
                buttonInstance = null;
            }
        }
      
    };


    var ActionButton = Class.create();
    ActionButton.prototype = {
    
        initialize:function(nodeId)
        {
            this.DOMNode = ($(nodeId) || null);
            this.attachButton = false;
            
            this.isEnable = false;
            this.isLock = false;
            
            
            //-> MENU VARIABLES AND PROPERTIES
            this.menuOpen = false;
            this.menuClassName = "menuButton";
            this.menuContentBuilded = false;
            
            //-> OPTIONS
			this.options = Object.extend({
				
				isLock:false,
				
				//-> MENU OPTIONS
				setupMenu:false,
				menuWidth:150,
				menuOffsetX:0,
				menuOffsetY:0,
				menuDataSource:null,
                menuDisplayFieldName:null,
                menuLinkActions:[],
				
				//-> MENU PROPERTIES NEEDED IN WEBSERVICE DATA MODE
				menuDataRequestActionName:"getData",
				menuDataRequestParameters:[],
				menuLoadingIndicator:null,
	            menuLoadingMessage:null	            
				
			}, arguments[1] || {});
			
			
			this.isLock = this.options.isLock;
			
            //-> LISTENERS_FUNCTION
            this.listenersFunction = {};
            //-> LISTENERS_EVENT_TYPE
            this.listenersEventType = {};
            //-> BIND_LISTENERS_FUNCTION
            this.bindListenersFunction = {};
            
            //->
            this.DOMNode.addClassName("disable");
            this.DOMNode.observe("click", function(e){
                Event.element(e).blur();
            });
            
            //-> REGISTER IN STORE
            ButtonStore.register(this);
            this.DOMId = nodeId;
            
            if(this.options.setupMenu == true && !this.isLock)
            {
                this.buildMenu();
            }
            
        },
        
        update:function(text)
        {
            this.DOMNode.getElementsByTagName("SPAN")[0].innerHTML = text;
        },
                
        getListeners:function()
        {
            for(property in this.listenersFunction)
            {
                alert(property + " = " + this.listenersFunction[property]);
            }
        },
        
        getCountListeners:function()
        {
            var i = 0;
            
            for(property in this.listenersFunction)
            {
                i = i + 1;
            }
            
            return i;
        },
        
        addListener:function(name, type, action)
        {
            if(this.isLock != true)
            {
                this.listenersFunction[name] = action;
                this.listenersEventType[name] = type;
                this.bindListenersFunction[name] = this.listenersFunction[name].bindAsEventListener(this);
            }
            
        },
        
        removeListener:function(name)
        {
            //-> STOP INDIVIDUAL LISTENER FIRST !
            this.stopListener(name);
            
            //alert(this.listenersFunction[name])
            if(Object.isFunction(this.listenersFunction[name]))
            {
                delete this.listenersFunction[name];
                delete this.listenersEventType[name];
                delete this.bindListenersFunction[name];
            }
        },
        
        startListener:function(name)
        {
            if(this.isLock != true)
            {
                if(this.isEnable == true)
                {
                    Event.observe(this.DOMNode, this.listenersEventType[name], this.bindListenersFunction[name]);
                }
                else
                {
                    alert(this.DOMNode.id + " button is currently disable, you can't attach \""+ name +"\" new listener a this moment !");
                }
            }
        },
        
        stopListener:function(name)
        {
            Event.stopObserving(this.DOMNode, this.listenersEventType[name], this.bindListenersFunction[name]);           
        },
        
        removeAllListeners:function()
        {
            //-> STOP ALL LISTENERS FIRST !
            this.disable();

            for(property in this.listenersFunction)
            {
                if(Object.isFunction(this.listenersFunction[name]))
                {
                    delete this.listenersFunction[name];
                    delete this.listenersEventType[name];
                    delete this.bindListenersFunction[name];
                }
            
            }

        },
        
        enable:function()
        {
            //alert(this.DOMNode.id + " -> " + this.isLock)
            if(this.isLock != true)
            {
                if(this.isEnable == false)
                {
                    for(property in this.listenersFunction)
                    {
                        //alert(this.DOMNode.id + " / " + property)
                        Event.observe(this.DOMNode, this.listenersEventType[property], this.bindListenersFunction[property]);
                    
                    }
                    
                    this.DOMNode.removeClassName("disable");
                    this.isEnable = true;
                }
                else
                {
                    alert(this.DOMNode.id + " button is already enable, disable it first !");
                
                }
            }
        },
        
        disable:function()
        {
            if(this.isEnable == true)
            {
                for(property in this.listenersFunction)
                {
                    //this.DOMNode.stopObserving(this.listenersEventType[property], this.bindListenersFunction[property]);
                    Event.stopObserving(this.DOMNode, this.listenersEventType[property], this.bindListenersFunction[property]);           
                }
                
                this.DOMNode.addClassName("disable");
                this.isEnable = false;
            }
        },
        
        //-> MENU METHODS
        buildMenu:function()
        {
            /*
            
		        <ul class="menuButton" style="width:150px">
		            <li><a href="#">Cible par champs</a></li>
		            <li><a href="#">Cible par r&eacute;activit&eacute;</a></li>
		            <li class="last"><a href="#">Cible combin&eacute;e</a></li>
		        </ul>
            
            */
            
            this.menu = new Element("ul", {className:this.menuClassName});
            this.menu.setWidth(this.options.menuWidth);
            this.menu.hide();
            
            //-> INSERT MENU AFTER BUTTON
            this.DOMNode.insert({after:this.menu});
            //-> INIT OPENER_BEHAVIOR
            this.initOpenerBehavior();
        },
        
        initOpenerBehavior:function()
        {
            this.addListener("toggleMenuButton", "click", function(e){this.toggleMenu()});
        },
        
        toggleMenu:function()
        {
            if(this.menuOpen == false)
            {
                this.openMenu();
            }
            else
            {
                this.closeMenu();
            }
        },
        
        openMenu:function()
        {
            if(this.options.menuDataSource != null)
            {
            
                if(!this.menuContentBuilded)
                {
                
                    var parametersPackage = "";
                    //->
                    if(this.options.menuDataRequestParameters.length > 0)
                    {
	                    $A(this.options.menuDataRequestParameters).each(function(param, index){parametersPackage = parametersPackage + "&" + param.key + "=" + param.value}.bind(this));
	                    
	                }
	                
	                //-> DEBUG
	                //alert(parametersPackage);
                    
                    //-> 
                    this.setupBlurBehavior();
                    
                    //-> EMPTY MENU
                    Utils.Element.emptyNode(this.menu);
                
                    //-> WEBSERVICE DATA CALLING MODE
                    if(Object.isString(this.options.menuDataSource))
                    {
                        //-> START LOADING
                        if(this.options.menuLoadingIndicator) this.options.menuLoadingIndicator.enable(this.options.menuLoadingMessage);
                    
                        Utils.Ajax.webServiceCaller({
                            url:this.options.menuDataSource,
                            method:"get",
                            parameters:"action="+ this.options.menuDataRequestActionName + parametersPackage,
                            onLoading:Prototype.emptyFunction,
                            onComplete:function(transport, json)
                            {
                                //-> DISABLE LOADING INDICATOR
                                if(this.options.menuLoadingIndicator) this.options.menuLoadingIndicator.disable();

                                var response = null;

                                try
                                {
                                    response = eval(transport.responseText)[0];
                                    var resultSet = response.records;
                                    
                                    //->
                                    if(resultSet.length > 0)
                                    {
                                        //-> BUILD
                                        this.buildMenuList(resultSet);
                                        
                                        //-> PLACE
                                        this.placeMenu();
                                        
                                        this.DOMNode.addClassName("active");
                                        this.menu.show();
                                        this.menuOpen = true;
                                                      
                                    }
                                    
                                    //-> EMPTY MEMORY
                                    resultSet = response = null;

                                }
                                //-> ERROR MESSAGE MANAGER
                                catch(error)
                                {
                                    Application.webservice.errorManager(transport.responseText);
                                    return;
                                }

                            }.bind(this)
            				
                        });                    
                    
                    }
                    //-> LOCAL DATA CALLING MODE
                    else
                    {
                       //-> TO_DO 
                        
                        
                        
                        
                        
                    }                    
                }
                //-> DATA ALREADY RECOVERED - JUST PLACE IT, SHOW IT
                else
                {
                    //-> PLACE
                    this.placeMenu();
                    
                    this.DOMNode.addClassName("active");
                    this.menu.show();
                    this.menuOpen = true;
                
                }
            }
        
        },
                
        placeMenu:function()
        {
            //-> POSITIONNING
            var coords = this.getButtonPosition();
            
            //-> OFFSET
            coords[0] = coords[0] + this.options.menuOffsetX;
            coords[1] = coords[1] + this.options.menuOffsetY;
            
            //-> SET COORDINATES                         
            this.menu.setStyle({left:coords[0] + "px", top:(coords[1] + this.DOMNode.offsetHeight) + "px"});
        },
        
        buildMenuList:function(data)
        {
            if(this.options.menuDisplayFieldName == null)
            {
                alert("Missing DISPLAY_FIELD_NAME options parameters !");
                return;
            }
            
            /*
                <li><a href="#">Cible par champs</a></li>
            */
        
            $A(data).each(function(record, index){

                var listItem = new Element("li", {className:"menuButton"}).insert({bottom:new Element("a", {href:"javascript:void(0)"}).update(record[this.options.menuDisplayFieldName])});
                if((index + 1) == data.length)
                {
                    listItem.addClassName("last");
                }
                
                //-> INSERT IN MENU
                this.menu.insert({bottom:listItem});
                
                if(this.options.menuLinkActions.length > 0 && (this.options.menuLinkActions[index] != null && Object.isFunction(this.options.menuLinkActions[index].action)))
                {
                    this.initBehavior(listItem, index);
                }
                
            }.bind(this));
            
            //-> VALIDATE BUILDING MENU LIST
            this.menuContentBuilded = true;
            
        },
        
        initBehavior:function(node, index)
        {
            //-> INIT BEHAVIOR
            node.observe("click", function(e){
                e.element().blur();
                this.options.menuLinkActions[index].action();
                this.closeMenu();
            
            }.bindAsEventListener(this));
        
        },
        
        closeMenu:function()
        {
            this.DOMNode.removeClassName("active");
            new Effect.Fade(this.menu, {duration:0.2})
            this.menuOpen = false;
        },
        
        getButtonPosition:function()
        {
            return this.DOMNode.positionedOffset();
        },
        
		setupBlurBehavior:function()
		{
			Event.observe(document, "click", function(e){
				if(this.menuOpen)
				{
					if(e.element().id != this.DOMId && (Utils.Element.getDirectAncestorById(e.element(), this.DOMId) == null) && e.element().className != this.menuClassName && (Utils.Element.getDirectAncestorByClassName(e.element(), this.menuClassName) == null))
					{
						this.closeMenu();
					}
				}
			}.bindAsEventListener(this));
			
		}

    }
   
    var ActionButtonsGroup = Class.create();
    ActionButtonsGroup.prototype = {
    
        initialize:function()
        {
            this.collection = [];
            
            if(Object.isArray(arguments[0]) && arguments[0].length > 0)
            {
               arguments[0].each(function(button){this.add(button)}.bind(this));
            } 
        },
        
        add:function(button)
        {
            this.collection[this.collection.length] = button;
        
        },
        
        enable:function()
        {
            this.collection.each(function(button){if(!button.isEnable) button.enable();});
        },
        
        disable:function()
        {
            this.collection.each(function(button){if(button.isEnable) button.disable();});
        }

    }
