﻿/*-----------------------------------------------------------------
SVI+ popups [hervé]
3 nov 2006
-------------------------------------------------------------------

Gestion des popups internes au document HTML
(div en position absolue avec titre 
	+ bouton fermer 
	+ contenu chargé en ajax 
	+ possibilité de déplacement
	+ fermeture en appuyant sur ESC)
	
utilise prototype(prototype.conio.net) + scriptaculous(script.aculo.us) pour les effets

utilisation: var p = new Popup('uniqueid','titre','url_de_contenu.html');
ou Popups.create('uniqueid','titre','url_de_contenu.html');
utilisation: var p = new Popup('uniqueid','titre','url_de_contenu.html', {options});
							ou Popups.create('uniqueid','titre','url_de_contenu.html', {options});
							
		     ex: var p = new Popup('popup1','titre du popup1','toto.aspx', {useEffects:true,draggable:true});
		     
fermeture du popup: p.close(); ou Popups.close('popup1')

-----------------------------------------------------------------*/


//tableau qui contient tous les popups existants
//+ quelques fonctions d'accès rapide (create/find/moveTo/close)
var Popups = {
  ps: [],
  
  //création d'un nouveau popup
  create: function(id,title,url,options) {
    return new Popup(id,title,url,options);
  },
  
  //recherche
  find: function(id) {
    for(var i=0;i<this.ps.length;i++) {
        if(this.ps[i].id==id) return this.ps[i];
    }
    return null;
  },
  
  //déplacement à partir de l'id
  moveTo: function(id,top,left) {
    var p = this.find(id);
    if(p) p.moveTo(top,left);
  },
  
  //fermeture a partir de l'id
  close: function(id) {
    var p = this.find(id);
    if(p) p.close();
  },
  
  //debug fct
  test: function() {
  	var str = '';
  	for(var i=0;i<this.ps.length;i++) {
  		if(str.length>0) str += ',';
        str+=this.ps[i].id;
    }
   	alert('popups:'+str);
  },
  
  /*------------fonctions internes----------------*/
  
  //suppression du tableau
  _remove: function(popupObj) {
  	for(var i=0;i<this.ps.length;i++) {
        if(this.ps[i].id==popupObj.id) {
        	this.ps.splice(i,1);
        	break;
        }
    }
  },
  
  //ajout du tableau
  _add: function(popupObj) {
    this.ps.push(popupObj);
  },
  
  //recherche du dernier zindex
  _lastZIndex: function() {
  	var zindex = 0;
  	for(var i=0;i<this.ps.length;i++) {
        if(this.ps[i].node.style.zIndex>zindex) 
        	zindex=this.ps[i].node.style.zIndex;
    }
    return zindex;
  }
  
}

//gestion d'un popup
var Popup = Class.create();
var PopupsZIndex = 0;
Popup.prototype= {
    options: {
        beforeLoad:null,  /* fonction appelée avant l'appel AJAX (div du popup passé en parametre)*/
        afterLoad:null,   /* fonction appelée après l'appel AJAX (div du popup passé en parametre)*/
        useEffects:false, /* fadein/fadeout */
        top:'50',      	  /* position */
        left:'50',     	  /* position */
        draggable:true,   /* permet le déplacement de la fenetre*/
        className:'popup', /* classe css du div*/
        isUrl:true /*le contenu spécifié est une URL*/
    },
    
    //initialisation du popup
    initialize: function(id,title,url,options) {
    	 this.isClosing=false;
    	
    	 //stockage des propriétés
        this.id = id;
        this.title=title;
        this.url=url;
        
        //stockage des options
        Object.extend(this.options, options || {});
        
        //création contenu + chargement
        this._create();
        this._load();
        
        //ajout tableau global
        Popups._add(this);
    },
    
    //déplacement du popup
    moveTo: function(top,left) {
        this.node.style.top = top+'px';
		this.node.style.left = left+'px';
    },
    
    //fonction de fermeture du popup
	close: function() {
		if(this.isClosing) return;
		this.isClosing=true;
		
		if(this.options.useEffects) new Effect.Opacity(this.node,
		                                                  { duration: 0.5, 
		                                                    transition: Effect.Transitions.linear, 
		                                                    from: 1.0, to: 0.0,
		                                                    afterFinish: this._remove.bind(this) } );
		else this._remove();
			
		  //on arrete de suivre les évènements keypress
	    Event.stopObserving(document, "keypress", this.eventKeyPress);
	    //et close
	    Event.stopObserving(this.link, "click", this.eventClose);
	    
	    //suppression du tableau global
	    Popups._remove(this);
	},
    
    /*-----------fonctions internes-----------------*/
    
    //création du code HTML du popup
    _create: function() {
        
		//création HTML
		this.node = this._createDiv();
		this.link = this._createCloseLink(this.node);
		var t = this._createTitle(this.node);
		this.content = this._createTemporaryContent(this.node);
		
		//gestion des effets
		if(this.options.useEffects) this.node.setOpacity(0.0);
		
		//déplacement
		this.moveTo(this.options.top,this.options.left);
		
		//ajout dans le body du document
		document.body.appendChild(this.node);
		
		//gestion du déplacement
		if(this.options.draggable)
		    new Draggable(this.node,{revert:false,handle:t,starteffect:null,endeffect:null});
	    
    },
    
    //création div principal
    _createDiv : function() {
    	var node = document.createElement('div');
		node.id = this.id;
		node.className = this.options.className;
		node.style.position = 'absolute';
		node.style.zIndex = ++PopupsZIndex;
						
		//gestion click -> topmost
		node.onclick = function() {
		  if(this.style.zIndex < PopupsZIndex) 
		      this.style.zIndex = ++PopupsZIndex;
		}
		
		//gestion fermeture avec ESC
		this.eventKeyPress = this._keypress.bindAsEventListener(this);
		Event.observe(document, "keypress", this.eventKeyPress);
		
		return $(node);
   	},
   	
   	//création lien de fermeture
   	_createCloseLink: function(nodeParent) {
   		var a = document.createElement('a');
		a.href="#";
		a.className='close';
		a.title='fermer cette fenêtre';
		
		//gestion fermeture avec ESC
		this.eventClose = this.close.bindAsEventListener(this);
		Event.observe(a, "click", this.eventClose);
		
		nodeParent.appendChild(a);
		return a;
    },
    
    //création titre de la page
    _createTitle: function(nodeParent) {
    	var t = document.createElement('h1');
		t.innerHTML=this.title;
		nodeParent.appendChild(t);
		return t;	
    },
    
    //création du contenu temporaire
    _createTemporaryContent: function(nodeParent) {
    	var p = document.createElement('p');
		p.className='loading';
		p.innerHTML='chargement des données...'
		nodeParent.appendChild(p);
		return $(p);	
		
    },
    
    //chargement du contenu du popup
    _load: function() {
        if(this.options.beforeLoad) 
        	this.options.beforeLoad(this.node);
        if(this.options.isUrl) {
	        new Ajax.Request(this.url, { method: 'get', 
	    	    							onComplete: this._loadComplete.bind(this) });
        }
        else {
            var response = {
                responseText: this.url
            };
            this._loadComplete(response);
        }
	 },
	 
	//fin du chargement, on met a jour dans la page
	_loadComplete: function(response) {
	 	  this.content.replace(response.responseText);
		  if(this.options.useEffects) new Effect.Opacity(this.node,
		                                                  { duration: 0.5, 
		                                                    transition: Effect.Transitions.linear, 
		                                                    from: 0.0, to: 1.0 });
		  if(this.options.afterLoad) this.options.afterLoad(this.node);
	},
	
	//suppression du popup
	_remove: function() {
    	this.node.remove();
    },
    
  //gestion appui sur la touche ESC
  _keypress: function(event) {
    if(event.keyCode!=Event.KEY_ESC) return;
    if(this.node.style.zIndex==PopupsZIndex) {
    	Event.stop(event); 
    	this.close();
    	
    	//recup dernier zindex existant avec timeout
    	setTimeout(function() {
    		PopupsZIndex=Popups._lastZIndex(); 
    	},200);
    }
  }
}


