


/* Global constants */
var TYPO3_SITE_REL_PATH = '/';
var MAP = new Object();
MAP.TYPO3_EVENTSPAGEURL = 	"events4you/auflistung-events4you.html"; 	// "index.php?id=10022";
MAP.TYPO3_VORTEILPAGEURL =	"vorteil4you/auflistung-vorteil4you.html";	// "index.php?id=10021";

MAP.MARKCOORDS_DIMENSION_X = 10;	// pixels
MAP.MARKCOORDS_DIMENSION_Y = 10;	// pixels
MAP.DIMENSION_X = 1000;				// pixels
MAP.DIMENSION_Y = 900;				// pixels
MAP.RADIUS_CURSOR = 80;				// pixels
MAP.SMALLRADIUS_CURSOR = 30;		// pixels
MAP.SMALLMAPTRESHOLD = 250;			// pixels
MAP.IEOFFSETX = -3;					// pixels
MAP.IEOFFSETY = -3;					// pixels
var DEBUG = false;



/**
 * Class that implements Cookie Management
 * @author	Alex Buchgeher <a.buchgeher(at)cyberhouse(dot)at>
 * @version 0.1.0
 */
var SessionMgm = Class.create();
SessionMgm.prototype = {
	initialize: function(id) {
		if(!navigator.cookieEnabled) {
			debug("cookies disabled!", "cookiesdisabled");
		}
		if(id == undefined) { id = ''; }
		this.sessionId = id;
		var d = new Date();
		d.setYear(d.getFullYear()+1);
		this.expires = d.toGMTString();
		this.path = '/';
		this.domain = false;
		this.secure = false;
		delete d;
		d = null;	
	},
	setKey: function(key, val) {
		key = this.sessionId + key;
		key = key.toLowerCase();
		var r;
		var dc = key + '=' + escape(val);
		dc+= (this.domain) ? '; domain=' + this.domain : '';
		dc+= (this.expires) ? '; expires=' + this.expires : '';
		dc+= (this.path)	? '; path=' + this.path : '';
		dc+= (this.secure) ? '; secure=' + this.secure : '';
		dc+= (this.domain) ? '; domain=' + this.domain : '';
		document.cookie = dc;
	},
	getKey: function(key) {
		key = this.sessionId + key;
		key = key.toLowerCase();
		var dc = document.cookie;
		var prefix = key + "=";
		var begin = dc.indexOf("; " + prefix);
		if (begin == -1) {
			begin = dc.indexOf(prefix);
			if (begin != 0) { return null; }
		} 
		else begin += 2;
		var end = document.cookie.indexOf(";", begin);
		if (end == -1) { end = dc.length; }
		var f = unescape(dc.substring(begin + prefix.length, end));
		return unescape(dc.substring(begin + prefix.length, end));	
	},
	delKey: function(key) {
		if (this.getKey(key)) {
			key = this.sessionId + key;
			key = key.toLowerCase();
			document.cookie = key + "=" +
			((this.path) ? "; path=" + this.path : "") +
			((this.domain) ? "; domain=" + this.domain : "") + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
		}
	}
}





/**
 * Class implements Map functionality
 * for the EventMaps
 *
 * @author	Alex Buchgeher <a.buchgeher(at)cyberhouse(dot)at>
 * @version 0.3.0
 * Major Bugfix that occured with IE7
 */
var Map = Class.create();
Map.prototype = {
	
	/**
	 * Class constructor
	 * @param string	The imageId (map)
	 * @param string	css-class for marking coord on map
	 */
	initialize: function(mapId, markerImageClass) {
		this.map = $(mapId);
		this.ses = new SessionMgm(mapId);
		this.mapId = mapId;
		this.markerImageClass = markerImageClass;
		this.mapWidth = 0;
		this.mapHeight = 0;
		this.marker = null;
		this.cursor = null;
		this.active = false;
		this.form = null;

		DEBUG = _GET("debug") == '1';
		
		this.clickEventInProgress = false;
		if(this.map == null) {
			return;
		}
		
		Event.observe(this.map, "click", this.setCoords.bindAsEventListener(this));
		
		if(DEBUG) {
			Event.observe(this.map, "mousemove", this.debugCoords.bindAsEventListener(this));
		}

			// if parameters are set via url
		if(_GET('tx_cybhmap_pi1[x]') != '' && _GET('tx_cybhmap_pi1[y]') != '') {
			this.ses.setKey('coordX',_GET('tx_cybhmap_pi1[x]'));
			this.ses.setKey('coordY',_GET('tx_cybhmap_pi1[y]'));
		}

		debug(this.ses.getKey('coordX'), this.mapId + "coordX");
		debug(this.ses.getKey('coordY'), this.mapId + "coordY");

//		this.map.onmousemove = this.updateCursorOverlay.bindAsEventListener(this);
//		this.map.onmouseover = this.updateCursorOverlay.bindAsEventListener(this);
//		this.map.onmouseout = this.removeCursorOverlay.bind(this);
//		document.body.onmousemove = this.updateCursorOverlay.bindAsEventListener(this);
		
		Event.observe(document, "mousemove", this.updateCursorOverlay.bindAsEventListener(this));
		Event.observe(window, "unload", this.unload.bind(this));
	},


	setStatus: function(state) {
		this.active = state;
	},


	/*********************************************
	
		implementation of mousecursor functions

	*********************************************/


	/**
	 * Should be called if map is active (and visible) => because of bug in IE7
	 * @return void
	 */
	initCursor: function() {
		this.setUpCursorOverlay();
	},


	/**
	 * Builds the mousecursor
	 * @return void
	 */
	setUpCursorOverlay: function() {
		if(this.cursor == null) {
			var cursorId = parseInt(this.map.height) > MAP.SMALLMAPTRESHOLD ? '' : 'small_';
			this.cursorDimension = parseInt(this.map.height) > MAP.SMALLMAPTRESHOLD ? MAP.RADIUS_CURSOR : MAP.SMALLRADIUS_CURSOR;
			this.cursor = document.createElement("div");
			this.cursor.id = cursorId + this.mapId + "Cursor";
			//this.cursor.onmousemove = this.updateCursorOverlay.bindAsEventListener(this);
			//this.cursor.onmouseover = this.updateCursorOverlay.bindAsEventListener(this);
			document.body.appendChild(this.cursor);
			this.cursor.onclick = this.setCoords.bindAsEventListener(this);
			this.cursor.style.display = "none";
		}
	},
	
	/**
	 * Updates position of mousecursor
	 * @param event		Mouse-Event
	 * @return void
	 */
	updateCursorOverlay: function(e) {
		if(this.isInsideMap(e)) {
			var mouseX = Event.pointerX(e);
			var mouseY = Event.pointerY(e);

				// center cursor
			this.cursor.style.display = "block";
			var ds = this.cursorDimension / 2;
			
			
			var ie_dx = 0;
			var ie_dy = 0;
			if(navigator.appName == "Microsoft Internet Explorer") {
				ie_dx = MAP.IEOFFSETX;
				ie_dy = MAP.IEOFFSETY;
			}

			
			this.cursor.style.left = (mouseX - ds + ie_dx) + "px";
			this.cursor.style.top = (mouseY - ds + ie_dy) + "px";
		} else {
			this.removeCursorOverlay();
		}
	},
	
	/**
	 * Hides mousecursor 
	 * @return void
	 */
	removeCursorOverlay: function() {
		if(this.cursor != undefined) {
			this.cursor.style.display = "none";
		}
	},
	
	/**
	 * Checks if mouse-cursor position is inside the active map.
	 * @param event
	 * @return boolean
	 */
	isInsideMap: function(e) {
		if(!this.active) { return false; }
		var mouseX = Event.pointerX(e);
		var mouseY = Event.pointerY(e);

		var elemPos = Position.cumulativeOffset(this.map);
		var posX = elemPos[0];
		var posY = elemPos[1];
		
		var dx = this.map.width;
		var dy = this.map.height;
		
		return ((mouseX >= posX && mouseX <= posX + dx) && (mouseY >= posY && mouseY <= posY + dy));
	},




	/*********************************************
	
		implementation of functions for setting and marking the coordinates

	*********************************************/

	/**
	 * Places a marker at the position
	 * of the recently clicked point in the map
	 * @return void
	 */
	markCoords: function() {
		if(this.map == null) { return; }
		
		this.active = true;
		
			// init cursor overlay when markCoords is hit.
			// at that point we know that the map is set to active
		this.initCursor();
		var marker = document.createElement("div");
		marker.className = this.markerImageClass;

		if(this.marker != null) {
			try {
				Element.remove(this.marker);
			} catch(e) {}
		}
		this.marker = marker;

		var x = this.ses.getKey("coordX");
		var y = this.ses.getKey("coordY");


			// delete coords if point has to be shown only once after a click-event
//		this.ses.delKey("coordX");
//		this.ses.delKey("coordY");


		if(x == null || x == 0 || x == undefined || x == '' || x == "undefined") { return; }


		x = this.getCoordXFromBaseMapX(x);
		y = this.getCoordYFromBaseMapY(y);

		
		var dx = Math.floor(MAP.MARKCOORDS_DIMENSION_X / 2);
		var dy = Math.floor(MAP.MARKCOORDS_DIMENSION_Y / 2);
		x -= dx;
		y -= dy;


		var ie_dx = 0;
		var ie_dy = 0;
		if(navigator.appName == "Microsoft Internet Explorer") {
			ie_dx = MAP.IEOFFSETX;
			ie_dy = MAP.IEOFFSETY;
		}

		marker.style.top = (Math.floor(y) + ie_dx) + "px";
		marker.style.left = (Math.floor(x) + ie_dy) + "px";
		
		var mapWrapper = this.map.parentNode;
		mapWrapper.appendChild(marker);
	},

	/**
	 * Returns the x-coordinate on the current map
	 * Expects a coordinate from the baseMap (1000*900px)
	 * @param integer
	 * @return integer
	 */
	getCoordXFromBaseMapX: function(x) {
		var imagewidth = this.map.width;

		//debug(imagewidth, "MapWidth"+this.mapId);		
		var relX = x / MAP.DIMENSION_X;
		var lat = relX * imagewidth;

		return lat;
	},
	
	/**
	 * Returns the y-coordinate on the current map
	 * Expects a coordinate from the baseMap (1000*900px)
	 * @param integer
	 * @return integer
	 */
	getCoordYFromBaseMapY: function(y) {
		var imageheight = this.map.height;

		//debug(imageheight, "MapHeight"+this.mapId);
		var relY = y / MAP.DIMENSION_Y;
		var lon = relY * imageheight;

		return lon;
	},
	
	/**
	 * Redirects to the singleview depending
	 * on the clicked location (and chosen map)
	 * 
	 * @return void
	 */
	setCoords: function(e) {
		if(this.clickEventInProgress) {
			return;
		}
		this.clickEventInProgress = true;
		
		var imagewidth = this.map.width;
		var imageheight = this.map.height;

		var relX = imagewidth / MAP.DIMENSION_X;
		var relY = imageheight / MAP.DIMENSION_Y;
		var elemPos = Position.cumulativeOffset(this.map);

		var mouseX = Event.pointerX(e);
		var mouseY = Event.pointerY(e);

			// store values for use after redirection
		var lat = parseInt((mouseX - elemPos[0])/relY);
		var lon = parseInt((mouseY - elemPos[1])/relX);

			// store the coordinated of the reference map (1000*900pixels)
		this.ses.setKey("coordX", lat);
		this.ses.setKey("coordY", lon);

			// coordinate on current map
		var realX = parseInt((mouseX - elemPos[0]));
		var realY = parseInt((mouseY - elemPos[1]));

		if(realX == 0 && realY == 0) { return; }
		debug(realX+"/"+realY, "realX "+ this.mapId);

		this.markCoords();

		var url = new String();
		switch(this.mapId) {
			case "greenMap":
				url = TYPO3_SITE_REL_PATH + MAP.TYPO3_EVENTSPAGEURL;
				break;
			case "blueMap":
			default:
				url = TYPO3_SITE_REL_PATH + MAP.TYPO3_VORTEILPAGEURL;
				break;
		}

		debug(url, "url");
		if(!DEBUG) {
			this.sendPostValues(url, lat, lon);
		}
	},

	/**
	 * Send coordinates to given url using post
	 * method.
	 * @param string
	 * @param integer
	 * @param integer
	 * @return void
	 */
	sendPostValues: function(url, lat, lon) {
		var form = document.createElement("form");
		form.action = url;
		form.method = "post";
		form.style.display = "none";

		var inputX = document.createElement("input");
		inputX.type = "hidden";
		inputX.name = "tx_cybhmap_pi1[x]";
		inputX.value = lat;

		var inputY = document.createElement("input");
		inputY.type = "hidden";
		inputY.name = "tx_cybhmap_pi1[y]";
		inputY.value = lon;
		
		form.appendChild(inputX);
		form.appendChild(inputY);

		var p = document.getElementsByTagName("body")[0];
		p.appendChild(form);

			// hold form for cleaning IE memory
		this.form = form;
		
		form.submit();
	},

	/**
	 * Debug mode
	 * @return void
	 */
	debugCoords: function(e) {
		var imagewidth = this.map.width;
		var imageheight = this.map.height;
		
		var relX = imagewidth / 1000;
		var relY = imageheight / 900;
		var elemPos = Position.cumulativeOffset(this.map);

		
		var mouseX = Event.pointerX(e);
		var mouseY = Event.pointerY(e);

		var lat = parseInt((mouseX - elemPos[0])/relY);
		var lon = parseInt((mouseY - elemPos[1])/relX);

		var elemPos = Position.cumulativeOffset(this.map);
		var mouseX = Event.pointerX(e);
		var mouseY = Event.pointerY(e);

		debug(lat + '/' + lon, "COORDs1000x900map");
		
		var lat = (mouseX - elemPos[0]);
		var lon = (mouseY - elemPos[1]);

		debug(lat + '/' + lon, "COORDs");
	},
	

	/**
	 * Cleanup IE memory.
	 * IE's garbage collector does not work as it
	 * should since version 4. Therefore it leaks memory without
	 * some little help
	 */
	unload: function() {
		if(this.form == null) { return; }
		try {
			//Element.remove(this.marker);
			this.marker = null;
			Element.remove(this.form);
			this.form = null;
		} catch(e) {}
	}
}







/**
 * Class implements tab switching functionality
 * for the EventMaps
 *
 * @author	Alex Buchgeher
 * @version 0.0.1
 */
var Tabs = Class.create();
Tabs.prototype = {
	
	/**
	 * Class constructor
	 * inits the default tab and attaches the eventlisteners
	 * automatically takes care of IE's bad memory management
	 */
	initialize: function() {
		this.greenTab = null;
		this.blueTab = null;
		this.greenMap = null;
		this.blueMap = null;
		this.activeMap = null;
		this.greenBox = null;
		this.blueBox = null;

		this.ses = new SessionMgm("tabs");
		this.greenMap = new Map("greenMap", "greenMapMarker");
		this.blueMap = new Map("blueMap", "blueMapMarker");

		this.greenTabImg_active = "fileadmin/4youcard/templates/images/tab-green_active.jpg";
		this.greenTabImg = "fileadmin/4youcard/templates/images/tab-green.jpg";
		this.blueTabImg_active = "fileadmin/4youcard/templates/images/tab-blue_active.jpg";
		this.blueTabImg = "fileadmin/4youcard/templates/images/tab-blue.jpg";


			// anything else than startscreen loaded?
		if($("map-startscreen") == null) {
			this.greenTabImg_active = "fileadmin/4youcard/templates/images/tab-green_active_rechts.jpg";
			this.greenTabImg = "fileadmin/4youcard/templates/images/tab-green_rechts.jpg";
			this.blueTabImg_active = "fileadmin/4youcard/templates/images/tab-blue_active_rechts.jpg";
			this.blueTabImg = "fileadmin/4youcard/templates/images/tab-blue_rechts.jpg";
		}

		this.preloadImage(this.greenTabImg_active);
		this.preloadImage(this.greenTabImg);
		this.preloadImage(this.blueTabImg_active);
		this.preloadImage(this.blueTabImg);
		this.preloadImage("fileadmin/4youcard/templates/images/point_bigger_blue.gif");
		this.preloadImage("fileadmin/4youcard/templates/images/point_bigger_green.gif");


		this.greenTab = $("green-tab");
		this.blueTab = $("blue-tab");

		this.greenBox = $("green-box");
		this.blueBox = $("blue-box");

	
			// try to attach event handler on green tab
		try {
			this.greenTab.onclick = this.switchToGreenTab.bind(this);
		} catch(e) {
			if(this.greenMap.map != null) {
				this.greenMap.markCoords();
			}
			if(this.blueMap.map != null) {
				this.blueMap.markCoords();
			}
			return;
		}
			// attach event handler on blue tab
		try {
			this.blueTab.onclick = this.switchToBlueTab.bind(this);
		} catch(e) {
			this.blueMap.markCoords();
			return;
		}

		this.setCurrentMap();
				
		Event.observe(window, "unload", this.unload.bindAsEventListener(this));
	},
	
	
	
	
	/*********************************************
	
		implementation of tab switching functions

	*********************************************/
	
	/**
	 * Sets the active tab depending on the
	 * values from the cookies.
	 * @return void
	 */
	setCurrentMap: function() {
		var map = this.ses.getKey("activeMap");
		switch(map) {
			case "blueMap":
				this.switchToBlueTab();
				break;
			case "greenMap":
			default:
				this.switchToGreenTab();
		}
	},
	
	/**
	 * Sets green Tab to state "active"
	 * @return void
	 */
	switchToGreenTab: function() {
		this.blueBox.style.display = "none";
		this.greenBox.style.display = "block";

		this.greenTab.style.background = "url(" + this.greenTabImg_active + ')';
		this.blueTab.style.background = "url(" + this.blueTabImg + ')';

		this.greenTab.style.borderBottom = "1px solid #99cc00";
		this.blueTab.style.borderBottom = "1px solid #fff";

		this.activeMap = "greenMap";
		
		this.ses.setKey("activeMap", this.activeMap);
		this.greenMap.markCoords();
		
		this.greenMap.setStatus(true);
		this.blueMap.setStatus(false);
	},

	/**
	 * Sets blue Tab to state "active"
	 * @return void
	 */
	switchToBlueTab: function() {
		this.greenBox.style.display = "none";
		this.blueBox.style.display = "block";

		this.blueTab.style.borderBottom = "1px solid #00ccff";	
		this.greenTab.style.borderBottom = "1px solid #fff";

		this.greenTab.style.background = "url(" + this.greenTabImg + ')';
		this.blueTab.style.background = "url(" + this.blueTabImg_active + ')';

		this.activeMap = "blueMap";

		this.ses.setKey("activeMap", this.activeMap);
		this.blueMap.markCoords();

		this.greenMap.setStatus(false);
		this.blueMap.setStatus(true);
	},




	/*********************************************
	
		implementation of helper funcs

	*********************************************/

	/**
	 * Preloads an image
	 * @param string	the Image-url
	 * @return void
	 */
	preloadImage: function(a) {
		if(document.images) {
			var dummy = new Image();
			dummy.src = a;
		}
	},

	/**
	 * [description]
	 */
	unload: function() {

	}
}


/**
 * Returns the get-parameter depending 
 * on the given key
 * @param string
 * @return string
 */
function _GET(key) {
	var url   = window.location.search;
	url = url.replace(/^\?/, '');
	if(url != '') {
		var getParams = url.split('&');
		var getKeyVal = new Array();
		for(var i=0; i<getParams.length; i++) {
			var ar = getParams[i].split('=');
			getKeyVal[ar[0]] = unescape(ar[1]);
		}
		return getKeyVal[key] == undefined ? '' : getKeyVal[key];
	}
	return '';
}


/**
 * Debugging function
 * Leaks memory when using IE
 * @param string	The string to debug
 * @param string	an optional key (by default set to debug)
 * @return void
 * @see DEBUG : boolean, global
 */
function debug(string, key) {
	if(!DEBUG) { return; }
	if(document.debugCnt == undefined) {
		document.debugCnt = 0;
	}
	if(key == '') {
		key = "debug";
	}
	var debug = $(key);
	if(debug == null) {
		document.debugCnt++;
		var top = 20 * document.debugCnt;
		var body = document.getElementsByTagName("body")[0];
		debug = document.createElement("div");
		debug.id = key;
		debug.style.position = "absolute";
		debug.style.right = "0px";
		debug.style.top = top + "px";
		debug.style.border = "2px solid #000";
		debug.style.background = "#fff";
		body.appendChild(debug);
	}
	debug.innerHTML = "<code>" + key + "</code> " + string;
	return;
}



