var aCAM = new Array();

////////////////////////////////////////////////////////////////////////////////////////////////////////
// MAIN FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////////////////////

function camInit(aSettings)
{
	if(!aSettings)
	{
		alert("INIT: Bitte alle notwendigen Initialisierungsparameter übergeben -> 'aSettings'\n");
		return;
	}
	
	
	// USER SETTINGS
	aCAM['path'] = (aSettings['path']) ? aSettings['path'] : "";									// Path to images-directory. The images-directory should have an directory named aCAM['mapsDir']
	aCAM['mapsDir'] = (aSettings['mapsDir']) ? aSettings['mapsDir'] : "maps";						// Directory name inside the aCAM['path'] which contains the maps
	aCAM['mapsExtension'] = (aSettings['mapsExtension']) ? aSettings['mapsExtension'] : ".png";		// Extension of the map files e.g. (.png, .jpg, .gif)
	
	aCAM['mapSectionWidth'] = aSettings['mapSectionWidth'];			// Dimenstion: Visible map-section
	aCAM['mapSectionHeight'] = aSettings['mapSectionHeight'];
	
	aCAM['perimeterWidth'] = aSettings['perimeterWidth'];			// Dimension: Perimeter area
	aCAM['perimeterHeight'] = aSettings['perimeterHeight'];
	
	aCAM['mapOriginX'] = aSettings['mapOriginX'];					// Map-origin
	aCAM['mapOriginY'] = aSettings['mapOriginY'];
	
	aCAM['pointCorrectionX'] = 0; //7;								// Correction to the realy point of the point-image
	aCAM['pointCorrectionY'] = 0; //22;
	
	aCAM['zoomLevel'] = aSettings['zoomLevel'];						// All available zoom levels as percent-values
	aCAM['zoom'] = aSettings['zoom'];								// Current zoom level
	
	aCAM['scrollLength'] = (aSettings['scrollLength']) ? aSettings['scrollLength'] : 10;					// Step width on scrolling
	aCAM['scrollInterval'] = (aSettings['scrollInterval']) ? aSettings['scrollInterval'] : 30;				// Delay in ms between scroll steps
	
	if(aSettings['callbackFuncGetClickPos'])
		aCAM['callbackFuncGetClickPos'] = function(json) {aSettings['callbackFuncGetClickPos'](json);};		// Callback-function will be called if onclick-event on the map has been released (json-parameter with coordinates will be passed)
	
	if(!camCheckSettings(aCAM))
		return;
	
		
	// SYSTEM SETTINGS
	aCAM['ready'] = false;
	aCAM['IE'] = document.all ? true : false;
	aCAM['lastPointPos'] = new Array();
	aCAM['timestamp'] = (new Date()).getTime();
	
	// avoid background image flicker in IE
	try	{document.execCommand("BackgroundImageCache", false, true);}
	catch(err) {}
	
	
	// Get all needed objects
	aCAM['oCamContainer'] = camGetObj('camContainer');
	aCAM['oCamPerimeter'] = camGetObj('camPerimeter');
	aCAM['oCamZoom0'] = camGetObj('camZoom0');
	aCAM['oCamZoomIn'] = camGetObj('camZoomIn');
	aCAM['oCamZoomOut'] = camGetObj('camZoomOut');
	aCAM['oCamZoom100'] = camGetObj('camZoom100');
	aCAM['oCamZoomData'] = camGetObj('camZoomData');
	aCAM['oCamPoint'] = camGetObj('camPoint');
	aCAM['oCamLoader'] = camGetObj('camLoader');
	
	aCAM['oCamScrollAreaNW'] = camGetObj('camScrollAreaNW');
	aCAM['oCamScrollAreaN'] = camGetObj('camScrollAreaN');
	aCAM['oCamScrollAreaNE'] = camGetObj('camScrollAreaNE');
	aCAM['oCamScrollAreaW'] = camGetObj('camScrollAreaW');
	aCAM['oCamScrollAreaE'] = camGetObj('camScrollAreaE');
	aCAM['oCamScrollAreaSW'] = camGetObj('camScrollAreaSW');
	aCAM['oCamScrollAreaS'] = camGetObj('camScrollAreaS');
	aCAM['oCamScrollAreaSE'] = camGetObj('camScrollAreaSE');
	
	// Set dimensions, positions and other init values
	aCAM['oCamContainer'].style.width = aCAM['mapSectionWidth']+"px";
	aCAM['oCamContainer'].style.height = aCAM['mapSectionHeight']+"px";
	aCAM['oCamContainer'].style.display = "block";
	
	aCAM['oCamPerimeter'].style.left = "0px";
	aCAM['oCamPerimeter'].style.top = "0px";
	camSetModeShowPerimeter(aSettings['modeShowPerimeter']);
	camSetModeShowPoint(aSettings['modeShowPoint']);
	
	aCAM['oCamPoint'].style.left = "0px";
	aCAM['oCamPoint'].style.top = "0px";
	
	aCAM['oCamLoader'].style.left = parseInt(aCAM['mapSectionWidth']/2 -(aCAM['oCamLoader'].width/2)) + "px";
	aCAM['oCamLoader'].style.top = parseInt(aCAM['mapSectionHeight']/2 -(aCAM['oCamLoader'].height/2)) + "px";
	
	// Add Event Listeners
	camSetModeMapClickable(aSettings['modeMapClickable']);

	camAddEvent("camScrollContainer", "mouseup", camScrollStop);
	camAddEvent("camScrollContainer", "mousemove", camScrollStop);
	
	camAddEvent("camScrollAreaNW", "mousedown", function(){camScroll('NW')});
	camAddEvent("camScrollAreaN", "mousedown", function(){camScroll('N')});
	camAddEvent("camScrollAreaNE", "mousedown", function(){camScroll('NE')});
	camAddEvent("camScrollAreaW", "mousedown", function(){camScroll('W')});
	camAddEvent("camScrollAreaE", "mousedown", function(){camScroll('E')});
	camAddEvent("camScrollAreaSW", "mousedown", function(){camScroll('SW')});
	camAddEvent("camScrollAreaS", "mousedown", function(){camScroll('S')});
	camAddEvent("camScrollAreaSE", "mousedown", function(){camScroll('SE')});
	
	camAddEvent("camScrollAreaNW", "click", function(event){event.cancelBubble = true;});
	camAddEvent("camScrollAreaN", "click", function(event){event.cancelBubble = true;});
	camAddEvent("camScrollAreaNE", "click", function(event){event.cancelBubble = true;});
	camAddEvent("camScrollAreaW", "click", function(event){event.cancelBubble = true;});
	camAddEvent("camScrollAreaE", "click", function(event){event.cancelBubble = true;});
	camAddEvent("camScrollAreaSW", "click", function(event){event.cancelBubble = true;});
	camAddEvent("camScrollAreaS", "click", function(event){event.cancelBubble = true;});
	camAddEvent("camScrollAreaSE", "click", function(event){event.cancelBubble = true;});
	
	camAddEvent("camZoom0", "click", camZoom0);
	camAddEvent("camZoomIn", "click", camZoomIn);
	camAddEvent("camZoomOut", "click", camZoomOut);
	camAddEvent("camZoom100", "click", camZoom100);
	
	// Load map data
	camZoom();
}

function camCheckSettings(aSettings)
{
	var aMessage = new Array();
	
	if(!aSettings)
		aMessage.push("INIT: Bitte alle notwendigen Initialisierungsparameter übergeben -> 'aSettings'\n");
	else
	{
		if(isNaN(aSettings['mapSectionWidth']) || aSettings['mapSectionWidth'] <= 0)
			aMessage.push("INIT: Keine gültige Breitenangabe des sichtbaren Kartenausschnitts -> 'mapSectionWidth'\n");
		
		if(isNaN(aSettings['mapSectionHeight']) || aSettings['mapSectionHeight'] <= 0)
			aMessage.push("INIT: Keine gültige Höhenangabe des sichtbaren Kartenausschnitts -> 'mapSectionHeight'\n");
		
		
		if(isNaN(aSettings['perimeterWidth']) || aSettings['perimeterWidth'] <= 0)
			aMessage.push("INIT: Keine gültige Breitenangabe des Suchradiuses -> 'perimeterWidth'\n");
		
		if(isNaN(aSettings['perimeterHeight']) || aSettings['perimeterHeight'] <= 0)
			aMessage.push("INIT: Keine gültige Höhenangabe des Suchradiuses -> 'perimeterHeight'\n");
		
		
		if(isNaN(aSettings['mapOriginX']) || aSettings['mapOriginX'] <= 0)
			aMessage.push("INIT: Keine gültige x-Koordinate des Ursprungs -> 'mapOriginX'\n");
		
		if(isNaN(aSettings['mapOriginY']) || aSettings['mapOriginY'] <= 0)
			aMessage.push("INIT: Keine gültige y-Koordinate des Ursprungs -> 'mapOriginY'\n");
		
		
		if(String(aSettings['zoomLevel'].push) == "undefined")
			aMessage.push("INIT: Kein gültiges Array mit Zoomlevels -> 'zoomLevel'\n");
		
		var zoomFound = false;
		for(var key in aSettings['zoomLevel'])
		{
			if(aSettings['zoomLevel'][key] == aSettings['zoom'])
				{zoomFound = true; break;}
		}
		if(isNaN(aSettings['zoom']) || !zoomFound)
			aMessage.push("INIT: Keine gültige Zoomangabe -> 'zoom'\n");
		
		
		if(isNaN(aSettings['scrollLength']) || aSettings['scrollLength'] <= 0)
			aMessage.push("INIT: Keine gültige Angabe der Scroll-Schrittweite -> 'scrollLength'\n");
		
		if(isNaN(aSettings['scrollInterval']) || aSettings['scrollInterval'] <= 0)
			aMessage.push("INIT: Keine gültige des Scroll-Intervalls -> 'scrollInterval'\n");
	}
	
	
	var messageText = "";
	for(var i=0; i<aMessage.length; i++)
		messageText += aMessage[i];
	
	if(messageText != "")
		alert(messageText);
	
	return !(messageText != "");
}

function camInitScript()
{
	if(!aCAM['oMapImage'].complete)
	{
		aCAM['timeoutCounterInitScript'] = isNaN(aCAM['timeoutCounterInitScript']) ? 0: aCAM['timeoutCounterInitScript']+1;
		
		if(aCAM['timeoutCounterInitScript'] < 50)
			window.setTimeout('camInitScript()', 100);
	}
	else
	{
		aCAM['timeoutCounterInitScript'] = 0;
		
		aCAM['oCamContainer'].style.backgroundImage = "url("+aCAM['oMapImage'].src+")";
		aCAM['oCamPerimeter'].style.display = (aCAM['modeShowPerimeter']) ? 'inline' : 'none';
		aCAM['oCamPoint'].style.display = (aCAM['modeShowPoint']) ? 'inline' : 'none';
		//aCAM['oCamPoint'].style.display = 'inline';
		aCAM['oCamLoader'].style.display = 'none';
		
		aCAM['oCamPerimeter'].style.width = aCAM['perimeterZoomWidth']+"px";
		aCAM['oCamPerimeter'].style.height = aCAM['perimeterZoomHeight']+"px";
		
		aCAM['ready'] = true;
		
		aCAM['lastPointPos']['x'] = isNaN(aCAM['lastPointPos']['x']) ? 0 : aCAM['lastPointPos']['x'];
		aCAM['lastPointPos']['y'] = isNaN(aCAM['lastPointPos']['y']) ? 0 : aCAM['lastPointPos']['y'];
		camSetMapPosIntoView(aCAM['lastPointPos']['x'], aCAM['lastPointPos']['y']);
	}
}

function camLoadMap()
{
	aCAM['oCamContainer'].style.backgroundImage = "url("+aCAM['path']+"blank.gif)";
	aCAM['oCamPerimeter'].style.display = 'none';
	aCAM['oCamPoint'].style.display = 'none';
	aCAM['oCamLoader'].style.display = 'inline';
	
	aCAM['oMapImage'] = new Image();
	aCAM['oMapImage'].src = aCAM['path']+aCAM['mapsDir']+"/map_"+aCAM['zoom']+aCAM['mapsExtension']+"?ts="+aCAM['timestamp'];
	
	aCAM['ready'] = false;
	camInitScript();
}

function camGetMapSize()
{
	if(!aCAM['ready'])	return;
	
	var aResult = new Array();
	
	aResult['width'] = aCAM['oMapImage'].width;
	aResult['height'] = aCAM['oMapImage'].height;
	
	return aResult;
}

function camGetBGPos()
{
	if(!aCAM['ready'])	return;
	
	var aResult = new Array();
	
	var aPos = aCAM['oCamContainer'].style.backgroundPosition;
	aPos = aPos.split(' ');
	
	aResult['x'] = parseInt(aPos[0]);
	aResult['y'] = parseInt(aPos[1]);
	
	aResult['x'] = isNaN(aResult['x']) ? 0 : aResult['x'];
	aResult['y'] = isNaN(aResult['y']) ? 0 : aResult['y'];
	
	return aResult;
}

function camSetBGPos(x, y, dir)
{
	if(!aCAM['ready'])	return;
	
	var aMapSize = camGetMapSize();
	
	if(x < -(aMapSize['width']-aCAM['mapSectionWidth']))
		x = -(aMapSize['width']-aCAM['mapSectionWidth']);
	else if(x > 0)
		x = 0;
	
	if(y < -(aMapSize['height']-aCAM['mapSectionHeight']))
		y = -(aMapSize['height']-aCAM['mapSectionHeight']);
	else if(y > 0)
		y = 0;
	
	
	var aPos = camGetBGPos();
	var diffX = (aPos['x'] -x);
	var diffY = (aPos['y'] -y);
	
	aCAM['oCamContainer'].style.backgroundPosition = x+"px "+y+"px";
	
	aCAM['oCamPoint'].style.left = (parseInt(aCAM['oCamPoint'].style.left) -diffX) +"px";
	aCAM['oCamPoint'].style.top = (parseInt(aCAM['oCamPoint'].style.top) -diffY) +"px";
	
	aCAM['oCamPerimeter'].style.left = (parseInt(aCAM['oCamPerimeter'].style.left) -diffX) +"px";
	aCAM['oCamPerimeter'].style.top = (parseInt(aCAM['oCamPerimeter'].style.top) -diffY) +"px";
	
	
	
	// Hide or show scroll icons
	/*if(dir)
	{
		aCAM['oCamScrollAreaNW'].style.visibility =	(dir == "NW"				&& diffX == 0 && diffY == 0	) ? "hidden" : "visible";
		aCAM['oCamScrollAreaW'].style.visibility =	(dir.match(/NW|W|SW/)		&& diffX == 0				) ? "hidden" : "visible";
		aCAM['oCamScrollAreaSW'].style.visibility =	(dir == "SW"				&& diffX == 0 && diffY == 0	) ? "hidden" : "visible";
		
		aCAM['oCamScrollAreaNE'].style.visibility =	(dir == "NE"				&& diffX == 0 && diffY == 0	) ? "hidden" : "visible";
		aCAM['oCamScrollAreaE'].style.visibility =	(dir.match(/NE|E|SE/)		&& diffX == 0				) ? "hidden" : "visible";
		aCAM['oCamScrollAreaSE'].style.visibility =	(dir == "SE"				&& diffX == 0 && diffY == 0	) ? "hidden" : "visible";
		
		aCAM['oCamScrollAreaNW'].style.visibility =	(dir == "NW"				&& diffX == 0 && diffY == 0	) ? "hidden" : "visible";
		aCAM['oCamScrollAreaN'].style.visibility =	(dir.match(/NW|N|NE/)		&& diffY == 0				) ? "hidden" : "visible";
		aCAM['oCamScrollAreaNE'].style.visibility =	(dir == "NE"				&& diffX == 0 && diffY == 0	) ? "hidden" : "visible";
		
		aCAM['oCamScrollAreaSW'].style.visibility =	(dir == "SW"				&& diffX == 0 && diffY == 0	) ? "hidden" : "visible";
		aCAM['oCamScrollAreaS'].style.visibility =	(dir.match(/SW|S|SE/)		&& diffY == 0				) ? "hidden" : "visible";
		aCAM['oCamScrollAreaSE'].style.visibility =	(dir == "SE"				&& diffX == 0 && diffY == 0	) ? "hidden" : "visible";
	}*/
}

function camSetMapPosIntoView(x, y)
{
	if(!aCAM['ready'])
	{
		aCAM['timeoutCounterSetMapPosIntoView'] = isNaN(aCAM['timeoutCounterSetMapPosIntoView']) ? 0: aCAM['timeoutCounterSetMapPosIntoView']+1;
		
		if(aCAM['timeoutCounterSetMapPosIntoView'] < 50)
			window.setTimeout('camSetMapPosIntoView('+x+', '+y+')', 100);
	}
	else
	{
		aCAM['timeoutCounterSetMapPosIntoView'] = 0;
		
		// memorize last point position
		aCAM['lastPointPos']['x'] = x;
		aCAM['lastPointPos']['y'] = y;
		
		// zoom correction
		x = parseInt(x * aCAM['zoomFactor']);
		y = parseInt(y * aCAM['zoomFactor']);
		
		// origin correction
		var correctionX = (parseInt(aCAM['mapSectionWidth']/2) -x) -aCAM['mapOriginZoomX'];
		var correctionY = (parseInt(aCAM['mapSectionHeight']/2) +y) -aCAM['mapOriginZoomY'];
		
		camSetBGPos(correctionX, correctionY);
		camSetPointTo(x, y);
	}
}


////////////////////////////////////////////////////////////////////////////////////////////////////////
// CLICK FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////////////////////

function camSetPointTo(x, y)
{
	if(!aCAM['ready'])	return;
	
	var aPos = camGetBGPos();
	
	var pointX = aPos['x'] +aCAM['mapOriginZoomX'] +x;
	var pointY = aPos['y'] +aCAM['mapOriginZoomY'] -y;
	
	aCAM['oCamPoint'].style.left = (pointX -aCAM['pointCorrectionX']) +"px";
	aCAM['oCamPoint'].style.top = (pointY -aCAM['pointCorrectionY']) +"px";
	
	aCAM['oCamPerimeter'].style.left = parseInt(pointX -aCAM['perimeterZoomWidth']/2) +"px";
	aCAM['oCamPerimeter'].style.top = parseInt(pointY -aCAM['perimeterZoomHeight']/2) +"px";
}

function camGetClickPos(e)
{
	if(!aCAM['ready'])	return;
	
	var aResult = new Array();
	
	var aPos = camGetBGPos();
	var aMousePos = camGetMousePos(e);
	
	aResult['x'] = -(aPos['x'] +aCAM['mapOriginZoomX'] -aMousePos['x']);
	aResult['y'] = aPos['y'] +aCAM['mapOriginZoomY'] -aMousePos['y'];
	
	// zoom correction
	aResult['x'] = parseInt(aResult['x'] / aCAM['zoomFactor']);
	aResult['y'] = parseInt(aResult['y'] / aCAM['zoomFactor']);
	
	camSetMapPosIntoView(aResult['x'], aResult['y']);
	
	if(aCAM['callbackFuncGetClickPos'])
	{
		var halfW = parseInt(aCAM['perimeterWidth']/2);
		var halfH = parseInt(aCAM['perimeterHeight']/2);
		
		var json = {
						'pointCenter': {'x': aResult['x'],	'y': aResult['y']},
						'pointNW': {'x': aResult['x']-halfW,	'y': aResult['y']+halfH},
						'pointSE': {'x': aResult['x']+halfW,	'y': aResult['y']-halfH}
					};
		aCAM['callbackFuncGetClickPos'](json);
	}
	
	return aResult;
}


////////////////////////////////////////////////////////////////////////////////////////////////////////
// ZOOM FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////////////////////

function camZoom(zoom)
{
	if(zoom)
		aCAM['zoom'] = parseInt(zoom);
	else if(!aCAM['zoom'])
		aCAM['zoom'] = 100;
	
	aCAM['zoomFactor'] = aCAM['zoom']/100;
	aCAM['oCamZoomData'].innerHTML = aCAM['zoom'] + " %";
	
	aCAM['mapOriginZoomX'] = parseInt(aCAM['mapOriginX'] * aCAM['zoomFactor']);
	aCAM['mapOriginZoomY'] = parseInt(aCAM['mapOriginY'] * aCAM['zoomFactor']);
	
	aCAM['perimeterZoomWidth'] = parseInt(aCAM['perimeterWidth'] * aCAM['zoomFactor']);
	aCAM['perimeterZoomHeight'] = parseInt(aCAM['perimeterHeight'] * aCAM['zoomFactor']);
	
	
	// enable / disable zoom buttons
	camRemoveClass(aCAM['oCamZoom0'], "camZoomItemDisabled");
	camRemoveClass(aCAM['oCamZoomIn'], "camZoomItemDisabled");
	camRemoveClass(aCAM['oCamZoomOut'], "camZoomItemDisabled");
	camRemoveClass(aCAM['oCamZoom100'], "camZoomItemDisabled");
	
	if(aCAM['zoomLevel'][aCAM['zoomLevel'].length -1] == aCAM['zoom'])
	{
		camAddClass(aCAM['oCamZoom0'], "camZoomItemDisabled");
		camAddClass(aCAM['oCamZoomOut'], "camZoomItemDisabled");
	}
	
	if(aCAM['zoomLevel'][0] == aCAM['zoom'])
	{
		camAddClass(aCAM['oCamZoomIn'], "camZoomItemDisabled");
		camAddClass(aCAM['oCamZoom100'], "camZoomItemDisabled");
	}
	
	camLoadMap();
}

function camZoom0()
{
	if(aCAM['zoom'] != aCAM['zoomLevel'][aCAM['zoomLevel'].length-1])
		camZoom(aCAM['zoomLevel'][aCAM['zoomLevel'].length-1]);
}

function camZoomIn()
{
	for(var i=0; i<aCAM['zoomLevel'].length; i++)
	{
		if(aCAM['zoomLevel'][i] == aCAM['zoom'] && aCAM['zoomLevel'][i-1])
			return camZoom(aCAM['zoomLevel'][i-1]);
	}
}

function camZoomOut()
{
	for(var i=0; i<aCAM['zoomLevel'].length; i++)
	{
		if(aCAM['zoomLevel'][i] == aCAM['zoom'] && aCAM['zoomLevel'][i+1])
			return camZoom(aCAM['zoomLevel'][i+1]);
	}
}

function camZoom100()
{
	if(aCAM['zoom'] != 100)
		camZoom(100);
}


////////////////////////////////////////////////////////////////////////////////////////////////////////
// SCROLL FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////////////////////

function camScroll(dir)
{
	if(!aCAM['ready'])	return;
	
	var aPos = camGetBGPos();
	dir = dir.toUpperCase();
	
	switch(dir)
	{
		case 'NW':
			aPos['x'] += aCAM['scrollLength'];
			aPos['y'] += aCAM['scrollLength'];
			break;
		case 'N':
			aPos['y'] += aCAM['scrollLength'];
			break;
		case 'NE':
			aPos['x'] -= aCAM['scrollLength'];
			aPos['y'] += aCAM['scrollLength'];
			break;
		case 'W':
			aPos['x'] += aCAM['scrollLength'];
			break;
		case 'E':
			aPos['x'] -= aCAM['scrollLength'];
			break;
		case 'SW':
			aPos['x'] += aCAM['scrollLength'];
			aPos['y'] -= aCAM['scrollLength'];
			break;
		case 'S':
			aPos['y'] -= aCAM['scrollLength'];
			break;
		case 'SE':
			aPos['x'] -= aCAM['scrollLength'];
			aPos['y'] -= aCAM['scrollLength'];
			break;
	}
	
	camSetBGPos(aPos['x'], aPos['y'], dir);
	
	aCAM['scrollTimeout'] = window.setTimeout('camScroll(\''+dir+'\')', aCAM['scrollInterval']);
}

function camScrollStop()
{
	if(!aCAM['ready'])	return;
	
	window.clearTimeout(aCAM['scrollTimeout']);
}


////////////////////////////////////////////////////////////////////////////////////////////////////////
// MOUSE FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////////////////////

function camGetMousePos(e)
{
	if(!aCAM['ready'])	return;
	
	var aResult = new Array();
	
	if (aCAM['IE'])
	{
		aResult['x'] = event.clientX + document.documentElement.scrollLeft;
		aResult['y'] = event.clientY + document.documentElement.scrollTop;
	}
	else
	{
		aResult['x'] = e.pageX;
		aResult['y'] = e.pageY;
	}
	
	var aObjPos = camGetObjPos(aCAM['oCamContainer']);
	aResult['x'] -= aObjPos['x'];
	aResult['y'] -= aObjPos['y'];
	
	aResult['x'] = (aResult['x'] < 0) ? 0 : aResult['x'];
	aResult['y'] = (aResult['y'] < 0) ? 0 : aResult['y'];
	
	return aResult;
}


////////////////////////////////////////////////////////////////////////////////////////////////////////
// MODE FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////////////////////

function camGetModeShowPerimeter()
{
	return aCAM['modeShowPerimeter'];
}

function camSetModeShowPerimeter(mode)
{
	aCAM['modeShowPerimeter'] = (typeof(mode) == "boolean") ? mode : false;
	
	aCAM['oCamPerimeter'].style.display = (aCAM['modeShowPerimeter']) ? 'inline' : 'none';
}

function camGetModeShowPoint()
{
	return aCAM['modeShowPoint'];
}

function camSetModeShowPoint(mode)
{
	aCAM['modeShowPoint'] = (typeof(mode) == "boolean") ? mode : false;
	
	aCAM['oCamPoint'].style.display = (aCAM['modeShowPoint']) ? 'inline' : 'none';
}

function camGetModeMapClickable()
{
	return aCAM['modeMapClickable'];
}

function camSetModeMapClickable(mode)
{
	aCAM['modeMapClickable'] = (typeof(mode) == "boolean") ? mode : false;
	
	if(aCAM['modeMapClickable'])
		camAddEvent("camScrollContainer", "click", camGetClickPos);
	else
		camRemoveEvent("camScrollContainer", "click", camGetClickPos);
}


////////////////////////////////////////////////////////////////////////////////////////////////////////
// HELPER FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////////////////////

function camGetObj(name)
{
	var result = (typeof(name) == "object") ? name : document.getElementById(name);
	
	return result;
}

function camGetObjPos(name)
{
	obj = camGetObj(name);
	
	var aResult = new Array();
	
	if (obj.offsetParent)
	{
		aResult['x'] = obj.offsetLeft;
		aResult['y'] = obj.offsetTop;
		
		while (obj = obj.offsetParent)
		{
			aResult['x'] += obj.offsetLeft;
			aResult['y'] += obj.offsetTop;
		}
	}
	
	return aResult;
}

function camAddEvent(obj, event, functionName)
{
	obj = camGetObj(obj);
	
	if(obj)
	{
		if(obj.attachEvent)
			obj.attachEvent("on" +event, functionName);
		else if(obj.addEventListener)
			obj.addEventListener(event, functionName, false);
	}
}

function camRemoveEvent(obj, event, functionName)
{
	obj = camGetObj(obj);
	
	if(obj)
	{
		if(obj.detachEvent)
			obj.detachEvent("on" +event, functionName);
		else if(obj.removeEventListener)
			obj.removeEventListener(event, functionName, false);
	}
}

function camAddClass(obj, className)
{
	obj = camGetObj(obj);
	
	if(obj)
		obj.className = obj.className + " " + className;
}

function camRemoveClass(obj, className)
{
	obj = camGetObj(obj);
	
	if(obj)
		obj.className = obj.className.replace(eval("/"+className+"/gi"), "");
}

