window.$Drag = { }; // Dépend de event-1c.

/*
	Utilisation sur un élément "elem" :

	elem.onmousedown = $Drag.track(
		event,
		function(x, y, evt) { // what to do on move },
		function(evt) { // ondragstart }, // optional
		function(evt) { // ondragend } // optional
	);
*/


// Multiplie par $Drag.K (typ. 1/10) la grandeur du déplacement du curseur,
// lorsque ALT est enfoncé pendant le mousemove. Cela permet des modifications
// minimales de la valeur (pixel par pixel) sans exiger de contrainte excessive
// de la part de la main ou du doigt qui commande le pointeur.
$Drag.K = 0.1;


$Drag.Track = function(
//----=====-----------

	// L'évènement brut reçu lors du mousedown initial.
	EVT,
	// Le callback à appeler lors de tout changement de position.
	ONMOVE /* (x, y, evt) */,
	// Un callback éventuel, à appeler juste avant le tracking.
	ONDRAGSTART /* (evt) */,
	// Un callback éventuel, à appeler juste après le tracking.
	ONDRAGEND /* (evt) */
) {

	$Event.Cancel(EVT = $Event.NrmEvt(EVT)); // Évite des sélections anarchiques
	$Drag.ONMOVE = ONMOVE;
	$Drag.ONDRAGEND = ONDRAGEND;
var SAVED = EVT.Target.position;
EVT.Target.position = 'absolute';
	$Drag.ORIGIN_X = EVT.screenX;
	$Drag.ORIGIN_Y = EVT.screenY;
EVT.Target.position = SAVED;
	$Drag.DOCUMENT_ONMOUSEMOVE = document.onmousemove;
	$Drag.DOCUMENT_ONMOUSEUP = document.onmouseup;
	document.onmousemove = $Drag.MOUSEMOVE;
	document.onmouseup = $Drag.MOUSEUP;
	if (ONDRAGSTART)
		ONDRAGSTART(EVT);
};


$Drag.MOUSEMOVE = function(EVT) {
//----=========----------------

/*
	Traitement de tout évènement mousemove reçu entre un appel à $Drag.Drag(…)
	et un mouseup. Le traitement consiste à exprimer les coordonnées du pointeur
	relativement à la position du mousedown initial (puis à appliquer un facteur
	d'échelle éventuel, si la touche ALT est enfoncée) et à appeler, avec ces
	coordonnées, le callback renseigné initialement.
*/

	$Drag.ONMOVE(
		/* x */
		((EVT = $Event.NrmEvt(EVT)).altKey ?
			(EVT.screenX - $Drag.ORIGIN_X) * $Drag.K :
			(EVT.screenX - $Drag.ORIGIN_X)),
		/* y */
		(EVT.altKey ?
			(EVT.screenY - $Drag.ORIGIN_Y) * $Drag.K :
			(EVT.screenY - $Drag.ORIGIN_Y)),
		EVT
	);
	$Event.Cancel(EVT); // Évite certaine "capture" souris dans MSIE.
};


$Drag.MOUSEUP = function(EVT) {
//----=======----------------

/*
	Traitement du premier évènement mouseup reçu après un appel à $Drag.Drag(…).
	Le traitement consiste d'abord à rétablir tous les gestionnaires
	d'évènements, conformément à leur état d'avant le drag, ce qui conduit
	normalement à clôturer la phase drag en cours; ensuite, à appeler la fonction
	éventuelle de clôture du tracking.
*/

	$Event.Cancel(EVT = $Event.NrmEvt(EVT));
	document.onmousemove = $Drag.DOCUMENT_ONMOUSEMOVE;
	document.onmouseup = $Drag.DOCUMENT_ONMOUSEUP;
	if ($Drag.ONDRAGEND)
		$Drag.ONDRAGEND(EVT);
};
