//*** This code is copyright 2003-2004 by Gavin Kistner, gavin@refinery.com
//*** It is covered under the license viewable at http://phrogz.net/JS/_ReuseLicense.txt
//*** Reuse or modification is free provided you abide by the terms of that license.
//*** (Including the first two lines above in your source code satisfies the conditions.)


// *** See http://phrogz.net/JS/AddClassKillClass_js.txt
function AddClass(obj,cName){ KillClass(obj,cName); return obj.className+=(obj.className.length>0?' ':'')+cName; }
function KillClass(obj,cName){ return obj.className=obj.className.replace(new RegExp("^"+cName+"\\b\\s*|\\s*\\b"+cName+"\\b",'g'),''); }
function HasClass(obj,cName){ return (!obj || !obj.className)?false:(new RegExp("\\b"+cName+"\\b")).test(obj.className) }
function RemoveClass(obj,cName){ KillClass(obj,cName) }


// *** See http://phrogz.net/JS/AttachEvent_js.txt
function AttachEvent(obj,evt,fnc,useCapture){
	if (!useCapture) useCapture=false;
	if (obj.addEventListener){
		obj.addEventListener(evt,fnc,useCapture);
		return true;
	} else if (obj.attachEvent) return obj.attachEvent("on"+evt,fnc);
	else{
		MyAttachEvent(obj,evt,fnc);
		obj['on'+evt]=function(){ MyFireEvent(obj,evt) };
	}
}
function MyAttachEvent(obj,evt,fnc){
	if (!obj.myEvents) obj.myEvents={};
	if (!obj.myEvents[evt]) obj.myEvents[evt]=[];
	var evts = obj.myEvents[evt];
	evts[evts.length]=fnc;
}
function MyFireEvent(obj,evt){
	if (!obj || !obj.myEvents || !obj.myEvents[evt]) return;
	var evts = obj.myEvents[evt];
	for (var i=0,len=evts.length;i<len;i++) evts[i]();
}

function DetachEvent(obj,evt,fnc,useCapture){
	if (!useCapture) useCapture=false;
	if (obj.removeEventListener) return obj.removeEventListener(evt,fnc,useCapture);
	else if(obj.detachEvent) return obj.detachEvent("on"+evt,fnc);
	else{
		//ToDo: ...
	}
}

function PreventDefault(evt){
	// *** Cross browser function to prevent the default action from occuring.
	if (!evt && window.event) evt=window.event;
	if (evt!=null){
		if (typeof(evt.preventDefault)=='function') evt.preventDefault();
		else evt.returnValue=false;
	}
	return false;
}
function CancelBubble(evt){
	// *** Cross browser function to prevent the event from bubbling.
	if (!evt && window.event) evt=window.event;
	if (evt!=null){
		if (typeof evt.stopPropagation=='function') evt.stopPropagation();
		else evt.cancelBubble=true;
	}
	return false;
}


function IsHidden(el){
	// *** See http://phrogz.net/JS/IsHidden_js.txt
	while (el!=null){
		if ((el.style && (el.style.display=='none' || el.style.visibility=='hidden')) ||	(el.currentStyle && (el.currentStyle.display=='none' || el.currentStyle.visibility=='hidden')))	return true;
		el=el.parentNode;
	}
	return false;
}


//-----------------------------------------------------------------------------
//----- PAN FUNCTIONS
//-----------------------------------------------------------------------------

function StartDrag(evt){
	DebugOut("StartDrag("+evt+")",DEBUG);
	if (!evt && window.event) evt=event;
	if (!evt) return alert("ERROR: Can't find an event object for Start Drag!");
	if(evt.button==2) return;
	var obj = evt.currentTarget || evt.srcElement;
	while (obj && !HasClass(obj,'draggable') ) obj=obj.parentNode;
	if (!obj) return alert("ERROR: Can't find the object to drag.");

	var leftValue = parseInt(obj.style.left,10);
	var topValue = parseInt(obj.style.top,10);
	if ((""+leftValue) =="NaN") leftValue = 0;
	if ((""+topValue) =="NaN") topValue = 0;
	window.draggableInfo={ obj:obj, x:leftValue-evt.clientX, y:topValue-evt.clientY };
	AttachEvent(document.body,'mousemove',TrackDrag,false);
	AttachEvent(document.body,'mouseup',StopDrag,false);
	AttachEvent(document.body,'selectstart',PreventDefault,false);
	AddClass(obj,'draggingNOW');
}

function TrackDrag(evt){
	//DebugOut("TrackDrag("+evt+")",DEBUG);
	if (!evt && window.event) evt=event;
	if (!evt) return alert("ERROR: Can't find an event object for Start Drag!");
//	if (!window.draggableInfo) return alert("ERROR: Where's my draggableInfo?!");
	var obj = draggableInfo.obj;
	obj.style.left = (parseInt(evt.clientX)+parseInt(draggableInfo.x))+'px';
	obj.style.top = (parseInt(evt.clientY)+parseInt(draggableInfo.y))+'px';
}

function StopDrag(evt){
	DebugOut("StopDrag()",DEBUG);
	try{
		if (!evt && window.event) evt=event;
		if (!evt) return alert("ERROR: Can't find an event object for Start Drag!");
	//	if (!window.draggableInfo) return alert("ERROR: Where's my draggableInfo?!");
		var obj = draggableInfo.obj;
		// compute new position
		var newLeft = (parseInt(evt.clientX)+parseInt(draggableInfo.x));
		var newTop = (parseInt(evt.clientY)+parseInt(draggableInfo.y));
		//set new position to layer
		obj.style.left = newLeft+'px';
		obj.style.top = newTop+'px';
		// execute map action
		var centerDespX = map.width/2 - newLeft;
		var centerDespY = map.height/2 - newTop;
		DebugOut("StopDrag final pixels center: (" + centerDespX + "," + centerDespY + ")",DEBUG);
		map.centerToPixels(centerDespX,centerDespY);
		// cleaning
	}catch(e){
		// no mostrem res. pot apareixer quan fan pan fora del navegador, pero segueix functionant
	}
	if (window.draggableInfo) KillClass(draggableInfo.obj,'draggingNOW');
	DetachEvent(document.body,'mousemove',TrackDrag,false);
	DetachEvent(document.body,'mouseup',StopDrag,false);
	DetachEvent(document.body,'selectstart',PreventDefault,false);
	window.draggableInfo=null;

}

//-----------------------------------------------------------------------------
//----- ZOOM FUNCTIONS
//-----------------------------------------------------------------------------
var zoomDiv_borderWidth = 0;

// crossbrowser scroll offset
http://www.quirksmode.org/viewport/compatibility.html
function getScrollOffsetX() {
	var x;
	if (self.pageYOffset) // all except Explorer
	{
	x = self.pageXOffset;
	}
	else if (document.documentElement && document.documentElement.scrollTop)
	// Explorer 6 Strict
	{
	x = document.documentElement.scrollLeft;
	}
	else if (document.body) // all other Explorers
	{
	x = document.body.scrollLeft;
	}
	return x;
}
function getScrollOffsetY() {
	var y;
	if (self.pageYOffset) // all except Explorer
	{
	y = self.pageYOffset;
	}
	else if (document.documentElement && document.documentElement.scrollTop)
	// Explorer 6 Strict
	{
	y = document.documentElement.scrollTop;
	}
	else if (document.body) // all other Explorers
	{
	y = document.body.scrollTop;
	}
	return y;
}

/**
*	Inici de zoom
*/
function StartZoom(evt){
	DebugOut("StartZoom("+evt+")",DEBUG);
	if (!evt && window.event) evt=event;
	if (!evt) return alert("ERROR: Can't find an event object for Start zoom!");
	if(evt.button==2) return;
	var obj = evt.currentTarget || evt.srcElement;
	while (obj && !HasClass(obj,'draggable')) obj=obj.parentNode;
	if (!obj) return alert("ERROR: Can't find the object to zoom.");
	// get reference to bbox layer
	var zoomBoxObj = map.zoomBoxDiv;
DebugOut("SCROLL ("+getScrollOffsetX()+","+getScrollOffsetY()+")",DEBUG);
	var initX = evt.clientX + getScrollOffsetX() - map.mapPixelsX - zoomDiv_borderWidth;
	var initY = evt.clientY + getScrollOffsetY() - map.mapPixelsY - zoomDiv_borderWidth;
	var topValue = parseInt(obj.style.top,10);
	var leftValue = parseInt(obj.style.left,10);

	DebugOut(">>>> : evt.clientX:" + evt.clientX , DEBUG);
	DebugOut(">>>> : map.mapPixelsX:" + map.mapPixelsX , DEBUG);
	
	DebugOut("StartZoom: initX:" + initX + ",  initY:" + initY , DEBUG);
	DebugOut("StartZoom: leftValue:" + leftValue + ", topValue:" + topValue , DEBUG);
	if ((""+leftValue) =="NaN") leftValue = 0;
	if ((""+topValue) =="NaN") topValue = 0;
	window.zoomInfo={ obj:zoomBoxObj, x:initX+leftValue, y:initY+topValue };
	AttachEvent(document.body,'mousemove',TrackZoom,false);
	AttachEvent(document.body,'mouseup',StopZoom,false);
	AttachEvent(document.body,'selectstart',PreventDefault,false);

	// Place the layer
	zoomBoxObj.style.width = "1px";
	zoomBoxObj.style.height = "1px";
	zoomBoxObj.style.visibility = "visible";
	zoomBoxObj.style.top = initY + "px";
	zoomBoxObj.style.left = initX + "px";
}

/**
*	track de zoom
*/
function TrackZoom(evt){
	if (!evt && window.event) evt=event;
	if (!evt) return alert("ERROR: Can't find an event object for Start zoom!");
	//if (!window.zoomInfo) return alert("ERROR: Where's my zoomInfo?!");

	var obj = zoomInfo.obj;
	var initX = zoomInfo.x;
	var initY = zoomInfo.y;
	var currentX = evt.clientX + getScrollOffsetX() - map.mapPixelsX - zoomDiv_borderWidth;
	var currentY = evt.clientY + getScrollOffsetY() - map.mapPixelsY - zoomDiv_borderWidth;

//window.status = "" + currentX + "," + currentY + "    " + evt.clientX + "," + evt.clientY;
	
	// box coords and size
	var x0 = Math.min(initX,currentX);
	var y0 = Math.min(initY,currentY);
	var boxWidth = Math.abs(currentX-initX);
	var boxHeight = Math.abs(currentY-initY);


	// limit box to image borders
	/*if (currentX<0) currentX=0;
	if (currentY<0) currentY=0;
	if (currentX>map.width) currentX=map.width;
	if (currentY>map.height) currentY=map.height;
	*/

	obj.style.left = x0+'px';
	obj.style.top = y0+'px';
	obj.style.width = boxWidth+'px';
	obj.style.height = boxHeight+'px';
}


/**
*	fi de zoom
*/
function StopZoom(evt){
	DebugOut("StopZoom()",DEBUG);

	var obj = zoomInfo.obj;
	var initX = zoomInfo.x;
	var initY = zoomInfo.y;
	var currentX = evt.clientX + getScrollOffsetX() - map.mapPixelsX - zoomDiv_borderWidth;//final pixels
	var currentY = evt.clientY + getScrollOffsetY() - map.mapPixelsY - zoomDiv_borderWidth;
	// make final pixels > init pixels
	if (currentX < initX) {
		tempX = initX;
		initX = currentX;
		currentX = tempX;
	}
	if (currentY < initY) {
		tempY = initY;
		initY = currentY;
		currentY = tempY;
	}

	// per evitar possibles problemes
	if (initX<0) initX=0;
	if (initY<0) initY=0;
	if (currentX>map.width) currentX=map.width;
	if (currentY>map.height) currentY=map.height;

	// pixels are absolute: making relative to image...
	DebugOut("StopZoom pixels BOX: ("+initX+","+initY+") , ("+currentX+","+currentY+")",DEBUG);

	if (map.getCurrentTool() == "ZOOMOUT") map.zoomOutWithPixelsBox(initX,initY,currentX,currentY);
	else map.zoomInWithPixelsBox(initX,initY,currentX,currentY);

	// cleaning events
	DetachEvent(document.body,'mousemove',TrackZoom,false);
	DetachEvent(document.body,'mouseup',StopZoom,false);
	DetachEvent(document.body,'selectstart',PreventDefault,false);
	window.zoomInfo=null;
	obj.style.visibility = "hidden";
}

//-----------------------------------------------------------------------------
//----- DRAWBBOX FUNCTIONS
//-----------------------------------------------------------------------------
/**
*	Inici de dibuixar caixa
*/
function StartDrawBBox(evt){
	DebugOut("StartDrawBBox("+evt+")",DEBUG);
	if (!evt && window.event) evt=event;
	if (!evt) return alert("ERROR: Can't find an event object for Start zoom!");
	var obj = evt.currentTarget || evt.srcElement;
	while (obj && !HasClass(obj,'draggable')) obj=obj.parentNode;
	if (!obj) return alert("ERROR: Can't find the object to zoom.");
	// get reference to bbox layer
	var zoomBoxObj = map.drawBboxDiv;

	var initX = evt.clientX + getScrollOffsetX() - map.mapPixelsX - zoomDiv_borderWidth;
	var initY = evt.clientY + getScrollOffsetY() - map.mapPixelsY - zoomDiv_borderWidth;
	var topValue = parseInt(obj.style.top,10);
	var leftValue = parseInt(obj.style.left,10);
	
	DebugOut("StartDrawBBox: initX:" + initX + ",  initY:" + initY , DEBUG);
	DebugOut("StartDrawBBox: leftValue:" + leftValue + ", topValue:" + topValue , DEBUG);
	if ((""+leftValue) =="NaN") leftValue = 0;
	if ((""+topValue) =="NaN") topValue = 0;
	window.zoomInfo={ obj:zoomBoxObj, x:initX+leftValue, y:initY+topValue };
	AttachEvent(document.body,'mousemove',TrackDrawBBox,false);
	AttachEvent(document.body,'mouseup',StopDrawBBox,false);
	AttachEvent(document.body,'selectstart',PreventDefault,false);

	// Place the layer
	zoomBoxObj.style.width = "1px";
	zoomBoxObj.style.height = "1px";
	zoomBoxObj.style.visibility = "visible";
	zoomBoxObj.style.top = initY + "px";
	zoomBoxObj.style.left = initX + "px";
	
}

/**
*	track de dibuixar caixa
*/
function TrackDrawBBox(evt){
	if (!evt && window.event) evt=event;
	if (!evt) return alert("ERROR: Can't find an event object for Start zoom!");
	//if (!window.zoomInfo) return alert("ERROR: Where's my zoomInfo?!");

	var obj = zoomInfo.obj;
	var initX = zoomInfo.x;
	var initY = zoomInfo.y;
	var currentX = evt.clientX + getScrollOffsetX() - map.mapPixelsX - zoomDiv_borderWidth;
	var currentY = evt.clientY + getScrollOffsetY() - map.mapPixelsY - zoomDiv_borderWidth;

	// box coords and size
	var x0 = Math.min(initX,currentX);
	var y0 = Math.min(initY,currentY);
	var boxWidth = Math.abs(currentX-initX);
	var boxHeight = Math.abs(currentY-initY);


	// limit box to image borders
	/*if (currentX<0) currentX=0;
	if (currentY<0) currentY=0;
	if (currentX>map.width) currentX=map.width;
	if (currentY>map.height) currentY=map.height;
	*/

	obj.style.left = x0+'px';
	obj.style.top = y0+'px';
	obj.style.width = boxWidth+'px';
	obj.style.height = boxHeight+'px';
}


/**
*	fi de dibuixar caixa
*/
function StopDrawBBox(evt){
	DebugOut("StopZoom()",DEBUG);

	var obj = zoomInfo.obj;
	var initX = zoomInfo.x;
	var initY = zoomInfo.y;
	var currentX = evt.clientX + getScrollOffsetX() - map.mapPixelsX - zoomDiv_borderWidth;//final pixels
	var currentY = evt.clientY + getScrollOffsetY() - map.mapPixelsY - zoomDiv_borderWidth;
	// make final pixels > init pixels
	if (currentX < initX) {
		tempX = initX;
		initX = currentX;
		currentX = tempX;
	}
	if (currentY < initY) {
		tempY = initY;
		initY = currentY;
		currentY = tempY;
	}

	// per evitar possibles problemes
	if (initX<0) initX=0;
	if (initY<0) initY=0;
	if (currentX>map.width) currentX=map.width;
	if (currentY>map.height) currentY=map.height;

	// pixels are absolute: making relative to image...
	DebugOut("DrawBBox pixels BOX: ("+initX+","+initY+") , ("+currentX+","+currentY+")",DEBUG);

	// guardem les coordenades de la caixa que s'ha dibuixat
	map.setDrawBboxExtentWithPixels(initX,initY,currentX,currentY);
	
	// cleaning events
	DetachEvent(document.body,'mousemove',TrackDrawBBox,false);
	DetachEvent(document.body,'mouseup',StopDrawBBox,false);
	DetachEvent(document.body,'selectstart',PreventDefault,false);
	window.zoomInfo=null;
}

//-----------------------------------------------------------------------------
//----- IDENTIFY FUNCTIONS
//-----------------------------------------------------------------------------

function StartIdentify(evt){
	DebugOut("StartIdentify("+evt+")",DEBUG);
	if (!evt && window.event) evt=event;
	if (!evt) return alert("ERROR: Can't find an event object for Start Identify!");
	var obj = evt.currentTarget || evt.srcElement;
	while (obj && !HasClass(obj,'draggable')) obj=obj.parentNode;
	if (!obj) return alert("ERROR: Can't find the object to Identify.");

	var initX = evt.clientX + getScrollOffsetX() - map.mapPixelsX - zoomDiv_borderWidth;
	var initY = evt.clientY + getScrollOffsetY() - map.mapPixelsY - zoomDiv_borderWidth;
	var topValue = parseInt(obj.style.top,10);
	var leftValue = parseInt(obj.style.left,10);
	
	DebugOut("StartIdentify: initX:" + initX + ",  initY:" + initY , DEBUG);
	DebugOut("StartIdentify: leftValue:" + leftValue + ", topValue:" + topValue , DEBUG);

	map.identifyWithPixels(initX,initY);
}

//-----------------------------------------------------------------------------
//----- MOUSE CLICK
//-----------------------------------------------------------------------------

function StartMouseClick(evt){
	DebugOut("StartMouseClick("+evt+")",DEBUG);
	if (!evt && window.event) evt=event;
	if (!evt) return alert("ERROR: Can't find an event object for StartMouseClick!");
	var obj = evt.currentTarget || evt.srcElement;
	while (obj && !HasClass(obj,'draggable')) obj=obj.parentNode;
	if (!obj) return alert("ERROR: Can't find the object to StartMouseClick.");

	var initX = evt.clientX + getScrollOffsetX() - map.mapPixelsX - zoomDiv_borderWidth;
	var initY = evt.clientY + getScrollOffsetY() - map.mapPixelsY - zoomDiv_borderWidth;
	var topValue = parseInt(obj.style.top,10);
	var leftValue = parseInt(obj.style.left,10);

	map.eventToolMouseClickCall(initX,initY);
}
//-----------------------------------------------------------------------------
//----- MESURAR DISTANCIES
//-----------------------------------------------------------------------------

function StartMeasureDistance(evt){
	DebugOut("StartMeasureDistance("+evt+")",DEBUG);
	if (!evt && window.event) evt=event;
	if (!evt) return alert("ERROR: Can't find an event object for StartMeasureDistance!");
	var obj = evt.currentTarget || evt.srcElement;
	while (obj && !HasClass(obj,'draggable')) obj=obj.parentNode;
	if (!obj) return alert("ERROR: Can't find the object to StartMeasureDistance.");

	var initX = evt.clientX + getScrollOffsetX() - map.mapPixelsX - zoomDiv_borderWidth;
	var initY = evt.clientY + getScrollOffsetY() - map.mapPixelsY - zoomDiv_borderWidth;
	var topValue = parseInt(obj.style.top,10);
	var leftValue = parseInt(obj.style.left,10);

	map.eventToolMeasureCall(initX,initY);
}
	


//-----------------------------------------------------------------------------
//----- MOVE PRINT BOX
//-----------------------------------------------------------------------------

function StartPrintDrag(evt){
	DebugOut("...........StartPrintDrag()",DEBUG);
	if (!evt && window.event) evt=event;
	if (!evt) return alert("ERROR: Can't find an event object for StartPrintDrag!");
	if(evt.button==2) return;
	var obj = evt.currentTarget || evt.srcElement;
	while (obj && !HasClass(obj,'printBoxStyle')) obj=obj.parentNode;
	if (!obj) return alert("ERROR: Can't find the object to StartPrintDrag.");

	var leftValue = parseInt(obj.style.left,10);
	var topValue = parseInt(obj.style.top,10);
	if ((""+leftValue) =="NaN") leftValue = 0;
	if ((""+topValue) =="NaN") topValue = 0;
	window.draggableInfo={ obj:obj, x:leftValue-evt.clientX, y:topValue-evt.clientY, initLeft:leftValue, initTop:topValue };
	//DebugOut("...........StartPrintDrag x: "+window.draggableInfo.x+"",DEBUG);
	AttachEvent(document.body,'mousemove',TrackPrintDrag,false);
	AttachEvent(document.body,'mouseup',StopPrintDrag,false);
	AttachEvent(document.body,'selectstart',PreventDefault,false);
	//AddClass(obj,'draggingNOW');
}

function TrackPrintDrag(evt){
	//DebugOut("TrackPrintDrag("+evt+")",DEBUG);
	if (!evt && window.event) evt=event;
	if (!evt) return alert("ERROR: Can't find an event object for TrackPrintDrag!");
//	if (!window.draggableInfo) return alert("ERROR: Where's my draggableInfo?!");
	var obj = draggableInfo.obj;
	obj.style.left = (parseInt(evt.clientX)+parseInt(draggableInfo.x))+'px';
	obj.style.top = (parseInt(evt.clientY)+parseInt(draggableInfo.y))+'px';
}

function StopPrintDrag(evt){
	DebugOut("StopPrintDrag()",DEBUG);
	try{
		if (!evt && window.event) evt=event;
		if (!evt) return alert("ERROR: Can't find an event object for StopPrintDrag!");
	//	if (!window.draggableInfo) return alert("ERROR: Where's my draggableInfo?!");
		var obj = draggableInfo.obj;
		// compute new position
		var newLeft = (parseInt(evt.clientX)+parseInt(draggableInfo.x));
		var newTop = (parseInt(evt.clientY)+parseInt(draggableInfo.y));
		//set new position to layer
		obj.style.left = newLeft+'px';
		obj.style.top = newTop+'px';

		var boxW=parseFloat(obj.style.width);
		var boxH=parseFloat(obj.style.height);

		var initLeft=parseFloat(draggableInfo.initLeft);
		var initTop=parseFloat(draggableInfo.initTop);

		/*// execute map action
		var centerDespX = map.width/2 + (newLeft-initLeft);
		var centerDespY = map.height/2 + (newTop-initTop);
		DebugOut("StopPrintDrag final pixels center: (" + centerDespX + "," + centerDespY + ")",DEBUG);
		map.centerToPixels(centerDespX,centerDespY);*/

		// execute map action
		var centerDespX = map.width/2 + newLeft;
		var centerDespY = map.height/2 + newTop;
		DebugOut("StopPrintDrag final pixels center: (" + centerDespX + "," + centerDespY + ")",DEBUG);
		map.centerToPixels(centerDespX,centerDespY);
		
	}catch(e){
		// no mostrem res. pot apareixer quan fan pan fora del navegador, pero segueix functionant
	}
	//if (window.draggableInfo) KillClass(draggableInfo.obj,'draggingNOW');
	DetachEvent(document.body,'mousemove',TrackPrintDrag,false);
	DetachEvent(document.body,'mouseup',StopPrintDrag,false);
	DetachEvent(document.body,'selectstart',PreventDefault,false);
	window.draggableInfo=null;

}
