// Copyright (c) 2006 Sébastien Gruhier (http://xilinus.com, http://itseb.com)
// 
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// VERSION 2 modifié par villaumé romain C2B-trunk



if(typeof Draggable == 'undefined')
  throw("portal.js requires including script.aculo.us' dragdrop.js library");

if(typeof Builder == 'undefined')
  throw("portal.js requires including script.aculo.us' builder.js library");

// Xilinus namespace
if(typeof Xilinus == 'undefined')
  Xilinus = {}
  
Builder.dump();


Xilinus.Widget = Class.create();  
Xilinus.Widget.lastId = 0;
Xilinus.Widget.remove = function(element, options) {    
  if (options && options.afterFinish)
    options.afterFinish.call();
} 


/* 
*Extension de la classe pour le portal
*
*
*/
Object.extend(Xilinus.Widget.prototype, {
  initialize: function(className, id) {
  	//creation du widjet
    className = className || "widget";  

    this._id   = id || ("widget_" + Xilinus.Widget.lastId++);
    
    this._headerDiv   = DIV({className: className + '_header', id: this._getId("header")},  ""); 
    this._titleDiv   = DIV({className: className + '_title', id: this._getId("title")},  "");    
    this._paramDiv   = DIV({className: className + '_param', id: this._getId("param")},  ""); //creation de la div param  
    this._optionDiv = DIV({className: className + '_option', id: this._getId("option")}, "");//creation de la div option   
    this._contentDiv = DIV({className: className + '_content', id: this._getId("content")},"");   
    this._footerDiv  = DIV({className: className + '_statusbar', id: this._getId("footer")}, "");
    
    var divHeader  = DIV({className: className + '_nw' }, [this._headerDiv , this._titleDiv] ); 
    var divOption = DIV({className: className + '_op'},  this._optionDiv);//creation de la div container option
    var divParam  = DIV({className: className + '_pa' }, this._paramDiv);//creation de la div container param
    var divContent = DIV({className: className + '_w' },  this._contentDiv);   
    var divFooter  = DIV({className: className + '_sw' }, this._footerDiv);  
    
    
    this._div = DIV({className: className + (className != "widget" ? " widget" : ""), id: this._getId()}, [divHeader, divParam, divContent, divOption, divFooter,]);     
    this._div.widget = this;

    return this;
  },    
  
  // detruire un module
  destroy: function() {
    this._div.remove();
  },
  
  //recuperer l'id du module
  getElement: function() {
    return $(this._getId()) || $(this._div);
  },
   
  //definir l'id du module
  setId: function(id) {
    this._id = id;
    return this;
  },
  //recupérer le titre du module
  getId: function(title) {
    return this._id;
  },
  
  //definir le titre du module
  setTitle: function(title) {
    $(this._titleDiv).update(title);
    return this;
  },
  //recupérer le titre du module
  getTitle: function(title) {
    return $(this._titleDiv)
  },
  
  setFooter: function(title) {
    $(this._footerDiv).update(title);
    return this;
  },
  //récupérer le footer
  getFooter: function(title) {
    return $(this._footerDiv)
  },
  //récupérer le header
  getHeader: function(title) {
    return $(this._headerDiv)
  },
  //définir le contenu
  setContent: function(title) {
  	//if($(this._contentDiv)=="")alert(title);
    //this.chargement($(this._contentDiv));
  	this.ajaxcontent = false;
  	this.title = title;
  	$(this._contentDiv).update(title);  
    return this;
  },
  //récupérer le contenu
   getContent: function(title) {
    return $(this._contentDiv)
  }, 
  //recalculer et dedimentionne la hauteur du module
  recalculHauteurDiv: function()
  {
    $(this._contentDiv).setStyle({height: null})
    var h = $(this._contentDiv).getHeight();
    $(this._contentDiv).setStyle({height: h + "px"});
  	
   
  	return this;
  },
     
  ajaxBoxUpdate: function ()
  {
	div =$(this._contentDiv);
  	if(typeof($(div))!='undefined')
  	{
	  	new Ajax.Request(this.page,{
	  		evalScripts: true,
	  		onComplete:function(e){
	  			retour = e.responseText;
	  			$(div).update(retour);		
	  			$(div).setStyle({height: null})
    			var h = $(div).getHeight();
    			$(div).setStyle({height: h + "px"});			
	  		}
	  		,onFailure:function(e){alert('erreur')}
	  		,asynchronous: false
	  	});

  	}

  },

  /* appeler une action d'un javascript 
  *
  *

  $A: function()
  {
  	
  }  */
  
  /* définir le contenu du module en ajax
  * @param page page appele
  * @param delay delais avant le refraichissement du contenu du module
  */
  setAjaxContent: function(page, delay)
  {

  	this.chargement($(this._contentDiv));
  	
  	this.delay = delay;
  	this.ajaxcontent = true;
  	this.page = page;
		div =$(this._contentDiv);
  	if(this.delay >0)
  	{
  		//alert('delay');
  		new Ajax.PeriodicalUpdater($(this._contentDiv), this.page, {evalScripts: true, frequency: this.delay, decay:2, onSuccess:function(e){
  				retour = e.responseText;
	  			$(div).update(retour);		
	  			$(div).setStyle({height: null})
    			var h = $(div).getHeight();
    			$(div).setStyle({height: h + "px"});			
	  		}});			
  		//new PeriodicalExecuter(this.ajaxBoxUpdate, this.delay);
  	}
  	else
  	{
  		//alert('nodelay'+$(this._contentDiv).id); 		
  		//new Ajax.Updater($(this._contentDiv),this.page,{ afterUpdate:this.traitementRefresh(this)});
  		this.ajaxBoxUpdate();

  	}

  	return this;
  },

  //raffraichir le contenu du module
  refreshAjaxContent: function(div)
  {
  	//alert(this.page);
  	new Ajax.Updater(div, this.page,{evalScripts: true, onComplete:this.recalculHauteurDiv});  	
  	return this;
  },
  //définir les options     
  setOption: function(title) {
  	var html = $(this._optionDiv).innerHTML;
  	//alert(html);
    $(this._optionDiv).update(html+title);  
    return this;
  },
  //récupérer les options
  getOption: function(title) {
    return $(this._optionDiv)
  },
  
  //définir les parametres
  setParam: function(title) {
    $(this._paramDiv).update(title.strip()); 
    return this;
  },
  //récupérer les paramètres 
  getParam: function(title) {
    return $(this._paramDiv)
  },   
  
  //raffraichir le contenu du module en prenant compte du delais de raffraichissement
  refreshContent: function(element)
  {
  	//alert(this.page);
  	var widget = $(element).up(".widget").widget;
  	refreshCallBack = widget.refreshCallBack;

  	if(refreshCallBack == false)
  	{
	  	if(this.ajaxcontent)
	  	{
	  		this.setAjaxContent(this.page, this.delay);
	  	}
	  	else
	  	{
	  		this.setContent(this.title);
	  	}  		
  	}
  	else
  	{
  		if('function' == typeof(eval(refreshCallBack))){
			eval(refreshCallBack)(this.delay);
		}
		else{
			alert("la fonction n'exite pas");
		}
		
  	}

  },
  //recalcule et redimentionne le module en hauteur
  updateHeight: function(orignal) { 
  	//alert(this.newHeight);
    $(this._contentDiv).setStyle({height: null})

    if(orignal >0)
    {
    	var h =  orignal;
    }
    else
    {
    	 var h = $(this._contentDiv).getHeight();
    }

    $(this._contentDiv).setStyle({height: h + "px"});
  },
  //fonction qui permet de mettre une image lors du chargement
  chargement: function(element)
  {
  	$(element).innerHTML= '<div id="chargement"><img src="images/ajax-loader.gif"></div>';
  },
  
  // PRIVATE FUNCTIONS
  _getId: function(prefix) { 
      return (prefix ? prefix + "_" : "") + this._id;
  }
});

/* 
*Extension de la classe pour les widgets
*
*
*/
Xilinus.Portal = Class.create()
Object.extend(Xilinus.Portal.prototype, {
  lastEvent: null,   
  widgets:   null,
  columns:   null, 
  
  initialize: function(columns, options) {   
    this.options = Object.extend({                  
                     url:          null,                 // Url called by Ajax.Request after a drop
                     onOverWidget: null,                 // Called when the mouse goes over a widget
                     onOutWidget:  null,                 // Called when the mouse goes out of a widget                                           
                     onChange:     null,                 // Called a widget has been move during drag and drop 
                     onUpdate:     null,                 // Called a widget has been move after drag and drop
                     removeEffect: Xilinus.Widget.remove // Remove effect (by default no effect), you can set it to Effect.SwitchOff for example
                   }, options)
    this._columns = (typeof columns == "string") ? $$(columns) : columns;
    this._widgets = new Array();    


       
    this._columns.each(function(element) {
    	//alert(element.id);
    	//classvalue = (element.className).toLowerCase();
    			//hasClassName()
    	//if(classvalue.indexOf("container") != -1)//on indique que cette div est un container
    	if(element.hasClassName("portal_container"))//on indique que cette div est un container
    	{
    		Droppables.add(element, {onHover: this.onHover.bind(this), overlap: "vertical", accept: this.options.accept})}
    	}.bind(this)
    	);  
    this._outTimer  = null;
    
    // Draggable calls makePositioned for IE fix (??), I had to remove it for all browsers fix :) to handle properly zIndex
    this._columns.invoke("undoPositioned");    
    
    this._currentOverWidget = null; 
    this._widgetMouseOver = this.widgetMouseOver.bindAsEventListener(this);
    this._widgetMouseOut  = this.widgetMouseOut.bindAsEventListener(this);
    
    Draggables.addObserver({ onEnd: this.endDrag.bind(this), onStart: this.startDrag.bind(this) }); 
  },
  
  get_colums: function(div)
	{
	
	  	var indexcolums = -1;
	  	this._columns.each(function(element) {
	  		indexcolums++;
	  		if(element.id == div)
	  		{
	  			valuecolums = indexcolums;			
	  		}	
	  	});  
	
	  	
	  	return valuecolums;
	},
  
	positionWidget: function(event)
	{
		var pos = {};
		if (typeof (event.clientX) != 'undefined')
		{
			pos.x = event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft);
			pos.y = event.clientY + (document.documentElement.scrollTop || document.body.scrollTop);
		}
		else
		{
			pos.x = event.x + (document.documentElement.scrollLeft || document.body.scrollLeft);
			pos.y = event.y + (document.documentElement.scrollTop || document.body.scrollTop);
		}
		return pos
	},
	//redimentionne le widget
	resizeHover: function ( event, widget )
	{
		this.widgetResize = widget;

		var eventPosition =this.positionWidget(event);
		var popupPosition = { x : $(this.widgetResize._id).offsetLeft, y : $(this.widgetResize._id).offsetTop };
		var popupDimension = { w : $(this.widgetResize._id).offsetWidth, h : $(this.widgetResize._id).offsetHeight };
		var offsetPosition = { x : eventPosition.x - popupPosition.x, y : eventPosition.y - popupPosition.y };
		this.resize.direction = '';
		
		//hHeader = this.widgetResize.getHeader().getHeight();
		hFooter = this.widgetResize.getFooter().getHeight();

		/*
		if (offsetPosition.y <= hHeader)
		{
			this.widgetResize.getHeader().setStyle({cursor: 'n-resize', borderTop: '2px solid #5a8891'});	
			this.resize.direction += 'n';
		}
		else 
		*/
		//alert(this.estreduit);
		if ((popupDimension.h - offsetPosition.y) <= hFooter)
		{
			this.resize.direction += 's';
			this.widgetResize.getFooter().setStyle({cursor: 's-resize', borderTop: '2px solid #5a8891'});	
		}

		
		
	},
	
	resizeOut: function ( event )
	{
		if (!this.resize.resizing)
		{
			this.widgetResize.getFooter().setStyle({cursor: '', borderTop: ''});	
		}
	},
		
	resizeStart: function ( event )
	{
		//var eventPosition = EVT.position(event);
		var eventPosition = this.positionWidget(event);
		var popupPosition = { x : $(this.widgetResize._id).offsetLeft, y : $(this.widgetResize._id).offsetTop };
		this.resize.initialPosition.x = eventPosition.x - popupPosition.x;
		this.resize.initialPosition.y = eventPosition.y - popupPosition.y;
		this.resize.initialMousePosition.x = eventPosition.x;
		this.resize.initialMousePosition.y = eventPosition.y;
		this.resize.initialPopupPosition.x = popupPosition.x;
		this.resize.initialPopupPosition.y = popupPosition.y;
		this.resize.initialDimension.w = $('content_'+this.widgetResize._id).offsetWidth;
		this.resize.initialDimension.h = $('content_'+this.widgetResize._id).offsetHeight;
		this.resize.resizing = true;
	},

	resizeApply: function ( event )
	{
		
		if (this.resize.resizing)
		{
			var eventPosition = this.positionWidget(event);
			var n, s;
			var offsetX, offsetY;
			var newWidth, newHeight;
			var newLeft, newTop;

			this.newHeight = this.resize.initialDimension.h + eventPosition.y - this.resize.initialMousePosition.y;
			newTop = this.resize.initialPopupPosition.y + eventPosition.y - this.resize.initialMousePosition.y;	

			//$('souris').innerHTML = 'content_'+this.widgetResize._id+' y: '+$(this.widgetResize._id).getHeight()+' y: '+eventPosition.y+' taille final: '+newTop+' direction '+this.resize.direction;
			
			//if(this.resize.direction == 's')$('content_'+this.widgetResize._id).setStyle({height: newHeight+ 'px'});
			//if(this.resize.direction == 'n')$('content_'+this.widgetResize._id).setStyle({top: newTop+ 'px'});
			//, top: newTop+'px'
			$('content_'+this.widgetResize._id).setStyle({height: this.newHeight+ 'px'});

			return this;

		}
	},

	resizeStop: function ( event )
	{
		this.resize.resizing = false;
	},

	redimentionneWidget: function(widget)
	{

		//if(!this.estreduit)
		idWidget = widget._id;

		if (this.estresizable) { 
		    this.resize =
				{
					hover : false,
					out : false,
					start : false,
					apply : false,
					stop : false,
					resizing : false,
					direction : '',
					initialPosition : { x : 0, y : 0 },
					initialMousePosition : { x : 0, y : 0 },
					initialPopupPosition : { x : 0, y : 0 },
					initialDimension : { w : 0, h : 0 }
				};
				
				this.objet = {};
				this.objet.bresizeHover = this.resizeHover.bindAsEventListener(this, widget);
				this.objet.bresizeOut = this.resizeOut.bindAsEventListener(this);
				this.objet.bresizeStart = this.resizeStart.bindAsEventListener(this);
				this.objet.bresizeApply = this.resizeApply.bindAsEventListener(this);
				this.objet.bresizeStop = this.resizeStop.bindAsEventListener(this);
			
 			  Event.observe($(idWidget), "mousemove", this.objet.bresizeHover);
				Event.observe($(idWidget), "mouseout", this.objet.bresizeOut);
				Event.observe($(idWidget), "mousedown", this.objet.bresizeStart);			
				Event.observe(document, "mousemove", this.objet.bresizeApply);
				Event.observe(document, "mouseup", this.objet.bresizeStop);		

		}
	},

	stopRedimentionneWidget: function(widget)
	{
				this.objet = {};
				this.objet.bresizeHover = this.resizeHover.bindAsEventListener(this, widget);
				this.objet.bresizeOut = this.resizeOut.bindAsEventListener(this);
				this.objet.bresizeStart = this.resizeStart.bindAsEventListener(this);
				this.objet.bresizeApply = this.resizeApply.bindAsEventListener(this);
				this.objet.bresizeStop = this.resizeStop.bindAsEventListener(this);
		//if(!this.estreduit)
		idWidget = widget._id;

		    this.resize =
				{
					hover : false,
					out : false,
					start : false,
					apply : false,
					stop : false,
					resizing : false,
					direction : '',
					initialPosition : { x : 0, y : 0 },
					initialMousePosition : { x : 0, y : 0 },
					initialPopupPosition : { x : 0, y : 0 },
					initialDimension : { w : 0, h : 0 }
				};
				
				Event.stopObserving($(idWidget), "mousemove", this.objet.bresizeHover);
				Event.stopObserving($(idWidget), "mouseout", this.objet.bresizeOut);
				Event.stopObserving($(idWidget), "mousedown", this.objet.bresizeStart);
				
				Event.stopObserving(document, "mousemove", this.objet.bresizeApply);
				Event.stopObserving(document, "mouseup", this.objet.bresizeStop);		
				
				//Event.unloadCache();		

	},	
	
  //fonction qui permet d'ajouer un widjet
  add: function(widget, columnIndex, widjetOptions) {  
  		
  	var widget;			
	idWidget = widget._id;		
    if(this.setOptions)
      this.setOptions(widjetOptions);
    else
      this.widjetOptions = widjetOptions || { };
      

	//on initialise les options du widjet
    this.draggable = typeof this.widjetOptions.draggable == "undefined" ? true : this.widjetOptions.draggable
    this.supprimable = typeof this.widjetOptions.supprimable == "undefined" ? false : this.widjetOptions.supprimable
    this.isparam = typeof this.widjetOptions.isparam == "undefined" ? true : this.widjetOptions.isparam
    this.refresh = typeof this.widjetOptions.refresh == "undefined" ? true : this.widjetOptions.refresh
    widget.refreshCallBack = typeof this.widjetOptions.refreshCallBack == "undefined" ? false : this.widjetOptions.refreshCallBack
    this.reduire = typeof this.widjetOptions.reduire == "undefined" ? true : this.widjetOptions.reduire
    this.estreduit = typeof this.widjetOptions.estreduit == "undefined" ? false : this.widjetOptions.estreduit
    this.estresizable = typeof this.widjetOptions.estresizable == "undefined" ? false : this.widjetOptions.estresizable
    
    // Add to widgets list
    this._widgets.push(widget);
    if (this.options.accept)
      widget.getElement().addClassName(this.options.accept)
    
    // Add element to column
    if(isNaN(columnIndex))
    {
    	columnIndex = this.get_colums(columnIndex);
    }
    //on ajoute le widget a la colonne
    this._columns[columnIndex].appendChild(widget.getElement());
    widget.updateHeight();
    
    // Make header draggable   
    if (this.draggable) {
      widget.draggable = new Draggable(widget.getElement(),{ handle: widget._titleDiv, revert: false});     
      widget.getTitle().addClassName("widget_draggable");   
    }
   
    //rendre le widjet supprimable
    if (this.supprimable) {
			widget.setOption('<a href="#" onclick="removeWidget(this); return false;" id="delete_button"></a>');
    } 
    //rendre le widjet parametrable
    if (this.isparam) {
    	//alert(this.getParam);
		if($('param_'+idWidget).innerHTML != "")widget.setOption('<a href="#" onclick="paramWidget(this); return false;" id="edit_button">');
    }     
    //rendre le widjet rafraichissable
    if (this.refresh) {
			widget.setOption('<a href="#" onclick="refreshWidget(this); return false;" id="refresh_button"></a>');
    }       
     //rendre le widjet reductible
    if (this.reduire) {
			widget.setOption('<a href="#" onclick="reduirehWidget(this); return false;"><img src="images/collapsen.png" class="reduire_button" border="0" id="reduire_button_'+idWidget+'"></a>');
    } 
     //rendre le widjet reductible
    if (this.estreduit) {   
	    $('content_'+idWidget).hide(); 
	    var vimg = $('reduire_button_'+idWidget);  
      vimg.src = 'images/expandn.png';
    }


    if (this.estresizable) { 
    	if(!this.estreduit)this.redimentionneWidget(widget);			
    	//this.redimentionneWidget(widget);			
    }   
       
    // Update columns heights
    this._updateColumnsHeight();  

    // Add mouse observers  
    if (this.options.onOverWidget)
      widget.getElement().childElements().invoke("observe", "mouseover", this._widgetMouseOver);
    if (this.options.onOutWidget)
      widget.getElement().childElements().invoke("observe", "mouseout",  this._widgetMouseOut);

    widget._optionDiv.style.display = 'none';//Fix pour IE
    widget._paramDiv.style.display = 'none';//Fix pour IE
    this.addWidgetControls(widget._optionDiv.id);
    
    return this;
  },  

  /* retourne id content en fonction de l'element
  *
  * @param typeContent defaut content
  * - Footer 
  * - Header 
  * 
  * pn l'appel de l'exterrieur en passant portal.$('element')
  */
  $:function(id, typeContent)
  {

   for (var index = 0, len = this._widgets.length; index < len; ++index) {
   	  var w = this._widgets[index];
      var wId = w.getId();    
      var wTitle = w.getTitle().innerHTML;
      var wContent = w.getContent().id;
      var wFooter = w.getFooter().id;
      var wHeader = w.getHeader().id;
      if(id == wId)
      {

      	switch(typeContent)
      	{
      		case "id":
      		return wId;
      		break;
      		case "content":
      		return wContent;
      		break;
      		case "Header":
      		return wHeader;
      		break;
      		case "Footer":
      		return wFooter;
      		break;
      		default:
      		return wContent;
      		break;
      	}
      	
      }
   }
   return false;
  },
  
  remove: function(widget) {
    // Remove from the list
    this._widgets.reject(function(w) { return w == widget});

    // Remove observers
    if (this.options.onOverWidget)
      widget.getElement().childElements().invoke("stopObserving", "mouseover", this._widgetMouseOver);
    if (this.options.onOutWidget)
      widget.getElement().childElements().invoke("stopObserving", "mouseout",  this._widgetMouseOut);

    // Remove draggable
    if (widget.draggable)
      widget.draggable.destroy();
      
    // Remove from the dom
    this.options.removeEffect(widget.getElement(), {afterFinish: function() {widget.destroy();}});
    
    // Update columns heights
    this._updateColumnsHeight();  
  },
    
  serialize: function() {
    parameters = ""
    this._columns.each(function(column) {   
      var p = column.childElements().collect(function(element) {
        return column.id + "[]=" + element.id
      }).join("&") 
      parameters += p + "&"
    });               
    
    return parameters;                      
  },     
  
  addWidgetControls: function(element) {
    $(element).observe("mouseover", this._widgetMouseOver); 
    $(element).observe("mouseout", this._widgetMouseOut); 
  },
  
  // EVENTS CALLBACKS
  widgetMouseOver: function(event) {   
    this._clearTimer();
      
    var element =  Event.element(event).up(".widget");
    if (this._currentOverWidget == null || this._currentOverWidget != element) {
      if (this._currentOverWidget && this._currentOverWidget != element)
        this.options.onOutWidget(this, this._currentOverWidget.widget)    
        
      this._currentOverWidget = element;
      this.options.onOverWidget(this, element.widget)
    }
  },

  widgetMouseOut: function(event) {    
    this._clearTimer();
    var element =  Event.element(event).up(".widget"); 
    this._outTimer = setTimeout(this._doWidgetMouseOut.bind(this, element), 100);
  },
  
  _doWidgetMouseOut: function(element) {
    this._currentOverWidget = null;
    this.options.onOutWidget(this, element.widget)    
  },                                               
  
  // DRAGGABLE OBSERVER CALLBACKS
  startDrag: function(eventName, draggable) { 
    var widget = draggable.element;
    
    if (!this._widgets.find(function(w) {return w == widget.widget}))
      return;

    var column = widget.parentNode;
    
    // Create and insert ghost widget
    var ghost = DIV({className: 'widget_ghost'}, ""); 
    $(ghost).setStyle({height: widget.getHeight()  + 'px'})

    column.insertBefore(ghost, widget);  

    // IE Does not absolutize properly the widget, needs to set width before
    widget.setStyle({width: widget.getWidth() + "px"});
    
    // Absolutize and move widget on body
    Position.absolutize(widget);  
    document.body.appendChild(widget);   
    
    // Store ghost to drag widget for later use
    draggable.element.ghost = ghost; 
    
    // Store current position
    this._savePosition = this.serialize();    
  },   

  endDrag: function(eventName, draggable) {
    var widget = draggable.element;      
    if (!this._widgets.find(function(w) {return w == widget.widget}))
      return;
    
    var column = widget.ghost.parentNode;
    
    column.insertBefore(draggable.element, widget.ghost); 
    widget.ghost.remove();   
    
    if (Prototype.Browser.Opera)     
      widget.setStyle({top: 0, left: 0, width: "100%", height: widget._originalHeight, zIndex: null, opacity: null, position: "relative"})
    else
      widget.setStyle({top: null, left: null, width: null, height: widget._originalHeight, zIndex: null, opacity: null, position: "relative"})
    
    widget.ghost = null;    

	//taille original du widget avant de deplacement afin de le conserver si drag&drop
   this.hOriginal = $('content_'+widget.widget._id).getHeight();

   widget.widget.updateHeight(this.hOriginal);
    this._updateColumnsHeight();
    
    // Fire events if changed
    if (this._savePosition != this.serialize()) {
      if (this.options.url)  
        new Ajax.Request(this.options.url, {evalScripts: true, parameters: this.serialize()});
      
      if (this.options.onUpdate)
        this.options.onUpdate(this);
    }
  },

  onHover: function(dragWidget, dropon, overlap) {  
    var offset = Position.cumulativeOffset(dropon);
    var x = offset[0] + 10;
    var y = offset[1] + (1 - overlap) * dropon.getHeight();

    // Check over ghost widget
    if (Position.within(dragWidget.ghost, x, y))
      return;
      
    // Find if it's overlapping a widget
    var found = false;
    var moved = false;
    for (var index = 0, len = this._widgets.length; index < len; ++index) {
      var w = this._widgets[index].getElement();
      if (w ==  dragWidget || w.parentNode != dropon)   
        continue;        

      if (Position.within(w, x, y)) {    
        var overlap = Position.overlap( 'vertical', w);     
        // Bottom of the widget
        if (overlap < 0.5) {         
          // Check if the ghost widget is not already below this widget
          if (w.next() != dragWidget.ghost) {
            w.parentNode.insertBefore(dragWidget.ghost, w.next());   
            moved = true;
          }
        } 
        // Top of the widget
        else {       
          // Check if the ghost widget is not already above this widget
          if (w.previous() != dragWidget.ghost) {      
            w.parentNode.insertBefore(dragWidget.ghost, w);   
            moved = true;
          }
        }
        found = true;
        break;
      }
    }
    // Not found a widget
    if (! found) {        
      // Check if dropon has ghost widget
      if (dragWidget.ghost.parentNode != dropon) {
        // Get last widget bottom value
        var last = dropon.childElements().last();
        var yLast = last ? Position.cumulativeOffset(last)[1] + last.getHeight() : 0; 
        if (y > yLast && last != dragWidget.ghost) {
          dropon.appendChild(dragWidget.ghost);
          moved = true;
        }
      }
    }  
    if (moved && this.options.onChange) 
      this.options.onChange(this)            

    this._updateColumnsHeight();
  },                
  
  // PRIVATE FUNCTIONS
  _updateColumnsHeight: function() {      
  	var h = 0;
    this._columns.each(function(col) {
    	colElement = col.id;
    	if(colElement)
    	{
    		//classvalue = $(colElement).className.toLowerCase();
    		//hasClassName()
    		if($(colElement).hasClassName("portal_container"))//on indique que cette div est un container
    		{
		      h = Math.max(h, col.childElements().inject(0, function(sum, element) { 
		        return sum + element.getHeight(); 
		      	}));
	    	}
    	}

    	

    	})
    	/* correction a apporteer important */
    	//this._columns.invoke("setStyle", {height: h + 'px'})
  },
  
  _clearTimer: function() {
    if (this._outTimer) {
      clearTimeout(this._outTimer);
      this._outTimer = null;
    }                        
  }
});     


/**ACTION SUR LES WIDGETS */

     //action sur les boutons
     function onOverWidget(portal, widget) {
     	idWidget = widget._id;
	     	try
				{
      				widget.getElement().insertBefore($('option_'+idWidget), widget.getElement().firstChild);
      				$('option_'+idWidget).show(); 
				}
				catch(err)
				{
				//Handle errors here
				} 

     } 
   
     function onOutWidget(portal, widget) {
     	idWidget = widget._id;
	     	try
				{
					$('option_'+idWidget).hide(); 
				}
				catch(err)
				{
				//Handle errors here
				}         
     } 
   
     function removeWidget(element) {
       	 var widget = $(element).up(".widget").widget;
       	 idWidget = widget._id;
       	 $('option_'+idWidget).hide();  
         //document.body.appendChild($('control_buttons').hide())
         portal.remove(widget);      
     }                                

     function paramWidget(idModule) {
 
       var vimg = $('param_button_'+idModule);
//,afterFinish: callBackEffetReduire(widget)

       if(Element.getStyle($('param_'+idModule), 'display') == "block")
       {    
       	
       	var effet = new Effect.BlindUp('param_'+idModule, {duration:0.15});    
       //	vimg.src = urlimages+'ico-fleche-droit.png';
       }
       else
       {
       	
       	var effet = new Effect.BlindDown('param_'+idModule, {duration:0.15});	
      // 	vimg.src = urlimages+'ico-fleche-bas.png';
       }
     } 
     
     
     function refreshWidget(element) {
     	
       var widget = $(element).up(".widget").widget;
       
       //alert(this.refreshCallBack);
       //idWidget = $(element).up(".widget").id;
			 widget.refreshContent(element);
     }


     function callBackEffetReduire(widget)
     {
     	portal._updateColumnsHeight();

     if(Element.getStyle($('content_'+widget._id), 'display') == "block")
       { //on rend le widget non redimentionnable
       	portal.stopRedimentionneWidget(widget);	
       }
       else
       { //on rend le widget redimentionnable
       	portal.redimentionneWidget(widget);
       }
      
     }

     function reduirehWidget(nomWidget) {
 
       var vimg = $('reduire_button_'+nomWidget);
//,afterFinish: callBackEffetReduire(widget)
       if(Element.getStyle($('content_'+nomWidget), 'display') == "block")
       {    
       	
       	var effet = new Effect.BlindUp('content_'+nomWidget, {duration:0.15});    
       	vimg.src = urlimages+'ico-fleche-droit.png';
       }
       else
       {
       	
       	var effet = new Effect.BlindDown('content_'+nomWidget, {duration:0.15});	
       	vimg.src = urlimages+'ico-fleche-bas.png';
       }
     } 
    

    function onChange() {
    
			//changement lors du deplacement
    }
    
    function widgetAlerte(element)
    {
    	
    	 var widget = $(element).up(".widget").widget;
       idWidget = $(element).up(".widget").id;
       //var effet = new Effect.Shake(idWidget, {duration:1});  
       var effet = new Effect.Pulsate(idWidget, {duration:1});  
    }
    

    
/*FIN ACTION SUR LES WIDGETS*/
       	var typeCss = '';
       	var isDrope = false;
       	var originalePosition = '';
       	
  function retourneIndex(style)
				{
						var urlcss = 'http://filerc2b/dev/Tests/V3-Interface/POC_ready/www/css/';
						var docStyleSheets = document.styleSheets;
						var arrayStyleSheets = Object.values(docStyleSheets);
						var href = '';
			
						//on retire les deux dernier elements du tableau
						arrayStyleSheets = arrayStyleSheets.slice(0,(arrayStyleSheets.length -2));	
			
						for(i=0; i<=arrayStyleSheets.length-1; i++)	
						{			
							element = arrayStyleSheets[i];
							if((typeof element == "object") && (typeof element != "number") && (typeof element != "function"))
							{
								
								href = element.href.toLowerCase();
								if((href.indexOf(style) != -1) && (typeof href == "string") )
								{
									return i;					
								}
							
							}				
						};
						
				}

	


				function reverseModule(typeAffichage)
				{

					if(typeAffichage == "")isDrope = true;
					var indexStyleDroitier = retourneIndex('page_droite');
					var indexStyleGauchier = retourneIndex('page_gauche');

					//document.styleSheets[indexStyleDroitier].disabled=true;					
					//document.styleSheets[indexStyleGauchier].disabled=true;	
		
					if(typeCss || typeAffichage=='droitier')
					{

						typeCss = false;
						if (navigator.appName=="Netscape")
						{
							document.styleSheets[indexStyleDroitier].disabled=false;
							document.styleSheets[indexStyleGauchier].disabled=true;							
						}
						else
						{
							document.styleSheets[indexStyleDroitier].disabled=true;
							document.styleSheets[indexStyleGauchier].disabled=false;							
						}
						alert('droitier indexStyleDroitier'+indexStyleDroitier+' indexStyleGauchier '+indexStyleGauchier+' typeCSS : '+typeCss);
					}
					else
					{

						typeCss = true;

						if (navigator.appName=="Netscape")
						{
							document.styleSheets[indexStyleDroitier].disabled=true;
							//document.styleSheets[indexStyleGauchier].disabled=false;							
						}
						else
						{
							document.styleSheets[indexStyleDroitier].disabled=false;
							document.styleSheets[indexStyleGauchier].disabled=true;							
						}		
						alert('gauchier indexStyleDroitier'+indexStyleDroitier+' indexStyleGauchier '+indexStyleGauchier+' typeCSS : '+typeCss);
					}

					return false;
				}
				
				
//fonction ambidextre
		       function starteffect(e){
	  
	       	  	originalePosition = e.positionedOffset();
		       	width = $('emplacement_module_gauche').getWidth();
		       	height = $('emplacement_module_gauche').getHeight();
		       	
						$('emplacement_module_gauche').setStyle({
						  width: width+'px',
						  height: height+'px'
						});
						
						$('module_selectionnes').hide();
			   		$('module_secondaire').hide();
	
	       }
	       
	       function revert(){
	       
	       	$('module_selectionnes').show();
					$('module_secondaire').show();

		
					return true;
					
	       }
	       
	       function reverteffect(e)
	       {
	       		$('module_selectionnes').show();
						$('module_secondaire').show();
					
	       }	

	         
//fonction ajout de module
	       
	function createDemos() {
		  //new Tip('module_dispo', '<ul><li><a class="module" href="#" onclick="portal.add(new Xilinus.Widget().setTitle(\'gainSite\').setContent(gainSite), \'module_selectionnes\',{estreduit:true});">gain site</a></li><li><a href="#" class="module" onclick="portal.add(new Xilinus.Widget().setTitle(\'kilukru\').setContent(kilukru), \'module_selectionnes\',{estreduit:true});">kilu kru</a></li></ul>', { title : 'Modules', hideOn: 'mouseover', hideAfter: 2, hook: { tip: 'topRight', target: 'topLeft'}, offset: { x: -5, y: 0 }});
	}
