
    var Helper = {
    
        // PRIMITIVE
	    bindRootObject:function(obj)
	    {
		    var root = this;
		    for(property in obj)
		    {
			    if(obj[property] && obj[property] != this && typeof(obj[property]) == "object")
			    {
				    //alert("this is an object : " + property + " = " + obj[property] + ", " + typeof(obj[property]));
				    obj[property]["root"] = root;
				    /* RECURSIVE FUNCTION */
				    this.bindRootObject(obj[property]);
			    }
		    }
	    },
        
	    bindRootObjectInCollection:function(obj, collection)
	    {
		    var root = this;
		    
		    for(var i = 0; i<collection.length; i++)
		    {
		        collection[i].root = root;
		    }
	    },
        
	    getObjPropertyByKeyInArray:function(_array, key)
	    {
	        var p;
	        
		    for(var i=0; i<_array.length; i++)
		    {
		        if(!Object.isFunction(_array[i].key))
		        {
		            //alert(_array[i] + "\n" + _array[i].key +" == "+ key);
			        if(_array[i].key == key)
			        {
			            p = _array[i];
				        break;
			        }
			    }
		    }
		    
		    return p;
	    },
        
        // FORM
	    postDataPackageSerializer:function(dataList)
	    {
	        var postPackage = {};
	        dataList.each(function(data){
	            if(Object.isArray(data.value))
	            {
	                data.value.each(function(_item, index){
	                    data.value[index] = encodeURIComponent((!Object.isString(data.value[index])?String(data.value[index]):data.value[index]));
	                });
		            
	                postPackage[data.key + "[]"] = data.value;
	            }
	            else
	            {
	                postPackage[data.key] = encodeURIComponent((!Object.isString(data.value)?String(data.value):data.value));
	            }
	        });
		    
	        return postPackage;
	    },
		
	    nodesReferenceCollector:function(root, _class)
	    {
	        var obj = {};
	        var formNodes = root.select("." + _class);
		
            $A(formNodes).each(function(node){
                if(!node.id) $(node).identify()
                obj[node.id] = $(node);
                
            }.bind(this));
            
            return obj;	
	    },
    
	    nodesValueProvider:function(obj, keyValueFormat)
	    {
	        // IF KEY_VALUE_FORMAT IS TRUE, METHOD RETURN AN ARRAY OF KEY/VALUE OBJECTS LIKE THIS : [ {key:#NODE_ID#, value:#NODE_VALUE#}, {key:#NODE_ID#, value:#NODE_VALUE#}, ... ]
	        // ELSE METHOD RETURN A SIMPLE OBJECT
	    
            var data = (!keyValueFormat?{}:[]);
            for(property in obj)
            {
                if(Object.isFormElement(obj[property]))
                {
                    var tag = obj[property].tagName;
    	            
                    switch(tag)
                    {
                        case "SELECT":
                        {
                            var combo = obj[property];
                            data[(!keyValueFormat?property:data.length)] = !keyValueFormat?this.getComboSelectedValue(combo):{key:property, value:this.getComboSelectedValue(combo)};
                        
                            break;
                        }   
                        default:
                        {
                            data[(!keyValueFormat?property:data.length)] = !keyValueFormat?obj[property].value:{key:property, value:obj[property].value};
                        }
                    }
                }
            }
            
            return data;	
	    },
	    
	    keyValueFormatProvider:function(/* object */ obj)
	    {
	        var data = [];
	        for(property in obj)
	        {
	            data[data.length] = {key:property, value:obj[property]}
	        }
	        
	        return data;
	    },
	    
        toogleFormFields:function(collection, status)
        {   
            if(Object.isFormElement(collection))
            {
                eval("collection." + (!status?"disable":"enable") + "()");
            }
            else
            {
                for(property in collection)
                {
                    if(Object.isFormElement(collection[property]))
                    {
                        eval("collection[property]." + (!status?"disable":"enable") + "()");
                    }
                }
            }
        },
                
        resetForm:function(collection, exclusion)
        {   
            if(!Object.isUndefined(collection))
            {
                for(node in collection)
                {
                    // EXCLUSION
                    var fieldIsExcluded = false;
                    
                    if(!Object.isUndefined(exclusion) && Object.isArray(exclusion))
                    {
                        for(var i=0; i<exclusion.length; i++)
                        {
                            if(exclusion[i] == node)
                            {
                                fieldIsExcluded = true;
                                break;
                            }
                        }
                    }
                
                    if(!fieldIsExcluded)
                    {
                        if(Object.isFormElement(collection[node]))
                        {
                            if(collection[node].tagName != "SELECT")
                            {
                                collection[node].value = "";
                            }
                            else
                            {
                                collection[node].selectedIndex = 0;
                            }
                        }
                        else
                        {
                            if(collection[node].hasClassName("readonlyInput")) collection[node].update("");
                        }
                    }
                }
            }
        },
        
        checkFormElementsEmpty:function(collection)
        {
            var atLeastOneEmpty = false;
            
            if(!Object.isUndefined(collection))
            {
                for(node in collection)
                {
                    if(Object.isFormElement(collection[node]))
                    {
                        if(collection[node].tagName != "SELECT")
                        {
                            if(collection[node].value == "" || collection[node].value == " ")
                            {
                                atLeastOneEmpty = true;
                                break;
                            }
                        }
                        else
                        {
                            if(collection[node].selectedIndex == 0)
                            {
                                atLeastOneEmpty = true;
                                break;
                            }
                        }
                    }
                }
            }
            
            return atLeastOneEmpty;
        },
        
        updateFormFields:function(response, fields, exclusion)
        {
            if(!response)
            {
                alert("MISSING RESPONSE !");
                return;
            }
        
            if(!fields)
            {
                alert("MISSING FIELDS !");
                return;
            }
        
            for(fieldName in fields)
            {
                var fieldIsExcluded = false;
                // EXCLUSION
                if(!Object.isUndefined(exclusion) && Object.isArray(exclusion))
                {
                    for(var i=0; i<exclusion.length; i++)
                    {
                        if(exclusion[i] == fieldName)
                        {
                            //alert(fieldName);
                            fieldIsExcluded = true;
                            break;
                        }
                    }
                }
                
                if(!fieldIsExcluded)
                {
                    var field = fields[fieldName];
                    
                    if(field && !Object.isUndefined(response[fieldName]))
                    {
                        if(Object.isFormElement(field))
                        {
                            switch(field.tagName)
                            {
                                case "INPUT": 
                                {
                                    var inputType = field.readAttribute('type'); 

                                    if(inputType != null)
                                    {
                                        switch(inputType)
                                        {
                                            case "text": 
                                            {
                                                field.value = response[fieldName];
                                                break;
                                            }
                                            case "password": 
                                            {
                                                field.value = response[fieldName];
                                                break;
                                            }
                                            case "hidden": 
                                            {
                                                field.value = response[fieldName];
                                                break;
                                            }
                                        
                                        }
                                    }
                                    
                                    break;
                                }
                                case "TEXTAREA": 
                                {
                                    field.value = response[fieldName];
                                    
                                    break;
                                }
                                case "SELECT": 
                                {
                                    var isMultipleCombo = field.readAttribute('multiple'); 
                                
                                    if(isMultipleCombo == null)
                                    {
                                        field.selectedIndex = Utils.Form.Element.getOptionIndexByValue(field, String(response[fieldName]));
                                    }
                                    
                                    break;
                                }
                            }
                        }
                        
                        else
                        {
                            if(fields[fieldName].hasClassName("readonlyInput"))
                            {   
                                if(!fields[fieldName].hasClassName("list"))
                                {
                                    fields[fieldName].innerHTML = response[fieldName];
                                }
                                else
                                {
                                    var content = [];
                                    response[fieldName].each(function(_item, index){content[index] = '<li' + (index == (response[fieldName].length - 1)?' class="last"':'') + '>' + _item + '</li>';});
                                    fields[fieldName].innerHTML = '<ul>' + content.join("") + '</ul>';
                                }
                            }
                        }
                    }
                }
            }
        
        },
        
        buildFormCombobox:function(combo, data, mapping, options)
        {
            if(combo)
            {
                if(!Object.isUndefined(options) && options)
                {
                    if(!Object.isUndefined(options.eraseBefore) && options.eraseBefore) this.emptyFormCombobox(combo);
                    if(!Object.isUndefined(options.needFirstEmptyOption) && options.needFirstEmptyOption) combo.insert({bottom:new Element("option", {value:"0"}).update("-")});
                }

                $A(data).each(function(dataItem){combo.insert({bottom:new Element("option", {value:(!Object.isUndefined(mapping) && mapping?dataItem[mapping.value]:dataItem)}).update((!Object.isUndefined(mapping) && mapping?dataItem[mapping.text]:dataItem))});});
            }
        
        },
        
        emptyFormCombobox:function(combo, needFirstEmptyOption)
        {
            Utils.Element.emptyNode(combo);
            if(needFirstEmptyOption) combo.insert({bottom:new Element("option", {value:"0"}).update("-")});
        },
        
        setMultipleComboboxSelection:function(combo, selectedValues)
        {
            // SAVE FIRST
            var options = [];
            $A(combo.getElementsByTagName("OPTION")).each(function(optionNode){options[options.length] = {value:optionNode.value, text:optionNode.text};});
            // EMPTY
            this.emptyFormCombobox(combo, false);
            
            // REBUILD
            options.each(function(option, index){
                var optionNode = new Element("option", {value:option.value}).update(option.text);
                selectedValues.each(function(value){if(value == parseInt(option.value, 10)) optionNode.writeAttribute("selected", "selected");});
                
                this.formFields.userPowerStationId.insert({bottom:optionNode});
            
            }.bind(this));
        
        },
        
        getComboSelectedValue:function(combo)
        {
            var isMultipleCombo = combo.readAttribute('multiple'); 
        
            if(isMultipleCombo == null)
            {
                return combo.options[combo.selectedIndex].value;
            }
            else
            {
                var selection = [];
                $A(combo.getElementsByTagName("OPTION")).each(function(optionNode, index){
                    if(optionNode.selected == true)
                    {
                        selection[selection.length] = (Prototype.Browser.IE)?optionNode.value:optionNode.readAttribute('value');
                    }
                
                });
                
                return selection;
            }
        },
        
        setFormFieldsInReadonlyMode:function(collection, status)
        {
            if(status == true)
            {
                for(property in collection)
                {
                    if(!collection[property].hasClassName("readonly")) collection[property].addClassName("readonly");
                }
            }
            else
            {
                for(property in collection)
                {
                    if(collection[property].hasClassName("readonly")) collection[property].removeClassName("readonly");
                }
            }
        }   
        
             
		
    };

    var Utils = {};
    Object.extend(Utils, {
		Ajax:{},
		Element:{},
		Form:{},
		Document:{},
		StyleSheet:{},
		Cookie:{},
		URL:{}

    });
    
    
	Object.extend(Utils.Ajax, {
		webServiceCaller:function()
		{
			var obj = arguments[0];
			var randomNum = new Date().getTime();
			
			var request = new Ajax.Request(obj.url+"?"+"datetime="+randomNum, {
				method:		obj.method, 
				parameters:	obj.parameters,
				postBody:   obj.postBody,
				onLoading:	obj.onLoading,
				onComplete:	obj.onComplete,
				onSuccess:	obj.onSuccess
			});
			
			return request;
		}
				  
	});
   
	Object.extend(Utils.Element, {
		emptyNode:function(node)
		{
		    if(node && node.hasChildNodes())
		    {
			    try
			    {
			        while(node.hasChildNodes())
			        {
			            node.removeChild(node.childNodes[0]);
			        }
			    }
			    catch(error){}
			}
		},
		
		getDirectAncestorByClassName:function(startNode, className)
		{
		    var nodeFind = null;
		    
		    $A(startNode.ancestors()).each(function(ancestor){
		        if(ancestor.hasClassName(className))
		        {
		            nodeFind = ancestor;
		            throw $break;
		        }
		    });
		    		    
		    //-> RETURN NODE
		    return nodeFind;
		
		},
        
		getDirectAncestorById:function(startNode, id)
		{
		    var nodeFind = null;
		    
		    $A(startNode.ancestors()).each(function(ancestor){
		        if(ancestor.id == id)
		        {
		            nodeFind = ancestor;
		            throw $break;
		        }
		    });
		    		    
		    //-> RETURN NODE
		    return nodeFind;
		
		}				  
	});
	
   	Object.extend(Utils.Form, {
		Element:
		{
            getOptionIndexByValue:function(combo, value)
            {
                var index = null;
                $A(combo.options).each(function(option, i){
                    if(option.value == String(value))
                    {
                       index = i;
                       throw $break;
                    }
                }); 
                
                return index; 
            }
		}
		        
	});
   
	Object.extend(Utils.Document, {
	
        viewportWidth:function()
        {
            if (Prototype.Browser.Opera) return document.body.clientWidth;
            return document.documentElement.clientWidth;
        },

        viewportHeight:function()
        {
            if(Prototype.Browser.Opera) return document.body.clientHeight;
            if(Prototype.Browser.WebKit) return this.innerHeight;
            return document.documentElement.clientHeight;
        },

        viewportSize:function()
        {
            return {'height':this.viewportHeight(), 'width':this.viewportWidth()};
        },

        getScrollLeft: function()
        {
            return this.pageXOffset || document.documentElement.scrollLeft;
        },

        getScrollTop:function()
        {
            return this.pageYOffset || document.documentElement.scrollTop;
        },

        getScrollOffsets:function()
        {
            return {'left':this.getScrollLeft(), 'top':this.getScrollTop()}
        },
	
		getPageSize:function()
		{
	        var xScroll, yScroll;
        	
	        if(window.innerHeight && window.scrollMaxY)
	        {	
		        xScroll = window.innerWidth + window.scrollMaxX;
		        yScroll = window.innerHeight + window.scrollMaxY;
	        }
	        else
	        {
	            if(document.body.scrollHeight > document.body.offsetHeight)
	            {
	                // all but Explorer Mac
		            xScroll = document.body.scrollWidth;
		            yScroll = document.body.scrollHeight;
	            }
	            else
	            {   // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		            xScroll = document.body.offsetWidth;
		            yScroll = document.body.offsetHeight;
	            }
	        }
        	
	        var windowWidth, windowHeight;

	        if (self.innerHeight)
	        {	// all except Explorer
		        if(document.documentElement.clientWidth)
		        {
			        windowWidth = document.documentElement.clientWidth; 
		        }
		        else
		        {
			        windowWidth = self.innerWidth;
		        }
		        windowHeight = self.innerHeight;
	        } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		        windowWidth = document.documentElement.clientWidth;
		        windowHeight = document.documentElement.clientHeight;
	        } else if (document.body) { // other Explorers
		        windowWidth = document.body.clientWidth;
		        windowHeight = document.body.clientHeight;
	        }	
        	
	        // For small pages with total height less then height of the viewport
		    pageHeight = (yScroll < windowHeight)?windowHeight:yScroll;

	        // For small pages with total width less then width of the viewport
		    pageWidth = (xScroll < windowWidth)?xScroll:windowWidth;		

	        arrayPageSize = new Array(pageWidth, pageHeight, windowWidth, windowHeight) 
	        return arrayPageSize;

		}
				  
	});
	
	
   	Object.extend(Utils.StyleSheet, {

        setActiveStyleSheet:function(title)
        {
            var i, a, main;
            for(i=0; (a = document.getElementsByTagName("link")[i]); i++)
            {
                if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title"))
                {
                    a.disabled = true;
                    if(a.getAttribute("title") == title) a.disabled = false;
                }
            }
        },
        
        getActiveStyleSheet:function() 
        {
            var i, a;
            for(i=0; (a = document.getElementsByTagName("link")[i]); i++)
            {
                if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title") && !a.disabled) return a.getAttribute("title");
            }
            
            return null;
        },
        
        getPreferredStyleSheet:function()
        {
            var i, a;
            for(i=0; (a = document.getElementsByTagName("link")[i]); i++)
            {
                if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("rel").indexOf("alt") == -1 && a.getAttribute("title"))
                {
                    return a.getAttribute("title");
                }
            }
            
            return null;
        }
	
		        
	});
	
   	Object.extend(Utils.Cookie, {

        create:function(name, value, days)
        {
            if(days)
            {
                var date = new Date();
                date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
                var expires = "; expires=" + date.toGMTString();
            }
            
            else expires = "";
            document.cookie = name + "=" + value + expires + "; path=/";
        },

        read:function(name)
        {
            var nameEQ = name + "=";
            var ca = document.cookie.split(';');
            for(var i=0; i < ca.length; i++)
            {
                var c = ca[i];
                while(c.charAt(0) == ' ') c = c.substring(1, c.length);
                if(c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
            }
            return null;
        },
        
        erase:function(name)
        {
	        this.createCookie(name, "", -1);
        }      
	
		        
	});
	
   	Object.extend(Utils.URL, {
   	
        getParameter:function(name)
        {
            name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
            var regexS = "[\\?&]"+name+"=([^&#]*)";
            var regex = new RegExp(regexS);
            var results = regex.exec(window.location.href);

            return results == null?null:results[1];
        }	
        
	});
	


    var PicPreviewManager = Class.create({
    
        DEFAULT_PIC_SOURCE:"/library/img/shim.gif",
        MODE:["N", "M"],
        initialize:function(node)
        {
            this.container = node;
            this.fileUploadField = $(node.getElementsByTagName("INPUT")[0]);
            this.mode = this.MODE[0];
        
			this.options = Object.extend({
			    removePicFunction:Prototype.EmptyFunction,
				onPicIsLoaded:Prototype.EmptyFunction,
				onRemovePic:Prototype.EmptyFunction
				
				
			}, arguments[1] || {});
			
			this.buildPicPanel();
        },
        
        buildPicPanel:function()
        {
            this.picLoadingIndicator  = new Element("span", {style:"overflow:hidden", className:"picLoadingIndicator"}).update("Chargement de l'image...").hide();
            
            this.picPanel  = new Element("div", {className:"picPanel"});
            this.picPanel.hide();
            this.picDetail = new Element("div", {className:"picDetail"});
            this.picDetail.hide();
            var picContainer = new Element("div", {className:"pic"});

            this.pic = new Element("img", {src:this.DEFAULT_PIC_SOURCE, alt:""});
            picContainer.insert({bottom:this.pic});
            
            var picInformations = new Element("div", {className:"picInformations"});
            this.picFileName = new Element("span", {className:"fileName"});
            this.picFileSize = new Element("span", {className:"fileSize"});
            this.picFileDimensions = new Element("span", {className:"fileDimensions"});
            this.picEnlargeButton = new Element("a", {className:"realPicSize"}).update("Taille r&eacute;elle").observe("click", function(e){this.openLargePic();}.bindAsEventListener(this));
            this.picRemoveButton = new Element("a", {className:"deletePic"}).update("Supprimer").observe("click", function(e){this.options.removePicFunction(this);}.bindAsEventListener(this));
            picInformations.insert({bottom:this.picFileName});
            picInformations.insert({bottom:this.picFileSize});
            picInformations.insert({bottom:this.picFileDimensions});
            picInformations.insert({bottom:this.picEnlargeButton});
            picInformations.insert({bottom:this.picRemoveButton});
            
            
            this.picDetail.insert({bottom:picContainer});
            this.picDetail.insert({bottom:picInformations});
            
            this.picPanel.insert({bottom:this.picDetail});
            this.container.insert({bottom:this.picLoadingIndicator});
            this.container.insert({bottom:this.picPanel});
            
        },
        
        setup:function()
        {
            
            
        },
        
        updatePicPanel:function(data, hidePic)
        {
            
            this.picSrcData = data.picSrc;
            this.picLargeSrcData = data.picLargeSrc;
            
            this.pic.style.width = this.picWidth = (data.picWidth + "px");
            this.pic.style.height = this.picHeightData = (data.picHeight + "px");
            this.picFileName.innerHTML = this.picFileNameData = data.picFileName;
            this.picFileSize.innerHTML = data.picFileSize + "ko";
            this.picFileSizeData = data.picFileSize;
            this.picFileDimensions.innerHTML = (data.picWidth + " x " + data.picHeight);
            
            if(!hidePic)
            {
                this.picLoadingIndicator.show();
                
                var time = new Date().getTime();
                var timeParam = "?t=" + time;
                var imgPreloader = new Image();
                // Once image is preloaded, set pic url
                imgPreloader.onload = function()
                {
                    this.picLoadingIndicator.hide();
	                this.pic.src = data.picSrc;
                    this.picPanel.show();
//                    if(!Prototype.Browser.IE)
//                    {
//                        new Effect.Appear(this.picDetail, {
//                            duration:1,
//                            afterFinish:function(){
//                                this.options.onPicIsLoaded();
//                            }.bind(this)
//                        });
//                    }
//                    else
//                    {
//                        this.picDetail.show();
//                        this.options.onPicIsLoaded();
//                    }
                    
                    this.picDetail.show();
                    this.options.onPicIsLoaded();
                    
			        // Clear onLoad, IE behaves irratically with animated gifs otherwise 
	                imgPreloader.onload = function(){};
    	            	
                }.bindAsEventListener(this);
                imgPreloader.src = data.picSrc;
            }
            
        },
        
        
        _set:function(data)
        {
            this.fileUploadField.hide();
            this.updatePicPanel(data);
        },
        
        _remove:function(noCallback)
        {
            this.fileUploadField.show();
            this.picPanel.hide();
            this.picDetail.hide();
            this.updatePicPanel({
                picFileName:'_',
                picFileSize:0,
                picWidth:0,
                picHeight:0
            }, true);
            
            if(!noCallback) this.options.onRemovePic();
        },
        
        _reset:function()
        {
            this._remove(true);
        },
        
        resetFileUploadField:function()
        {
            this.fileUploadField.value = "";
        },
        
        openLargePic:function()
        {
            window.open(this.picLargeSrcData);
        },
        
        hideRemoveButton:function()
        {
            this.picRemoveButton.hide();
        },
        
        hideEnlargeButton:function()
        {
            this.picEnlargeButton.hide();
        },
        
        show:function()
        {
            if(!this.container.visible()) this.container.show();
        },
        
        hide:function()
        {
            if(this.container.visible()) this.container.hide();
        }
        
        
    });
    
Array.prototype.remove = function(obj) {
  var a = [];
  for (var i=0; i<this.length; i++) {
    if (this[i] != obj) {
      a.push(this[i]);
    }
  }
  return a;
}
    




