/*
	Created: Jim O'Donnell, National Maritime Museum
	Date: 02/2007 
	Description: Controller script for zoomable, annotated pictures.
	Usage: 	Create a new zoomable image - HotSpotController.init(picID, size, imagePath, buttonID, callback)
			Add a note (optional) - HotSpotController.setHotspotSize(spotSize); - only need to call this once.
									HotSpotController.addHotspot(x,y,heading,note); - repeat as necessary.
	Input:	picID		id of img element to which the overlay will be added.
			size		magnifier size (pixels).
			imagePath	image path to use as the source of the magnified view.
			buttonID	id of the element to use as an on/off button.
			callback	optional callback function to execute once the magnifier has finished loading.
			spotSize	hotspot size (pixels).
			x,y			x,y coordinates (on the larger image) of a note.
			heading		note heading.
			note		note text (one para max). May contain inline HTML tags (<em>, <a>, <img> etc.)
						but not block level HTML (<p>, <div>, <h1> etc.)
	Usage example:
	<p id="ZTthumbnail">
		<img src="/collections/images/700/PY/32/PY3270.jpg" id="fullscreen"  alt="London, from Greenwich. Picture in the possession of Walter Fawkes Esqr. of Farnley" /> 
	</p>
	<script language="JavaScript" type="text/javascript">
		HotSpotController.init("fullscreen",300, '/collections/images/2000/PY3270.jpg', 'magnifyButton');
		HotSpotController.setHotspotSize(150);
		HotSpotController.addHotspot(0, 750, 'St Alfege Church', 'St Alfege, the parish church of Greenwich, commemorates Alfege, Saxon Archbishop of Canterbury. Having been captured by Viking raiders in 1012, he was taken to their camp at Greenwich and murdered after a drunken feast. A church was built on the supposed site of his death in the 12th century, succeeded by a later medieval one whose roof collapsed in a storm in 1710. The present church was completed by 1714 except for the tower, which is that of the earlier church faced in 1730 with Portland stone and with a spire also added at that time.');
		HotSpotController.addHotspot(887, 450, 'St. Paulâ€™s Cathedral', 'A cathedral dedicated to St Paul has overlooked the City of London since AD 604. The present cathedral, depicted here, is the fourth to occupy the same site. Designed by Sir Christopher Wren, it was built between 1675 and 1710 after its predecessor was destroyed in the Great Fire of London, 1666.');
	</script>
	
	Mises Ã  jour : Octavo (JL) - Avril 2009
	** Ajout de diffÃ©rentes fonctions gÃ©rant les clics et la sÃ©lection de pixels
	** Traitement des langues
	** Modification Ã  la volÃ©e du formulaire de sÃ©lection des pixels  	
*/

var Moveable = {
	obj: null,
	init: function(obj) {
		obj.move = this.move;
		this.x = parseInt(obj.style.left);
		this.y = parseInt(obj.style.top);
	},
	move: function(x,y) {
		Moveable.obj = this;
		var o = Moveable.obj;
        o.style.top = y +"px";
        o.style.left = x + "px";		
	}
};

var is_okay         = true; // GÃ¨re le statut du pixel sÃ©lectionnÃ©

var MaxAmountPixel4CB         = 15; // Nombre maximum de pixels sÃ©lectionnables pour un paiement CB
var MaxAlertIsDone            = false; // gÃ¨re l'affichage du message d'avertissement
var APixelCost                = 100; // CoÃ»t d'un pixel

var applwin                   = null; // Objet BoÃ®te de dialogue, permet le blocage du systÃ¨me si pas de validation
var dlg_canceled              = false; // GÃ¨re l'annulation de la boÃ®te de dialogue

var pixels                    = new Array; // Stocke les pixels sÃ©lectionnÃ©s


var HotSpotPic = {
	obj: null,
	hotspots: new Array(),
	hotspotSize: null,
	activeHotspot: null,
	init: function(obj) {
		obj.hotspots = this.hotspots;
		obj.hotspotSize = this.hotspotSize;
		obj.activeHotspot = this.activeHotspot;
		obj.addHotspot = this.addHotspot;
		obj.checkMessage = this.checkMessage;
		obj.getHotspot = this.getHotspot;
	},
	addHotspot: function(x,y,node) {
		HotSpotPic.obj = this;
		var o = HotSpotPic.obj;
		var hotspot = {x: x, y: y, node: node}
		o.hotspots.push(hotspot);
	},
	getHotspot: function(x,y) {
//return any stored note at x,y

		HotSpotPic.obj = this;
		var o = HotSpotPic.obj;
		var tmpHs = null;
		for (i=0;i<o.hotspots.length;i++) {
			var hotspot = o.hotspots[i];
			var node = hotspot.node;
			if (node != null) {
				if (x > (hotspot.x-o.hotspotSize) && x < (hotspot.x+o.hotspotSize) && y > (hotspot.y-o.hotspotSize) && y < (hotspot.y+o.hotspotSize)) {
					tmpHs = hotspot;
				}
			}
		}
		return tmpHs;
	},
	checkMessage: function(x,y) {
//is there a note at position (x,y)? If so, make it visible.
		HotSpotPic.obj = this;
		var o = HotSpotPic.obj;
		var className = '';
		
		var hotspot = this.getHotspot(x,y);
//Has the active hotspot changed? If so, hide the old one and make the new one active.
		if (hotspot != this.activeHotspot) {
			
			if (this.activeHotspot) {
				fadeOut(this.activeHotspot.node, 100);
				this.activeHotspot.node.style.zIndex = 1;
			}
			
			this.activeHotspot = hotspot;
			
			if (hotspot) {
				var tmpNode = hotspot.node;
				if (hotspot.x > HotSpotController.xMax/(2*HotSpotController.scaleFactor)) className = 'leftAlign';
		 		tmpNode.style.display = "block";
				tmpNode.style.zIndex = 100;
				fadeIn(tmpNode, 0);
				document.getElementById('captionContainer').className = className;
			}
		}
		
	}

};

var HotSpotController = {
	init: function(thumbnailID, viewPortSize, filePath, toggleID, callback) {
	
//reduced size image
		var thumbImage = document.getElementById(thumbnailID);
		
// control to toggle the overlay on/off;
		var toggleControl = document.getElementById(toggleID);
		
		this.hasRun = true;
		
		// on met l'input de la quantité + le bouton ok invisible dès qu'on arrive sur la page
		document.getElementById("quantity").style.visibility = 'hidden';
		document.getElementById("bt_ok").style.visibility = 'hidden';
		
//Container needs to wrap around image.
		thumbImage.parentNode.style.width = thumbImage.width+'px';

//create the overlay container.
		this.overlay = document.createElement('div');
		this.overlay.setAttribute('id', 'ZToverlay');
		this.overlay.style.visibility = 'hidden';
		//this.overlay.style.width = viewPortSize+'px';
		//this.overlay.style.height = viewPortSize+'px';
		//this.overlay.style.overflow = 'auto';
		thumbImage.parentNode.insertBefore(this.overlay, thumbImage);
// link so overlay can have keyboard focus
		var accessLink = document.createElement('a');
		accessLink.setAttribute('href', 'javascript:void(0);'); // slightly icky. oh well.
    addEvent(accessLink, 'keydown', keyPress);
		addEvent(accessLink, 'keypress', keyPress);
		this.overlay.appendChild(accessLink);
//draggable square
		this.magnifier = document.createElement('div');
		this.magnifier.setAttribute('id', 'magnifier');
		accessLink.appendChild(this.magnifier);
//container for the full size image - defines the viewable region.
		var viewPort = document.createElement('div');
		viewPort.setAttribute('id', 'viewPort');
//full size image.
		var image = document.createElement('img');
			image.setAttribute('src', filePath);
			image.setAttribute('id', 'ZTview');
			image.style.top = "0";
			image.style.left = "0";
		viewPort.appendChild(image);

// cancel right clicks and context menu events on the hi-res image.
		//addEvent(image, 'mousedown', cancelRightClick);
		addEvent(image, 'contextmenu', cancelEvent);
		accessLink.appendChild(viewPort);
		this.zoomedView = image;
//initialise the view port height and width.
		this.setSize(viewPort, viewPortSize, viewPortSize);
		
		this.viewPortSize = viewPortSize;
		
		viewPort.style.top = (-1*viewPortSize)-10 + "px";
		viewPort.style.left = (-1*viewPortSize)/2.4 + "px";
		
//make various bits and pieces moveable etc. 
//These are all decorator classes which add methods to existing DOM objects.
		// Mise en commentaire : Ã©viter que l'image zoomÃ©e puisse Ãªtre dÃ©placÃ©e
    Moveable.init(this.zoomedView);
    Moveable.init(this.magnifier);
		Moveable.init(this.overlay);
		HotSpotPic.init(this.zoomedView);
		
// add a handler to finish setup once the full size image has finished loading.
// stupid opera doesn't fire onload when a cached image loads - use img.complete instead.
		
		/*
    if(!user_agent.is_msie()){
      // On attend le chargement complet de l'image
      while(!image.complete){
        // Il faudrait trouver une tite animation le temps du chargement...
      }
		}
		*/
    
    if (image.complete) {
			this.finishSetup(thumbImage, toggleControl, callback);
			// viewPort
      
      if(!user_agent.is_msie()){
        addEvent(viewPort,'click',selectandnext); // Ajoute le contrÃ´leur de clic sur l'image zoomÃ©e
        // Permet de visualiser le numÃ©ro du pixel survolÃ©...
        addEvent(viewPort,'mousemove',showPixel);
        addEvent(viewPort,'mouseout',hidePixel);
      }

		} else {
			addEvent(image, 'load', function() {HotSpotController.finishSetup(thumbImage, toggleControl, callback)});
//if the image doesn't existing, remove the loading message and quit without finishing the set-up.
			addEvent(image, 'error', function() {
											  deleteLoadingMessage('loadingMessage');
											  });
			setLoadingMessage(thumbImage, localization['loading'], 'loadingMessage');
		}
	},
	finishSetup: function(thumbImage, toggleControl, callback) {
		deleteLoadingMessage('loadingMessage');
		if(user_agent.is_msie()){
      addEvent(viewPort,'click',selectandnext); // Ajoute le contrÃ´leur de clic sur l'image zoomÃ©e
      // Permet de visualiser le numÃ©ro du pixel survolÃ©...
      addEvent(viewPort,'mousemove',showPixel);
      addEvent(viewPort,'mouseout',hidePixel);
    }
//scale factor for scaling between motion of the small image and motion of the large image.
// don't try this until zoomedView.width > 0 ie. until zoomedView has loaded.
		HotSpotController.scaleFactor = thumbImage.width/this.zoomedView.width;
//rescale magnifier to match our viewport size.
		HotSpotController.setSize(this.magnifier, this.viewPortSize*this.scaleFactor, this.viewPortSize*this.scaleFactor);
//set drag boundaries for the magnifier
		HotSpotController.xMax = thumbImage.width - (this.viewPortSize * this.scaleFactor);
		HotSpotController.yMax = thumbImage.height - (this.viewPortSize * this.scaleFactor);
		

// make the overlay draggable and add a handler to respond to drag events.
		Drag.init(this.overlay, null, 0, this.xMax, 0, this.yMax);
		HotSpotController.overlay.onDrag = function(x, y) {
	//When the magnifier is dragged, move the large image back by an equivalent amount to bring the selected region into view.
	//Check to see if we should display a message at the new position.
			curr_x = x/HotSpotController.scaleFactor;
			curr_y = y/HotSpotController.scaleFactor;
	//Large image moves in the opposite direction to the magnifier.
			HotSpotController.zoomedView.move(-1*curr_x, -1*curr_y);
			HotSpotController.zoomedView.checkMessage(curr_x,curr_y);
		}

//Suggestion from Pat Lauke - start in the center of the picture.
		HotSpotController.jump(thumbImage.width/2,thumbImage.height/2);
		
// Ajoute le gestionnaire d'Ã©vÃ©nement pour traiter les clics sur le zoom
HotSpotController.zoomedView.onClick = function(){
  alert("Clic sur le zoom !");
  return;
}

// add event handlers for jumping around the picture and toggling the overlay on and off.
		addEvent(thumbImage, 'click', function(e) {
											   toggleControl.focus();
											   HotSpotController.jumpToMouseClick(e);
											   cancelEvent(e);
											   });
// Why doesn't the following line work for the enter key in Safari?
		addEvent(toggleControl, 'click', function(e) {
												  toggleControl.focus();
												  toggleVisibility(HotSpotController.overlay);
												  HotSpotController.toggleHotspots();
												  cancelEvent(e);
												  return false;
												  });
// Add support for keyboard control
		addEvent(toggleControl, 'keydown', keyPress);
		addEvent(toggleControl, 'keypress', keyPress);
		toggleControl.className = 'active';
//controls for notes. Show notes if query param present in URL.
		var noteButton = document.getElementById('ZTnotes');
		if (noteButton) {
			addEvent(noteButton, 'click', HotSpotController.toggleHotspots);
			noteButton.className = 'active';
		}
		if(callback) callback();
	},
	setHotspotSize: function(size) {
		this.zoomedView.hotspotSize = size;
	},
	addHotspot: function(x,y,heading,caption) {
		var captionContainer = document.getElementById('captionContainer');
		var node = document.createElement('li');
		node.className = 'HScaption';
		node.appendChild(getHTMLElement('h2',heading));
		node.appendChild(getHTMLElement('p',caption));
		if (!captionContainer) {
			captionContainer = document.createElement('ul');
			captionContainer.setAttribute('id', 'captionContainer');
			this.overlay.appendChild(captionContainer);
		}
		captionContainer.appendChild(node);
		this.zoomedView.addHotspot(x,y,node);
	},
	toggleHotspots: function() {
		if (HotSpotController.showNotes) {
			HotSpotController.hideHotspots();
		} else {
			HotSpotController.showHotspots();
		}
	},
	showHotspots: function() {
		var len = this.zoomedView.hotspots.length;
		for ( var i=0; i<len; ++i ){
			if(typeof(console) != 'undefined') console.log(i);
			var marker = this.getHotspotMarker(this.zoomedView.hotspots[i]);
			marker.style.display = 'block';
		}
		this.showNotes = true;
	},
	hideHotspots: function() {
		var len = this.zoomedView.hotspots.length;
		for ( var i=0; i<len; ++i ){
			var marker = this.getHotspotMarker(this.zoomedView.hotspots[i]);
			marker.style.display = 'none';
		}
		this.showNotes = false;
	},
	getHotspotMarker: function(hotspot) {
/*
create a new DOM node to display a hotspot on the screen.
The new node is a sibling of the thumbnail image.
We will use absolute positioning to place the new node relative to the 
top left corner of the thumbnail.
*/
		var id = 'hsx' + hotspot.x + 'y' + hotspot.y;
		if (!document.getElementById(id)) {
			var newNode = document.createElement('a');
			var image = document.createElement('img');
			//alert("Facteur " + this.scaleFactor + " taille de l'Ã©lÃ©ment viewport " + this.viewPortSize);
			//var size = this.viewPortSize * this.scaleFactor;
			var size = 1; // Force la taille du hotspot Ã  5 pixels de cÃ´tÃ©
			var parent = this.overlay.parentNode;
			
			this.setSize(image, size, size);
			this.setSize(newNode, size, size);

//without this, the link won't be clickable in IE6
//			image.setAttribute('src', '/collections/shared/images/transparent.gif');
//			image.setAttribute('alt', '');
//			newNode.appendChild(image);
			
			// Ici, Ã©ventuellement, on ajoute un lien vers la fiche du donateur
			newNode.setAttribute('href', 'javascript:void(0);');
			newNode.style.position = 'absolute';
			newNode.style.display = 'none';
			newNode.style.zIndex = 10;
			newNode.style.left = hotspot.x*this.scaleFactor+'px';
			newNode.style.top = hotspot.y*this.scaleFactor+'px';
			newNode.className = 'translucent';
			newNode.id = id;
			addEvent(newNode, 'focus', function() {
					if (HotSpotController.overlay.style.visibility == 'hidden') {
						HotSpotController.overlay.style.visibility = 'visible';
					}
					//HotSpotController.jump(parseInt(hotspot.x*HotSpotController.scaleFactor)+size/2,parseInt(hotspot.y*HotSpotController.scaleFactor)+size/2)
				});
			addEvent(newNode, 'click', function() {
			    // Afficher ici la surimpression
					if (HotSpotController.overlay.style.visibility == 'hidden') {
						HotSpotController.overlay.style.visibility = 'visible';
					}
					//HotSpotController.jump(parseInt(hotspot.x*HotSpotController.scaleFactor)+size/2,parseInt(hotspot.y*HotSpotController.scaleFactor)+size/2)
				});
			parent.appendChild(newNode);
			return newNode;
		} else {
			return document.getElementById(id);
		}
	},
	setSize: function(obj, height, width) {
//set the size of obj to height and width in pixels.
    	obj.style.width = width + "px";
		obj.style.height = height + "px";			
	},
	jumpToMouseClick: function(e) {
		var x = 0;
		var y = 0;
		var coords = getXY(e);
		
		x = coords.x;
		y = coords.y;
		HotSpotController.jump(x,y);
	},
	jump: function(x,y) {
		
		var size = parseInt(HotSpotController.magnifier.style.width)*0.5;
		x = parseInt(x);
		y = parseInt(y);
//		if (typeof console != 'undefined') console.log(size);
// suggestion from MCG list - keep x,y inside drag boundaries.
		x = x-size;
		y = y-size;
		x = Math.max(0,x);
		y = Math.max(0,y);
		x = Math.min(x, HotSpotController.xMax);
		y = Math.min(y, HotSpotController.yMax);
//		if (typeof console != 'undefined') console.log('x:'+x+' y:'+y);
		HotSpotController.overlay.move(x,y);
		HotSpotController.overlay.onDrag(x,y);
	},
	move: function(keyCode, step) {
	// experimental support for keyboard navigation.
	// move the overlay in response to the cursor keys.
	// only does up, down, left, right at present.
		var curr_x = parseInt(HotSpotController.overlay.style.left);
		var curr_y = parseInt(HotSpotController.overlay.style.top);
		var new_x = curr_x;
		var new_y = curr_y;
		
		switch(keyCode) {
			case 37: //left
				new_x = Math.max(curr_x - step, 0);
				new_y = curr_y;
			break;
			case 38: //up
				new_x = curr_x;
				new_y = Math.max(curr_y - step, 0);
			break;
			case 39: //right
				new_x = Math.min(curr_x + step, this.xMax);
				new_y = curr_y;
			break;
			case 40: //down
				new_x = curr_x;
				new_y = Math.min(curr_y + step, this.yMax);
			break;
		}
		HotSpotController.overlay.move(new_x, new_y);
		HotSpotController.zoomedView.move(-1*new_x/this.scaleFactor, -1*new_y/HotSpotController.scaleFactor);
		HotSpotController.zoomedView.checkMessage(new_x/this.scaleFactor, new_y/HotSpotController.scaleFactor);
	}

};

function getTextElement(elementName, text) {
	var node = document.createElement(elementName);
	var textNode = document.createTextNode(text);
	node.appendChild(textNode);
	return node;
}

function getHTMLElement(elementName, html) {
	var node = document.createElement(elementName);
	var d = document.createElement('div');
	d.innerHTML = html;

	while (d.firstChild) {
		node.appendChild(d.firstChild);
	}
	return node;
}

function toggleVisibility(node) {
	if(node.style.display == "none" || node.style.visibility == "hidden") {
		node.style.display = "block";
		node.style.visibility = "visible";
		standardsFadeIn(node,0);
		
	} else {
		
		node.style.display = "none";
	}
}

function getXY(e) {
// Return x,y position of mouse clicks relative to target element.
// Works in IE, Firefox and Safari. Haven't tried Opera.
		if (e.layerX) {
			x = e.layerX;
			y = e.layerY;
		} else if (e.offsetX) {
			x = e.offsetX;
			y = e.offsetY;
		} else {
			x = e.x;
			y = e.y;
		}
		
		return {x:x,y:y};
}

function cancelRightClick(e) {
  cancelEvent(e);
  //alert("ExÃ©cution de cancelRightClick");
	var rightclick;
	if (e.which) rightclick = (e.which == 3);
	else if (e.button) rightclick = (e.button == 2);
	if (rightclick) {
		cancelEvent(e);
	}
}

function selectandnext(e) {
  /****************************************************************************/
  /* DÃ©claration des variables locales                                        */
  /****************************************************************************/  
	var coords          = getXY(e); // RÃ©cupÃ¨re les coordonnÃ©es du pixel cliquÃ©
  var nb_pixels       = 0;
  var XHR             = new XHRConnection(); // Objet d'appels Ajax
  var script_name     = new String;
  var dlg_msg         = new String;
  var dlg_return_code = 0;
  var unserialize     = new RegExp("[=]","g");
  var datas           = new Array;
  
  var x               = 0;
  var y               = 0; // CoordonnÃ©es divisÃ©es par 10 pour rÃ©tablissement de la proportion
  
  /****************************************************************************/
  /* ImplÃ©mentation                                                           */
  /****************************************************************************/
  
  if(applwin == null || dlg_canceled){ 
    // LÃ , on traite la disponibilitÃ© du pixels... appel Ajax... et analyse du retour
    //alert("CoordonnÃ©es cliquÃ©es : (" + coords.x + ", " + coords.y + ") - (" + e.x + ", " + e.y + ")");
    x = parseInt(coords.x / 10);
    y = parseInt(coords.y / 10);
    
      // VÃ©rifie si le pixel courant n'est pas dÃ©jÃ  dans la sÃ©lection
      if(!already_exists(coords.x,coords.y)){ // A ce moment, le pixel ne fait pas partie du tableau interne "pixels"
        XHR.appendData("x_coord",x); // CoordonnÃ©e X du pixel cliquÃ©
        XHR.appendData("y_coord",y); // CoordonnÃ©e Y du pixel cliquÃ©
        XHR.appendData("session_name",document.getElementById("session_name_ID").value);
        
        script_name = path_to_root() + "templates/200000pixels/includes/ajax_scripts/check_4_pixel.ajax.php";
        
        // Appel le script Ajax de contrÃ´le et met Ã  jour la variable is_okay gÃ©nÃ©rale
        XHR.sendAndLoad(script_name,"POST",set_is_okay);
        
        // Si tout est okay... on ajoute au panier... Le panier est constituÃ© d'une zone de saisie entiÃ¨re
        // et d'une liste... de pixels...
        // GÃ©nÃ¨re le calcul du coÃ»t total ainsi que du crÃ©dit d'impÃ´t associÃ©
        if(is_okay){
          // GÃ©nÃ¨re le message qui doit Ãªtre affichÃ© dans le dialogue
          dlg_msg = localization['select_pixel'] + ": <strong>" + get_num_pixel(coords.x,coords.y) + "</strong>";
          dlg_msg += "\n<br/>";
          dlg_msg += localization['ajouter'];
          dlg_msg += "\n<br/>";
          dlg_msg += "<input type=\"radio\" name=\"yes_no\" value=\"1\" onclick=\"give_focus(true);\">&nbsp;" + localization['oui'] + "&nbsp;&nbsp;";
          dlg_msg += "<input type=\"radio\" name=\"yes_no\" value=\"0\" onclick=\"give_focus(false);\">&nbsp;" + localization['non'] + "&nbsp;&nbsp;";
          // Affiche une boÃ®te de dialogue permettant l'ajout du pixel sÃ©lectionnÃ©... ou non !
          applwin = new DialogWindow(dlg_msg, {
            hideApplyButton: true,
            hideCancelButton: false,
            title:localization['caption_title'],
            top:45,
            left:450,
            okText:localization['ok'],
            cancelText:localization['cancel'],
            modal:true
          });
                                  
          // assign event handler for apply event
          applwin.apply(function() {
            //alert('Enregistrement en cours...');
            //alert(this.serialize(true));
            //alert(this.serialize(false));
            // DÃ©termine le code de retour Ã  partir des donnÃ©es sÃ©rialisÃ©es
            datas = this.serialize(false).split(unserialize);
            dlg_return_code = datas[1];
            
            if(dlg_return_code == 1){
              // Ajoute le pixel au tableau des pixels internes
              //alert("Ajoute " + get_num_pixel(coords.x,coords.y) + " au tableau interne.");
              pixels.push(get_num_pixel(coords.x,coords.y));
              
              // DÃ©termine le nombre de pixels courants
              //nb_pixels = document.getElementById("quantity").value;
              //nb_pixels++;
              nb_pixels = pixels.length;
              
              // IntÃ¨gre le contrÃ´le sur le nombre de pixels sÃ©lectionnÃ©s
              if((nb_pixels > MaxAmountPixel4CB) && !MaxAlertIsDone){
                alert(localization['up_to'] + MaxAmountPixel4CB + localization['pixel_cmd']);
                MaxAlertIsDone = true; // Pour ne pas rÃ©afficher le message aprÃ¨s coup
              }
              document.getElementById("quantity").value = nb_pixels;
              
              // Calcule le montant total du don
              document.getElementById("montant_don").value = nb_pixels * APixelCost;
              
              // GÃ¨re l'affichage des champs du formulaire courant
              if(!document.getElementById("rd_avec_sel").disabled){
                document.getElementById("rd_avec_sel").disabled = true;
              }
              if(!document.getElementById("rd_sans_sel").disabled){
                document.getElementById("rd_sans_sel").disabled = true;
              }
              if(!document.getElementById("quantity").readOnly){
                document.getElementById("quantity").readOnly = true;
                
              }
              document.getElementById("quantity").style.visibility = 'visible';
              document.getElementById("bt_ok").style.visibility = 'visible';
              
              // Ajoute une ligne, si ce n'est pas dÃ©jÃ  fait... dans le tableau et met Ã  jour la select box
              
              if(document.getElementById("pixelSelectBox")){
                // La ligne dans le tableau est dÃ©jÃ  crÃ©Ã©e

                // Suppression de toutes les options...
                var selectBox = document.getElementById("pixelSelectBox");
                var nodeList = selectBox.getElementsByTagName("option");
                while(selectBox.hasChildNodes()){
                  var node = nodeList.item(0);
                  selectBox.removeChild(node);
                }
                // RecrÃ©e la liste avec les Ã©lÃ©ments
                // Ajoute la ligne d'en-tÃªte du tableau
                var oOption = document.createElement("option");
                selectBox.appendChild(oOption);
                oOption.value = 0; // Option par dÃ©faut
                oOption.text = localization["selBox_title"];
                
                // Alimente la liste avec les pixels dÃ©jÃ  sÃ©lectionnÃ©s
                for(i=0;i<pixels.length;i++){
                  oOption = document.createElement("option");
                  selectBox.appendChild(oOption);
                  oOption.value = i+1;
                  oOption.text = pixels[i];
                }
             
                // Ajoute la derniÃ¨re ligne pour vider le panier
                oOption = document.createElement("option");
                selectBox.appendChild(oOption);
                oOption.value = 99; // Option par dÃ©faut
                oOption.text = localization["selBox_empty"];              
               
              } else {
                // Ajoute une ligne au tableau
                var new_line = document.createElement("tr");
                // SpÃ©cifie un ID spÃ©cique, pour pouvoir supprimer la ligne le cas Ã©chÃ©ant
                new_line.setAttribute("id","selectLine");
                
                var new_col  = document.createElement("td");
                new_col.colSpan = "2"; // Hack IE qui ne comprend pas toujours setAttribute
                

                // CrÃ©ation de la liste dÃ©roulante qui va bien...
                var selectBox = document.createElement("select");
                selectBox.setAttribute("height",1);
                selectBox.setAttribute("id","pixelSelectBox");
                //selectBox.setAttribute("onchange","check_if_empty();");
                selectBox.onchange = function(){check_if_empty();};              
                // Ajoute la ligne d'en-tÃªte du tableau
                var oOption = document.createElement("option");
                selectBox.appendChild(oOption);
                oOption.value = 0; // Option par dÃ©faut
                oOption.text = localization["selBox_title"];
                
                // Alimente la liste avec les pixels dÃ©jÃ  sÃ©lectionnÃ©s
                for(i=0;i<pixels.length;i++){
                  oOption = document.createElement("option");
                  selectBox.appendChild(oOption);
                  oOption.value = i+1;
                  oOption.text = pixels[i];
                }
             
                // Ajoute la derniÃ¨re ligne pour vider le panier
                oOption = document.createElement("option");
                selectBox.appendChild(oOption);
                oOption.value = 99; // Option par dÃ©faut
                oOption.text = localization["selBox_empty"];
                                            
                new_col.appendChild(selectBox);
  
                              
                new_line.appendChild(new_col);
                
                document.getElementById("cartSettings").getElementsByTagName("tbody")[0].appendChild(new_line);
              }
            	// Ajoute le pixel sÃ©lectionnÃ© Ã  la session courante via Ajax
            	script_name = path_to_root() + "templates/200000pixels/includes/ajax_scripts/add_a_pixel.ajax.php";
            	
              XHR = new XHRConnection();
            	
            	// Ajoute les informations Ã  traiter
              XHR.appendData("x_coord",x); // CoordonnÃ©e X du pixel cliquÃ©
              XHR.appendData("y_coord",y); // CoordonnÃ©e Y du pixel cliquÃ©
              XHR.appendData("pixel",get_num_pixel(coords.x,coords.y));
              XHR.appendData("session_name",document.getElementById("session_name_ID").value);
              
              XHR.sendAndLoad(script_name,"POST"); // Appel au script d'alimentation de la session courante                        
            } else {
              // Supprimer la derniÃ¨re valeur du tableau
              //alert("Supprime le dernier Ã©lÃ©ment du tableau !");
              //pixels.pop();
            }
          	// Restaure la valeur de la boÃ®te de dialogue Ã  null
          	applwin = null;
            
            /*
            // GÃ¨re le masquage de la zone "panier" pour ajouter la liste des pixels
            if(document.getElementById('cartContent').style.visibility == 'visible'){
              document.getElementById('cartContent').style.visibility = 'hidden';
            }
            */        	
          });
          
          applwin.el.style.width = '400px';
          applwin.el.style.height = '100px';
          applwin.show();
              
        } else {
          // DÃ©pile l'Ã©lÃ©ment du tableau
          //alert("Supprime le dernier Ã©lÃ©ment du tableau !");
          //pixels.pop();
          // Afficher une boÃ®te de dialogue affichant le fait que le pixel courant est dÃ©jÃ  sÃ©lectionnÃ©
          (new DialogWindow(localization['unavailable'])).show();
        }
      } else {
        // Affiche un message indiquant que le pixel a dÃ©jÃ  Ã©tÃ© sÃ©lectionnÃ©
        (new DialogWindow(localization['already_in_basket'])).show();
      }
	}

	
  return;
}

/******************************************************************************/
/* private void showPixel(void)                                               */
/*  @access private                                                           */
/*  @type Gestionnaire d'Ã©vÃ©nement                                            */
/*  @param void                                                               */
/*  @return void                                                              */
/*  @comment Masque l'infobulle dÃ¨s que la souris sort de la zone             */
/******************************************************************************/
function hidePixel(){
  /****************************************************************************/
  /* DÃ©claration des variables locales                                        */
  /****************************************************************************/
  
  /****************************************************************************/
  /* ImplÃ©mentation                                                           */
  /****************************************************************************/
  pixel_box = document.getElementById("pixel-box");
  
  pixel_box.innerHTML = "";
  
  return;
}

/******************************************************************************/
/* private void showPixel(event e)                                            */
/*  @access private                                                           */
/*  @type Gestionnaire d'Ã©vÃ©nement                                            */
/*  @param event e                                                            */
/*  @return void                                                              */
/*  @comment Affiche le numÃ©ro du pixel survolÃ© dans une info-bulle           */
/******************************************************************************/
function showPixel(e){
  /****************************************************************************/
  /* DÃ©claration des variables locales                                        */
  /****************************************************************************/
  var coords          = getXY(e); // RÃ©cupÃ¨re les coordonnÃ©es du pixel cliquÃ©
  
  var x               = 0;
  var y               = 0;
  
  // Positionnement de l'infobulle
  var pos_x           = new String;
  var pos_y           = new String;
  var left_offset     = 500;
  var top_offset      = 200;
  
  var num_pixel       = 0; // NumÃ©ro du pixel courant
  
  var pixel_box       = null;
  
  /****************************************************************************/
  /* ImplÃ©mentation                                                           */
  /****************************************************************************/
  x = parseInt(coords.x / 10);
  y = parseInt(coords.y / 10);
  
  num_pixel = get_num_pixel(coords.x,coords.y);
  
  pixel_box = document.getElementById("pixel-box");
  pixel_box.style.textAlign = "center";
  
  pixel_box.innerHTML = "<strong>" + num_pixel + "</strong>";
  
  /* @RFC : gÃ©rer correctement l'affichage qui suit la souris avec le dÃ©calage
  // GÃ©nÃ¨re l'infobulle qui suit la souris
  document.getElementById("showpixel").innerHTML = "<strong>Pixel : " + num_pixel + "</strong>";
  

  // Affiche l'infobulle
  pos_x = (x + left_offset) + 'px';
  pos_y = (y + top_offset) + 'px';
    
  //pixel_box.innerHTML += "<br/>" + pos_x + " - " + pos_y;
  

  if(user_agent.is_msie()){
    document.getElementById("showpixel").style.left = pos_x;
    document.getElementById("showpixel").style.top = pos_y;
  } else {
    document.getElementById("showpixel").style.left = '300px';
    document.getElementById("showpixel").style.top = '350px';
  }
  */
    
  return;
}

/******************************************************************************/
/* private void set_is_okay(object obj)                                       */
/*  @access private                                                           */
/*  @type setter                                                              */
/*  @param object obj : objet gÃ©nÃ©rÃ© par l'appel Ajax                         */
/*  @return void                                                              */
/*  @comment Callback ajax permettant de dÃ©terminer si un pixel peut-Ãªtre     */
/*    ajoutÃ© au panier.                                                       */
/*    Les contenus du XML sont :                                              */
/*      value => vrai si le pixel peut Ãªtre ajoutÃ© au panier                  */
/*      x_coord => coordonnÃ©e X du pixel sÃ©lectionnÃ©                          */
/*      y_coord => coordonnÃ©e Y du pixel sÃ©lectionnÃ©                          */
/*      pixel => numÃ©ro du pixel dÃ©duit                                       */       
/******************************************************************************/
function set_is_okay(obj){
  /****************************************************************************/
  /* DÃ©claration des variables locales                                        */
  /****************************************************************************/
  var tabResult = obj.responseXML.getElementsByTagName('resultat');
  var resultat  = null;
    
  /****************************************************************************/
  /* ImplÃ©mentation                                                           */
  /****************************************************************************/

  resultat = tabResult.item(0); // RÃ©cupÃ¨re le rÃ©sultat renvoyÃ©
  
  is_okay = resultat.getAttribute("value");
    
  return;  
}

/******************************************************************************/
/* private bool already_exists(int x_coord,y_coord)                           */
/*  @access private                                                           */
/*  @type setter                                                              */
/*  @param int x_coord                                                        */
/*  @param int y_coord                                                        */
/*  @return bool                                                              */
/*  @comment VÃ©rifie si le pixel n'a pas dÃ©jÃ  Ã©tÃ© ajoutÃ© et alimente le       */
/*    tableau des pixels pour la session courante.                            */
/******************************************************************************/
function already_exists(x_coord,y_coord){
  /****************************************************************************/
  /* DÃ©claration des variables locales                                        */
  /****************************************************************************/
  
  /****************************************************************************/
  /* ImplÃ©mentation                                                           */
  /****************************************************************************/
  if(!in_array(get_num_pixel(x_coord,y_coord),pixels)){
    //pixels.push(get_num_pixel(x_coord,y_coord));
    return false;
  }
  return true;
}  

/******************************************************************************/
/* private int get_num_pixel(int x_coord,int y_coord)                         */
/*  @access private                                                           */
/*  @type getter                                                              */
/*  @param int x_coord                                                        */
/*  @param int y_coord                                                        */
/*  @return int => NumÃ©ro du pixel                                            */
/*  @comment Calcule et retourne le numÃ©ro du pixel Ã  partir des coordonnÃ©es  */
/******************************************************************************/
function get_num_pixel(x_coord,y_coord){
  /****************************************************************************/
  /* DÃ©claration des variables locales                                        */
  /****************************************************************************/
  var num_pixel         = 0;
  
  var x                 = parseInt(x_coord/10);
  var y                 = parseInt(y_coord/10);
  
  /****************************************************************************/
  /* ImplÃ©mentation                                                           */
  /****************************************************************************/
  
  //num_pixel = ((y_coord + 1) * 586) + x_coord;
  num_pixel = ((y + 1) * 586) + x;
  return num_pixel;
}

function getcoords(e) {
  /****************************************************************************/
  /* DÃ©claration des variables locales                                        */
  /****************************************************************************/  
	var coords          = getXY(e); // RÃ©cupÃ¨re les coordonnÃ©es du pixel cliquÃ©
  
  alert("CoordonnÃ©es cliquÃ©es : (" + coords.x + ", " + coords.y + ")");
  return;
}

function cancelEvent(e) {
	if (e && e.preventDefault) e.preventDefault(); // DOM event cancel
	return false; // IE event cancel
}

function setLoadingMessage(node, message, id) {
	var lm = getTextElement('span', message);
	lm.setAttribute('id', id);
	node.parentNode.insertBefore(lm,node);
}

function deleteLoadingMessage(id) {
	var node = document.getElementById(id);
	if (node) node.parentNode.removeChild(node);
}

	function keyPress(e) {
		var step = 2;
		var keyCode = e.keyCode;
		
		if (e.shiftKey) step = 20;
		
	//Map safari keycodes to codes generated by other browsers.
		switch (keyCode) {
		  case 63234:
			keyCode = 37;
			break;
		  case 63232:
			keyCode = 38;
			break;
		  case 63235:
			keyCode = 39;
			break;
		  case 63233:
			keyCode = 40;
			break;
		  default:;
		}
	//pass the code for the key that was pressed to the controller's keyboard function
		if (keyCode >= 37 && keyCode <= 40) {
			HotSpotController.move(keyCode, step);
			if (e && e.preventDefault) e.preventDefault(); // DOM event cancel
			return false; // IE event cancel
		} else {
			return true;
		}
	}

	function setOpacity(obj, opacity) {
	  opacity = (opacity == 100)?99.999:opacity;
	  
	  // IE/Win
	  obj.style.filter = "alpha(opacity:"+opacity+")";
	  
	  // Safari<1.2, Konqueror
	  obj.style.KHTMLOpacity = opacity/100;
	  
	  // Older Mozilla and Firefox
	  obj.style.MozOpacity = opacity/100;
	  
	  // Safari 1.2, newer Firefox and Mozilla, CSS3
	  obj.style.opacity = opacity/100;
	}
	
	function standardsFadeIn(obj,opacity) {
		if (opacity <= 100) {
		  obj.style.opacity = opacity/100;
		  opacity += 10;
		  window.setTimeout(function() {
							standardsFadeIn(obj, opacity);
									 }, 
									 50);
		}
	}

	function fadeIn(obj,opacity) {
		if (opacity <= 100) {
		  setOpacity(obj, opacity);
		  opacity += 10;
		  window.setTimeout(function() {
							fadeIn(obj, opacity);
									 }, 
									 50);
		}
	}
	function fadeOut(obj,opacity) {
		if (opacity >= 0) {
		  setOpacity(obj, opacity);
		  opacity -= 10;
		  window.setTimeout(function() {
							fadeOut(obj, opacity);
									 }, 
									 50);
		} else {
			obj.style.display = 'none';
		}
	}
	function getQueryVariable(variable) {
  		var query = window.location.search.substring(1);
  		var vars = query.split("&");
  		for (var i=0;i<vars.length;i++) {
    		var pair = vars[i].split("=");
    		if (pair[0] == variable) {
      			return pair[1];
    		}
 		 }
  		return false;
	}


/******************************************************************************/
/* private void check_if_empty(obj)                                           */
/******************************************************************************/
function check_if_empty(){
  /****************************************************************************/
  /* DÃ©claration des variables locales                                        */
  /****************************************************************************/
  var selectBox = document.getElementById("pixelSelectBox");
 
  var XHR             = new XHRConnection(); // Objet d'appels Ajax
  var script_name     = new String;

  /****************************************************************************/
  /* ImplÃ©mentation                                                           */
  /****************************************************************************/  
  if(selectBox[selectBox.selectedIndex].value == 99){
    // Il faut vider la liste et restaurer les champs
    pixels = new Array; // Vide le tableau complÃ¨tement
    
    // Restauration des champs de saisie
    if(document.getElementById("rd_avec_sel").disabled){
      document.getElementById("rd_avec_sel").disabled = false;
    }
    if(document.getElementById("rd_sans_sel").disabled){
      document.getElementById("rd_sans_sel").disabled = false;
    }
    if(document.getElementById("quantity").readOnly){
      document.getElementById("quantity").readOnly = false;
    }
    document.getElementById("quantity").value = 0;
    
    // Suppression de la ligne du tableau...
    var line = document.getElementById("selectLine");
    document.getElementById("cartSettings").getElementsByTagName("tbody")[0].removeChild(line);
    
    // Vide la table osc_pixels via appel Ajax
    script_name = path_to_root() + "templates/200000pixels/includes/ajax_scripts/remove_pixels.ajax.php";
    XHR.appendData("session_name",document.getElementById("session_name_ID").value);
    XHR.sendAndLoad(script_name,"POST"); // Appel au script d'alimentation de la session courante
    
    // Interdit l'utilisation du bouton Ok de la boÃ®te
        
  }  
  return;
}  

function path_to_root(){
  // Permet de dÃ©terminer le chemin d'accÃ¨s aux extensions Ajax
  
  var host_name = location.hostname;
  var current_script_path = location.pathname;
  var localReg            = new RegExp("[localhost|127.0.0.1]","g");
  var slashReg            = new RegExp("[/]","g");
  var local               = false;
  var sub_folder          = 0;
  var return_path         = ''; // Chemin Ã  retourner
  var debug               = new String();
  var local_offset        = 0; // Calcule l'offset en fonction du navigateur
  var web_offset          = 0;
    
  // DÃ©termination de l'exÃ©cution du script
  if(host_name.match(localReg)){
    local = true;
  }
  
  // En fonction du navigateur
  if(navigator.appName.indexOf("Explorer") > -1){
    local_offset = 2;
    web_offset = 1;
  } else {
    local_offset = 3;
    web_offset = 2;
  }
  
  // DÃ©coupe le chemin pour dÃ©terminer la racine
  var path_parts = current_script_path.split(slashReg);
  
  script_name = path_parts[path_parts.length];
  
  /*
  // Pour debogage
  for(i=0;i<path_parts.length;i++){
    debug += path_parts[i] + "\n";  
  }
  alert(debug);
  */
  
  // DÃ©termine la profondeur du script courant
  if(local){
    sub_folder = path_parts.length - local_offset;
  } else {
    sub_folder = path_parts.length - web_offset;
  }
  
  // DÃ©termine le chemin Ã  retourner
  if(sub_folder == 1){
    return_path = './';
  } else {
    for(i=0;i<sub_folder;i++){
      return_path += '../';
    }
  }
  
  
  // Pour dÃ©bugage
  //alert("Chemin vers racine :" + return_path);
  
  return return_path;
}

/**
 * in_array() recherche needle  dans collection et retourne TRUE s'il s'y trouve, ou FALSE sinon.
 * 
 * Le troisiÃ¨me paramÃ¨tre strict est optionnel. S'il vaut TRUE alors in_array() vÃ©rifiera aussi 
 * que le type du paramÃ¨tre needle correspond au type de la valeur trouvÃ©e dans collection.
 * 
 * @param mixed needle
 * @param array collection
 * @param bool  strict (optionnel)
 * @return bool
 */
function in_array(needle, collection, strict) {
    
    if (strict == null) {
        strict = false;
    }
    
    var i = collection.length-1;
    
    if (i >= 0) {
        
        do {
            if (collection[i] == needle) {
                
                if (strict && typeof(collection[i]) != typeof(needle)) {
                    continue;
                }
                
                return true;
            }
        } while (i--);
    }
    
    return false;
} 

/******************************************************************************/
/* public void give_focus(bool give_it)                                       */
/*  @access public                                                            */
/*  @type MÃ©thode de manipulation d'objet                                     */
/*  @param bool give_it : Vrai si je dois activer le bouton ok, faux sinon    */
/*  @return void                                                              */
/******************************************************************************/
function give_focus(give_it){
  /****************************************************************************/
  /* DÃ©claration des variables locales                                        */
  /****************************************************************************/
  var ok_button = document.getElementById("ok_button"); // Bouton Okay du dialogue
  
  /****************************************************************************/
  /* ImplÃ©mentation                                                           */
  /****************************************************************************/
  if(user_agent.is_msie()){
    if(give_it){
      // Active le bouton ok
      ok_button.disabled = false;
      //alert("Doit activer le bouton Ok sous IE");
    } else {
      // DÃ©sactive le bouton ok
      if(!ok_button.disabled)
        ok_button.disabled = true;
      //alert("Doit dÃ©sactiver le bouton Ok sous IE");
    }
  }
  
  return;
}