
	// WINBOXES CONTAINER, REGISTER ALL WINBOXES
	
    var WinComponentStore = {
        overlays:[],
        winBoxes:[],
        modalBoxes:[],
        highestZindex:50,
        highestOverlayHeight:0,

        //-> REGISTER A NEW WINBOX
        getWinComponentNumber:function(type)
        {
            return (this[type].length);
        },

        //-> REGISTER A NEW WINBOX
        register:function(winComponentInstance, type)
        {
            this[type].push(winComponentInstance);
        },

        //-> UNREGISTER A NEW WINBOX
        unRegister:function(winComponentInstance, type)
        {
            this[type] = this[type].reject(function(d){
                return d == winComponentInstance;
            });

        },
        
        setOverlaysStyle:function(styleProperties)
        {
            $(this.overlays).each(function(overlayInstance){
                overlayInstance.overlayNode.setStyle(styleProperties);
            }.bind(this));
        },
        
        applyHighestZindex:function()
        {
            var zIndex =  this.highestZindex;
            this.incrementHighestZindex();
            
            return zIndex;
        },
                
        incrementHighestZindex:function()
        {
            this.highestZindex = (this.highestZindex + 1);
        },
        
        //-> USED ONLY FOR IE OVERLAY RESIZE PROBLEM
        setHighestOverlayHeight:function(newHeight)
        {
             this.highestOverlayHeight = Math.max(this.highestOverlayHeight, newHeight) 
        },

        // CLOSE ALL WINBOX
        closeWinBoxes:function()
        {  
            this.winBoxes.each(function(winBox){winBox.close()});
        }
      
    };
    
    var Overlay = Class.create();
    Overlay.prototype = {
    
        initialize:function()
        {
            if(!arguments[0] || !arguments[0].parent || !arguments[0].position)
            {
                alert("Missing overlay insertion parameters !");
                return;
            }
            
            this.parent = arguments[0].parent;
            this.position = arguments[0].position;
            
            //-> OPTIONS
			this.options = Object.extend({
				onClick:Prototype.emptyFunction,	
				background:true,
				backgroundColor:"#525f16"			
				
			}, arguments[1] || {});
            
            this.build();
        },
        
        build:function()
        {
		    //-> WINBOX OVERLAY
		    this.overlayNode = new Element("div", {className:"winBoxOverlay"}).observe("click", function(){
		        //-> START BEFORE OPEN CALLBACK
		        this.options.onClick(this);
		        
		    }.bindAsEventListener(this));
		    
		    //-> HIDE OVERLAY
		    this.overlayNode.hide();
		    //-> INSERT OVERLAY
		    eval("this.parent.insert({" + this.position + ":this.overlayNode})");
		    //-> OVERLAY BACKGROUND
		    if(this.options.background == true)
		    {
		        this.overlayNode.setStyle({backgroundColor:this.options.backgroundColor});
		    }
		    
       }
        
    };
    
    var ModalBox = Class.create();
    ModalBox.prototype = {
    
        initialize:function()
        {                        
            //-> OPTIONS
			this.options = Object.extend({
			    alwaysOnTop:false,
			    positionY:282,
			    message:"No message",
                buttons:[],
				onClickOverlay:Prototype.emptyFunction
								
			}, arguments[0] || {});
            
            
            this.memory = {};
            
            this.buttons = [];
            
            this.pyramidPositionSetup = false;
            this.isOpen = false;
            this.modalBoxNumber = 0;
                        
            this.build();
            
            window.onresize = function()
            {
                this.stretchOverlay();
                
            }.bind(this);

        
        },
        
        build:function()
        {
            /*
                <div class="modalBoxWrapper">
                    <div class="modalBox">
                        <div class="message">Confirmez la suppression 100% des enregistrements s&eacute;lectionn&eacute;s ?</div>
                        <div class="buttons">
                            <a href="#" class="button"><span>Annuler</span></a>
                            <a href="#" class="button"><span>Non</span></a>
                            <a href="#" class="button"><span>Oui</span></a>
                            <div class="clear"></div>
                        </div>
                    </div>
                </div>
            */

		    //-> MODALBOX WRAPPER
		    this.modalBoxWrapper = new Element("div", {className:"modalBoxWrapper"});
		    this.modalBoxWrapper.setTop(this.options.positionY);
		    this.modalBoxWrapper.hide();
		    
		    //-> MODALBOX
		    this.modalBox = new Element("div", {className:"modalBox"});
		    //-> INSERT
		    this.modalBoxWrapper.insert({bottom:this.modalBox});
		    
		    //-> MODALBOX MESSAGE AREA
		    this.messageArea = new Element("div", {className:"message"}).update(this.options.message);
		    //-> INSERT
		    this.modalBox.insert({bottom:this.messageArea});
		    //-> MODALBOX BUTTONS
		    this.buttonsWrapper = new Element("div", {className:"buttons"});
		    //-> INSERT
		    this.modalBox.insert({bottom:this.buttonsWrapper});
		    
		    //-> FINALLY INSERT MODAL_BOX_WRAPPER
		    $(document.body).insert({bottom:this.modalBoxWrapper});
		    
		    //-> CREATE OVERLAY INSTANCE
		    this.modalBoxOverlay = new Overlay({parent:this.modalBoxWrapper, position:"before"}, {
		            backgroundColor:("#000000"),
		            onClick:function()
		            {
		                //-> ON_CLICK_OVERLAY CALLBACK
		                this.options.onClickOverlay(this);
		                //->
		                //alert("Click ModalBox Overlay");
                        new Effect.Pulsate(this.modalBox, {
                            duration:.4,
                            pulses:3

                        });
                        
                                        
		            }.bind(this)
		        }
		    );
		    
		    this.modalBoxOverlay.overlayNode.setOpacity(.2);
		    
		    
            //-> REGISTER OVERLAY IN OVERLAYS STORE
            WinComponentStore.register(this.modalBoxOverlay, "overlays");
	        //-> REGISTER MODALBOX IN MODALBOXES STORE
	        WinComponentStore.register(this, "modalBoxes");
		    
		    //-> GET MODALBOX NUMBER
		    this.modalBoxNumber = WinComponentStore.getWinComponentNumber("modalBoxes")
		    
		    //-> INVARIABLE BUTTONS !!!
	        	    
		    //->
		    //-> BUILD SOURCE WINDOW
		    if(DEBUG_MODE == true && (1 == 0))
		    {
		        var showSourceButtonId = "showSourceButtonN" + this.modalBoxNumber;
		        var showSourceButton = new Element("a", {id:showSourceButtonId, className:"button showSource"}).insert({bottom:new Element("span").update("Show Source")});
		        //-> INSERT SOURCE BUTTON
		        this.buttonsWrapper.insert({bottom:showSourceButton});
		        //-> CREATE ACTION_BUTTON INSTANCE
                this.showSourceButton = new ActionButton(showSourceButtonId);
                this.showSourceButton.addListener(showSourceButtonId, "click", function(e){
				    w = window.open();
				    w.document.write(document.body.innerHTML);	
				    w.document.close();

                }.bind(this));
                this.showSourceButton.enable();
            }
            
		    //-> CUSTOM BUTTONS !!!
            this.buildButtons(this.options.buttons);
                       
            //-> CLEAR BUTTONS DIVISION
		    this.clearDivision = new Element("div", {className:"clear"});
		    //-> INSERT
		    this.buttonsWrapper.insert({bottom:this.clearDivision});
		    
		    
       	},
       
       	toString:function()
       	{
            return ("ModalBox " + this.modalBoxNumber);
       	},
       
      	buildButtons:function(collection)
       	{
       
            //-> EMPTY MODALBOX BUTTONS - EXCEPT DEBUG_SHOW_SOURCE
            this.buttons.each(function(buttonInstance){
                //-> STOPOBSERVING
                buttonInstance.removeListener(buttonInstance.DOMNode.id);
                //-> REMOVE DOM NODE
                buttonInstance.DOMNode.remove();
                //-> DESTROY INSTANCE
                buttonInstance = null;
                delete buttonInstance;
                
            });
            //-> REALLY EMPTY BUTTON INSTANCES COLLECTION
            this.buttons = [];
       
            var propertiesCollection = collection;
       
            //-> INVERT LOOP - CAUSE TO FLOAT:RIGHT CSS POSITIONNING
            var count = 0;
		    for(i=0; i<(propertiesCollection.length); i++)
		    //for(i = (propertiesCollection.length - 1); i>=0; i--)
		    {
		        var buttonProperties = propertiesCollection[i];
		    
		        var currentButtonId = buttonProperties.codeName + "ButtonN" + this.modalBoxNumber;
		        var currentButtonNode = new Element("a", {id:currentButtonId, className:"button"}).insert({bottom:new Element("span").update(buttonProperties.label)});
		        //-> INSERT SOURCE BUTTON
		        this.buttonsWrapper.insert({top:currentButtonNode});
		        
		        //-> CREATE ACTION_BUTTON INSTANCE
                this.buttons[count] = new ActionButton(currentButtonId);
                this.setActionButton(this.buttons[count], currentButtonId, buttonProperties.action, buttonProperties.noClosure);
                this.buttons[count].enable();
                
                count = count + 1;	    
		    }
       	},
       
       	setActionButton:function(buttonInstance, id, action, noClosure)
       	{
            buttonInstance.addListener(id, "click", function(e){
                if(!noClosure) this.close();
                if(Object.isFunction(action)) action(this); 

            }.bind(this));
       	},
       
       	open:function(configuration)
       	{
            if(!this.isOpen)
            {
            
                //-> Z-INDEX MANAGEMENT
                if(this.options.alwaysOnTop == false)
                {
		            //-> WIN PYRAMID POSITION MANAGEMENT
		            if(!this.pyramidPositionSetup)
		            {
	                    //-> OVERLAY Z-INDEX
	                    this.modalBoxOverlay.overlayNode.setStyle({zIndex:WinComponentStore.applyHighestZindex()});
			            //-> WINBOX WRAPPER Z-INDEX
			            this.modalBoxWrapper.setStyle({zIndex:(WinComponentStore.applyHighestZindex())});
    			        
                        //-> SET PYRAMID_POSITION_SETUP TO TRUE
			            this.pyramidPositionSetup = true;
		            }
		        }
		        else
		        {
                    //-> OVERLAY Z-INDEX
                    this.modalBoxOverlay.overlayNode.setStyle({zIndex:WinComponentStore.applyHighestZindex()});
		            //-> WINBOX WRAPPER Z-INDEX
		            this.modalBoxWrapper.setStyle({zIndex:(WinComponentStore.applyHighestZindex())});
		        }
		        
		        //-> CONFIGURATION
		        if(!Object.isUndefined(configuration))
		        {
		            //-> MESSAGE
		            if(!Object.isUndefined(configuration.message))
		            {
		                this.messageArea.update(configuration.message);
		            }
		            
		            //-> BUTTONS
		            if(!Object.isUndefined(configuration.buttons) && configuration.buttons.length > 0)
		            {
		                this.buildButtons(configuration.buttons);
		            }
		            
		            //-> SPECIFIC DATA
		            if(!Object.isUndefined(configuration.data))
		            {
		                this.memory = configuration.data;
		            }		        
		        }
    		    
                this.modalBoxWrapper.show();
                this.stretchOverlay();
                this.modalBoxOverlay.overlayNode.show();
                
                this.isOpen = true;
            
            }
       	},
        
       	close:function()
       	{
            if(this.isOpen == true)
            {
                this.modalBoxWrapper.hide();
                this.modalBoxOverlay.overlayNode.hide();
                
                this.isOpen = false;
            }
       	},
       
		stretchOverlay:function()
		{
            //-> GET PAGE SIZE
            var arrayPageSize = Utils.Document.getPageSize();
            
            //-> MANAGE HEIGHT - MORE DIFFICULT
            var currentWinBoxWrapperHeight = this.options.positionY + this.modalBoxWrapper.getHeight();
            
            if((arrayPageSize[1] < currentWinBoxWrapperHeight))
            {
                arrayPageSize[1] = currentWinBoxWrapperHeight;
                WinComponentStore.setHighestOverlayHeight(currentWinBoxWrapperHeight);
            }
            else
            {
                if(WinComponentStore.highestOverlayHeight != 0)
                {
                    arrayPageSize[1] = WinComponentStore.highestOverlayHeight;
                }
            }
            //-> AFFECT HEIGHT
            WinComponentStore.setOverlaysStyle({height:arrayPageSize[1] + "px"});
		
		},
		
		updateMessage:function(message)
		{
			this.messageArea.update(message);
		},
		
		disableButtons:function()
		{
			for(i=0; i<this.buttons.length; i++) this.buttons[i].disable();
		},
		
		enableButtons:function()
		{
			for(i=0; i<this.buttons.length; i++) this.buttons[i].enable();
		}
        
        
    };


    var WinBox = Class.create();
    WinBox.prototype = {
    
        VERSION:"1.6.0",
        SCRIPT_TAG_SUFFIX_ID:"_ScriptFile",
        BEHIND_PAGE_SUFFIX:"BehindPage",
        PAGE_ADAPTATER_CODENAME:"PageAdaptater",
    
        initialize:function()
        {
			if(!arguments[0])
			{
				alert("Missing configuration parameters !")
			}
			
			//-> [0] => prefix, [1] => template, [2] => behindPage, [3] => pageAdaptaterJsFiles, [4] => pageClassName
			this.config = arguments[0];
			//-> PAGE_ADAPTATER_JS_FILE - OBJECT TYPE
			this.pageAdaptaters = {};
			
			//-> INIT WITNESS VARIABLES
			this.initWitnessVariables();
			
			this.appearDuration = .2;
			this.overlayOpacity = .2;
			this.openOrigin = {};
			this.isOpen = false;
			this.defaultWidth = 650;
			
			this.currentPageSizes = [];
			this.pyramidPositionSetup = false;
			
			this.allAttachJsFilesLoaded = false;
			//->
			this.nbPageAdaptaterLoaded = 0;
			this.openWinBoxCustomCallback = null;

            //-> OPTIONS
			this.options = Object.extend({
				width:0,
				height:0,
				position:{x:null, y:null},
				requestParameters:[],
	            classNames:[],
				loadingIndicator:null,
				overlay:false,
				overlayBackgroundColor:"#000000",
				opacityAnimation:false,
				alwaysOnTop:false,
				
				onload:Prototype.emptyFunction,
				beforeOpen:Prototype.emptyFunction,
				onOpen:Prototype.emptyFunction,
				beforeClose:Prototype.emptyFunction,
				afterClose:Prototype.emptyFunction,
				onXHTMLSqueletonBuilded:Prototype.emptyFunction
				
				
			}, arguments[1] || {});
			
			//-> BUILD WIN
			this.build();
			
        },
        
        initWitnessVariables:function()
        {
            this.winBoxIsBuilded = false;

            this.templateResultSet = null;
            this.templateLoaded = false;
            
            //-> PAGE_JS WITNESSES
            this.pageScriptDOMInsertion = false;
            this.behindPageIsLoaded = false;
            this.pageJsLoadVerifications = 0;
            
            
            this.pageAdaptaterJsFileIsLoaded;
            
			//-> INIT PAGE_ADAPTATER WITNESSES
			//-> ADD 2 properties : scriptDOMInsertion and loaded
			this.config.pageAdaptaterJsFiles.each(function(adaptaterProperties, index){
			    
			    var id = ("_" + (index+1));
			    this.pageAdaptaters[id] = {
			    
			        id:id,
			        url:adaptaterProperties.url,
			        scriptDOMInsertion:false,
			        loaded:false
			        
			    };
			
			}.bind(this));
			
			this.currentAdaptaterId = this.getAdaptaterIdByIndex(0);
			
            this.XHTMLSqueleton = "";
            this.XHTMLSqueletonBuilded = false;
            
            this.firstTimeLoad = true;
        },
        
        
        getCurrentAdaptater:function(n)
        {
            return this.pageAdaptaters[n];
        },
        
        setWinBoxTitle:function(title)
        {
            this.title.update(title);
        },
        
        getWinBoxBorderWidth:function()
        {
            if(this.winBox)
            {
			    var winBoxBorderWidth = {
			        t:this.winBox.getStyle("borderTopWidth"),
			        r:this.winBox.getStyle("borderRightWidth"),
			        b:this.winBox.getStyle("borderBottomWidth"),
			        l:this.winBox.getStyle("borderLeftWidth")
			    };
    			
			    for(property in winBoxBorderWidth)
			    {
			        winBoxBorderWidth[property] = parseInt(winBoxBorderWidth[property].replace("px", ""), 10);
			    }
    			
			    return winBoxBorderWidth;
			
			}
			else
			{
			    alert("WINBOX DOESN'T EXIST");
			    return {t:0, r:0, b:0, l:0};
			}
        },
		
		build:function()
		{
			/*
			    <div class="overlay"></div>
			    
			    <div class="winBoxWrapper">
				    <div class="winBox" style="width:600px; height:395px; top:300px; margin-left:-300px; z-index:45;">
					    <div class="winBoxTitle"></div>
					    <div class="winBoxBody"></div>
				    </div>
				</div>
			*/
			
			var winBoxWidth = (this.options.width != 0?this.options.width:this.defaultWidth);
			
			
			//-> WINBOX WRAPPER
			this.winBoxWrapper = new Element("div", {className:"winBoxWrapper"});
			
		    //-> //////////////////////////////////////////////////////
		    this.winBoxWrapper.addClassName("hide");
		    
		    			    
			//-> INSERT
            $(document.body).insert({bottom:this.winBoxWrapper});
			
		    //-> WINBOX LEFT POSITION
		    if(this.options.position && this.options.position.x != null)
		    {
		        this.winBoxWrapper.setLeft(this.options.position.x);
		    }
		    //-> WINBOX TOP POSITION
		    if(this.options.position && this.options.position.y != null)
		    {
		        this.winBoxWrapper.setTop(this.options.position.y);
		    }
			
			
			//-> WINBOX
			this.winBox = new Element("div", {className:"winBox"});
			//-> INSERT
			this.winBoxWrapper.insert({top:this.winBox});
			//-> GET BORDER WIDTH
			var winBoxBorderWidth = this.getWinBoxBorderWidth();
			
			//-> OVERLAY
			if(this.options.overlay == true)
			{
			    //-> CREATE OVERLAY INSTANCE
			    this.winBoxOverlay = new Overlay({
			            parent:this.winBoxWrapper,
			            position:"before"
			        },
			        {
			            backgroundColor:(this.options.overlayBackgroundColor)
			        }
			    )
			}
			
	        //-> REGISTER OVERLAY IN OVERLAYS STORE
	        WinComponentStore.register(this.winBoxOverlay, "overlays");
	        //-> REGISTER WINBOX IN WINBOXES STORE
	        WinComponentStore.register(this, "winBoxes");
	        
			
			//-> WINBOX OPTIONAL CSSCLASSES
			if(this.options.classNames.length > 0)
			{
				$A(this.options.classes).each(function(className){this.winBox.addClassName(className);}.bind(this));
			}
			
			//-> WINBOX WIDTH
			this.winBox.setStyle({width:(winBoxWidth + "px")});
						
			//-> WINBOX HEADER
			this.header = new Element("div", {className:"winBoxHeader"});
			this.winBox.insert({bottom:this.header});
			this.header.setStyle({
			    width:winBoxWidth + "px"
			});
			
			//-> WINBOX TITLE
			this.title = new Element("div", {className:"winBoxTitle"});
			this.winBox.insert({bottom:this.title});
			
			
			//-> WINBOX CLOSE BUTTON, INCLUDE IN HEADER
			var closeButton = new Element("a", {id:(this.config.prefix + "CloseButton"), className:"winBoxCloseButton"}).update("Fermer");
			this.header.insert({bottom:closeButton});
			this.closeButton = ButtonStore.create(closeButton.id, "click", this.close.bindAsEventListener(this));
			
			//-> WINBOX BODY
			this.body = new Element("div", {className:"winBoxBody"});
			this.winBox.insert({bottom:this.body});
			
		    this.winBoxWrapper.hide();
		    this.winBoxWrapper.removeClassName("hide");
		    
			//-> 
			this.winBoxIsBuilded = true;

		},
						
		loadTemplate:function(pageTitle)
		{
			if(this.config.template && this.config.template != "")
			{
				//-> START LOADING
				if(this.options.loadingIndicator)
				{
					this.options.loadingIndicator.enable("Chargement du gabarit, veuillez patienter.");
				}

				//-> SCAN FOR REQUEST PARAMETERS
				var requestParameters = "";
				if(this.options.requestParameters.length > 0)
				{
                    $A(this.options.requestParameters).each(function(param){               
                        
                        requestParameters += ("&" + param.key + "=" + param.value);
                    
                    }.bind(this));
                }

				Utils.Ajax.webServiceCaller({
					url:this.config.template,
					method:"get",
					parameters:"action=getTemplate" + requestParameters,
					onLoading:Prototype.emptyFunction,
					onComplete:function(transport){
						
						var response = transport.responseText;
						
						//-> DISABLE LOADING INDICATOR
						if(this.options.loadingIndicator)
						{
							this.options.loadingIndicator.disable();
						}
						
						//-> ERROR MESSAGE MANAGER
						try
						{
							this.templateResultSet = response;
							this.templateLoaded = true;
							//alert(this.templateResultSet)
                            
							//-> BUILD PAGE SQUELETON
							this.buildXHTMLSqueleton(pageTitle);
						}
						catch(error)
						{
							Application.webservice.errorManager(response);
							return;
						}
					}.bind(this)
					
				});           
				
			}
			
			
		},
		
		buildXHTMLSqueleton:function(pageTitle)
		{
		
		    if(!this.XHTMLSqueletonBuilded)
		    {
			    //-> EMPTY BODY
			    Utils.Element.emptyNode(this.body);
    			
			    this.XHTMLSqueleton = this.purgeWebserviceTemplate();
    			
			    //-> SET TITLE
			    this.title.update("");
			    //-> SET BODY CLASS
			    this.body.addClassName(this.config.pageClassName);
    			
			    //-> ADD XHTML CDATA TO WINBOX BODY
			    this.body.update(this.XHTMLSqueleton);
			    this.XHTMLSqueletonBuilded = true;
			    //-> RESTORE TO EMPTY VALUE, TO OPTIMIZE MEMORY
			    this.XHTMLSqueleton = "";
			    
			    //-> ON_XHTML_SQUELETON_BUILDED CALLBACK
			    this.options.onXHTMLSqueletonBuilded(this);
			    			    
			}
			
		    //-> SET TITLE
		    if(!Object.isUndefined(pageTitle) && pageTitle != "")
		    {
		        this.title.update(pageTitle);
		    }
		    
			//-> START LOADING
			if(this.options.loadingIndicator && !this.allAttachJsFilesLoaded) this.options.loadingIndicator.enable("Chargement des scripts associ&eacute;s.");
			
			//-> START SCRIPT EVALUATION
			this.evalScriptInstructions();
		    			
		},
		
		purgeWebserviceTemplate:function()
		{
			//-> CREATE TEMP CONTENT DIVISION
			var tempContent = new Element("div").update(this.templateResultSet).hide();
			$(document.body).insert({bottom:tempContent});
			
			//-> SAVE CONTENT
			var purgeContent = tempContent.getElementsByClassName("template")[0].innerHTML;
			
			//-> EMPTY AND DESTROY TEMP ELEMENT
			tempContent.update("");
			tempContent.remove();
			
			//-> RETURN XHTML TEMPLATE CONTENT
			return purgeContent;
		
		},
				
		scriptTagCreation:function(properties, adaptater, adaptaterId)
		{
		    /*
		        properties = {
		            id -> @string
		            url -> @url
		            DOMInsertionComplete -> @string -> represent an object property
		        }
		    */
		    
	        if(Object.isUndefined(properties.id) || Object.isUndefined(properties.url))
	        {
	            alert("Missing parameters !");
	            return;
	        }
		    
            var head = document.getElementsByTagName("head")[0];
            var script = document.createElement("script");
            script.id = properties.id + this.SCRIPT_TAG_SUFFIX_ID;
            script.type = "text/javascript";
            script.src = properties.url;
                        
            head.appendChild(script);
            
            
            //-> CHANGE STATUS
            if(!adaptater)
            {
                this[properties.DOMInsertionComplete] = true;
            }
            else
            {
                this.pageAdaptaters[adaptaterId][properties.DOMInsertionComplete] = true;
            }
		
		},
		
		pageLoadChecker:function()
		{
		    
            //-> LOAD PAGE JS INSTRUCTIONS
            if(!this.pageScriptDOMInsertion)
            {
                this.scriptTagCreation({id:(this.config.prefix + this.BEHIND_PAGE_SUFFIX), url:this.config.behindPage.url, DOMInsertionComplete:"pageScriptDOMInsertion"});
            }
            
            if(this.behindPageIsLoaded == false)
            {
                setTimeout(function(){
                    this.pageJsLoadVerifications = this.pageJsLoadVerifications + 1;
                    this.evalScriptInstructions();
                    
                }.bind(this), 50);
            }
            else
            {
                this.behindPageIsLoaded = true;
            }		
		},
		
		adaptaterLoadChecker:function(adaptaterId)
		{
            var currentAdaptater = this.pageAdaptaters[adaptaterId];
            
            //alert(adaptaterId + " scriptDOMInsertion = " + currentAdaptater.scriptDOMInsertion + "\n" + adaptaterId + " loaded = " + currentAdaptater.loaded)

            //-> LOAD PAGE JS INSTRUCTIONS
            if(currentAdaptater.scriptDOMInsertion == false)
            {
                this.scriptTagCreation({
                    id:currentAdaptater.id,
                    url:currentAdaptater.url,
                    DOMInsertionComplete:"scriptDOMInsertion"
                }, true, adaptaterId);
            }
            
	        if(currentAdaptater.loaded == true)
	        {
	            this.nbPageAdaptaterLoaded = this.nbPageAdaptaterLoaded + 1;
	        }
	        
	        setTimeout(function(){this.evalScriptInstructions();}.bind(this), 50);
		
		},
		
		getAdaptaterIdByIndex:function(index)
		{
		    var matchId = "";
		    var count = 0;
		    for(property in this.pageAdaptaters)
		    {
		        if(count == index)
		        {
		            matchId = property;
		            break;
		        
		        }
		    
		        count = count + 1;
		    }
		    
		    return matchId;
		},
		
		evalScriptInstructions:function()
		{
		
            //-> CASE 1 -> WE HAVE ONE OR SEVERAL ADAPTATERS
            if(this.config.pageAdaptaterJsFiles.length != 0)
            {
                if(this.nbPageAdaptaterLoaded < (this.config.pageAdaptaterJsFiles.length))
                {
                    this.adaptaterLoadChecker(this.getAdaptaterIdByIndex(this.nbPageAdaptaterLoaded));
                }
                //-> STEP 2 -> ALL ADAPTATER ARE LOADED, NOW LOAD PAGE_JS_FILE IF NEEDED
                else
                {
                
		            if(!Object.isUndefined(this.config.behindPage))
		            {
	                    this.pageLoadChecker();
                    }
                }
                
            }
            //-> CASE 2 -> NO ADAPTATER
            else
            {
		        if(!Object.isUndefined(this.config.behindPage))
		        {
	                this.pageLoadChecker();
                }
            }
            
            //-> FINAL VERIFICATION PROCESS
            //-> ////////////////////////////////////////////////////////////////////////////////////////////////
            
            //-> CASE 1 -> WE HAVE ONE OR SEVERAL ADAPTATERS
            if(this.config.pageAdaptaterJsFiles.length != 0)
            {
                
                //-> CASE 1.1 -> ALL ADAPTATERS ARE LOADED
                if(this.nbPageAdaptaterLoaded == (this.config.pageAdaptaterJsFiles.length))
                {
                    //-> CASE 1.1.1 -> WE HAVE A PAGE_JS_FILE
                    if(!Object.isUndefined(this.config.behindPage))
                    {
                        //-> CASE 1.1.1.1 -> PAGE_JS_FILE IS LOAD
                        if(this.behindPageIsLoaded == true)
                        {
                            this.showWinBox();
                        }
                    }
                    //-> CASE 1.1.2 -> NO PAGE_JS_FILE
                    else
                    {
                        this.showWinBox();
                    }
                }
            }
            
            //-> CASE 2 -> NO ADAPTATER
            else
            {
                //-> CASE 2.1 -> WE HAVE A PAGE_JS_FILE
                if(!Object.isUndefined(this.config.behindPage))
                {
                    //-> CASE 2.1.1 -> PAGE_JS_FILE IS LOAD
                    if(this.behindPageIsLoaded == true)
                    {
                        this.showWinBox();
                    }
                }
                //-> CASE 2.2 -> NO PAGE_JS_FILE
                else
                {
                    //-> DEBUG
                    this.showWinBox();
                }
            }
		},
				
		showWinBox:function()
		{
            //-> START DESIRED ADAPTATER - WE ARE SURE THAT ALL ADAPTATERS ARE LOADED HERE !
            eval(this.config.prefix + this.PAGE_ADAPTATER_CODENAME + this.getCurrentAdaptater(this.currentAdaptaterId).id.substr(1) + "['initAdaptater']()");     

            if(!this.allAttachJsFilesLoaded) this.allAttachJsFilesLoaded = true;
			//-> START LOADING
			if(this.options.loadingIndicator && !this.allAttachJsFilesLoaded) this.options.loadingIndicator.disable();

            this.options.onOpen(this);
                       
            //-> CUSTOM CALLBACK
            if(this.openWinBoxCustomCallback != null)
            {
                this.openWinBoxCustomCallback();
                
                //-> EMPTY MEMORY
                this.openWinBoxCustomCallback = null;
            }

            //-> SHOW WINBOX
            //-> IF FIRST TIME SHOW WINBOX WHITHOUT EFFECT
            if(this.firstTimeLoad == true)
            {
                //-> HACK USED ONLY FOR GECKO ENGINE.
                //-> AT THIS MOMENT IT DOESN'T MATTER CAUSE WE ADD SPECIAL CSS RULE : overflow:-moz-scrollbars-vertical;
                //-> ONLY FOR GECKO ENGINE.
                //-> THIS PROPERTY MADE VERTICAL SCROLLBAR ALWAYS PRESENT LIKE IN IE
                //-> WinComponentStore.setOverlaysStyle({width:"0"});
                
                this.winBoxWrapper.show();
                if(this.options.overlay == true)
                {
                    this.stretchOverlay();
                    this.winBoxOverlay.overlayNode.show();
                    this.winBoxOverlay.overlayNode.setOpacity(this.overlayOpacity);
                }


                //-> TURN TO FALSE, FIRST_TIME_LOAD
                this.firstTimeLoad = false;
            }
            else
            {
        
                this.winBoxWrapper.show();
                if(this.options.overlay == true)
                {
                    this.stretchOverlay();
                    this.winBoxOverlay.overlayNode.show();
                }
                else
                {
                    this.winBoxWrapper.show();
                }
            }		
		},
		
		stretchOverlay:function()
		{
		    if(this.options.overlay)
		    {
                //-> GET PAGE SIZE
                var arrayPageSize = Utils.Document.getPageSize();
                //-> DOESN'T NEED TO RESIZE OVERLAY IN WIDTH IN FACT...
                //-> MANAGE WIDTH - NO PROBLEM FOR THIS PROPERTY...
                //WinComponentStore.setOverlaysStyle({width:arrayPageSize[0] + "px"});
                
                //-> MANAGE HEIGHT - MORE DIFFICULT
                var currentWinBoxWrapperHeight = this.options.position.y + this.winBoxWrapper.getHeight();
                
                if((arrayPageSize[1] < currentWinBoxWrapperHeight))
                {
                    arrayPageSize[1] = currentWinBoxWrapperHeight;
                    WinComponentStore.setHighestOverlayHeight(currentWinBoxWrapperHeight);
                    
                }
                else
                {
                    if(WinComponentStore.highestOverlayHeight != 0)
                    {
                        arrayPageSize[1] = WinComponentStore.highestOverlayHeight;
                    }
                }
                //-> AFFECT HEIGHT
                WinComponentStore.setOverlaysStyle({height:arrayPageSize[1] + "px"});
                
            }
		
		},
		
		open:function(openCustomCallback, openOrigin, pageTitle, adaptaterId)
		{
		    if(!this.isOpen)
		    {
		        if(openOrigin) this.openOrigin = openOrigin;
		    
		        this.options.beforeOpen(this);
		        if(Object.isFunction(openCustomCallback))
		        {
		            this.openWinBoxCustomCallback = openCustomCallback;
		        }
		        
		        //-> ADAPTATER
		        if(!Object.isUndefined(adaptaterId))
		        {
		            this.currentAdaptaterId = adaptaterId;
		        }
		        else
		        {
		            this.currentAdaptaterId = this.getAdaptaterIdByIndex(0);
		        }
		        
		        if(!this.winBoxIsBuilded)
		        {
		            this.build();
		        }
		        
		        //-> TEMPLATE IS NOT YET LOADED, LOAD IT
			    if(!this.templateLoaded)
			    {
			        this.loadTemplate(pageTitle);
			    }
		        //-> TEMPLATE IS ALREADY LOADED, TRY TO LOAD SCRIPT INSTRUCTIONS IF IT IS NOT ALREADY LOAD
			    else
			    {
			        this.buildXHTMLSqueleton(pageTitle);
			    }
			    
			    if(!this.options.alwaysOnTop)
			    {
			        //-> WIN PYRAMID POSITION MANAGEMENT
			        if(!this.pyramidPositionSetup)
			        {
		                //-> OVERLAY Z-INDEX
		                this.winBoxOverlay.overlayNode.setStyle({zIndex:WinComponentStore.applyHighestZindex()});
			            //-> WINBOX WRAPPER Z-INDEX
			            this.winBoxWrapper.setStyle({zIndex:(WinComponentStore.applyHighestZindex())});
    			        
			            //-> SET PYRAMID_POSITION_SETUP TO TRUE
			            this.pyramidPositionSetup = true;
			        }
			    }
			    
			    //-> IN THIS CASE, WE ALWAYS INCREMENT Z-INDEX, IN ORDER TO PUT WINBOX ALWAYS ON TOP
			    else
			    {
	                //-> OVERLAY Z-INDEX
	                this.winBoxOverlay.overlayNode.setStyle({zIndex:WinComponentStore.applyHighestZindex()});
		            //-> WINBOX WRAPPER Z-INDEX
		            this.winBoxWrapper.setStyle({zIndex:(WinComponentStore.applyHighestZindex())});
			    
			    }
			    
			    this.isOpen = true;
			}
					
		},
		
		beforeWinBoxClosure:function(customCallback)
		{
            //-> START BEFORE CLOSE CALLBACK
            this.options.beforeClose(this);
            //-> CUSTOM CALLBACK
            if(customCallback && typeof(customCallback) == "function")
            {
                customCallback();
            }
		
		},
		
		afterWinBoxClosure:function(reInstall)
		{
            //-> START AFTER CLOSE CALLBACK
            this.options.afterClose(this);
            this.isOpen = false;
            
            if(reInstall == true)
            {
                this.initWitnessVariables();
                
                if(this.options.overlay == true)
                {
                    //-> UNREGISTER WINBOX IN STORE
                    WinComponentStore.unRegister(this.winBoxOverlay, "overlays");
                    this.winBoxOverlay.overlayNode.remove();
                    this.winBoxOverlay = null;
                }
                
                this.title.remove();
                this.body.remove();
                this.winBox.remove();
                this.winBoxWrapper.remove();
                //-> DESTROY DOM REFERENCES
                this.title = null;
                this.body = null;
                this.winBox = null;
                this.winBoxWrapper = null;
                //-> UNREGISTER WINBOX IN STORE
                WinComponentStore.unRegister(this, "winBoxes");
            }
		
		},
		
		close:function(customCallback, reInstall)
		{
		    if(this.isOpen)
		    {
		    
                if(this.options.overlay == true)
                {
                    if(this.options.opacityAnimation)
                    {
	                    new Effect.Parallel(
		                    [
		                        new Effect.Fade(this.winBoxOverlay.overlayNode, {duration:this.appearDuration}),
		                        new Effect.Fade(this.winBoxWrapper, {sync:true, duration:this.appearDuration})
		                    ], 
		                    {
		                        duration:this.appearDuration,
		                        beforeStart:function()
		                        {
            		                this.beforeWinBoxClosure(customCallback);
                		            
		                        }.bind(this),
        		                
		                        afterFinish:function()
		                        {
            		                this.afterWinBoxClosure(reInstall);
                		            
		                        }.bind(this)		                
        		                
		                    } 
	                    );
	                }
	                else
	                {
	                    this.beforeWinBoxClosure(customCallback);
	                    
	                    this.winBoxOverlay.overlayNode.hide();
	                    this.winBoxWrapper.hide();
	                    
	                    this.afterWinBoxClosure(reInstall);
	                }
	            }
	            else
	            {
	                if(this.options.opacityAnimation)
	                {
	                    new Effect.Fade(this.winBoxWrapper, {
	                        duration:this.appearDuration,
	                        beforeStart:function()
	                        {
	                            this.beforeWinBoxClosure(customCallback);
            		        
	                        }.bind(this),
    		                
	                        afterFinish:function()
	                        {
        		                this.afterWinBoxClosure(reInstall);
            		            
	                        }.bind(this)		                    
    	                    
	                    });
	                }
	                else
	                {
	                    this.beforeWinBoxClosure(customCallback);
	                    
	                    this.winBoxWrapper.hide();
	                    
	                    this.afterWinBoxClosure(reInstall);
	                }
	            
	            }
		    
		    }
		
		}
		

    }