	// KL, global projection object (MERCATOR)
	myProjection = myToolTip = myLastQuery = myRoute = null;
	myAllNotams = myNotamLayer = myMapObjects = myLastClickedNotam = null;
	myCenterMapOnRequest = false;

	function initNotam ()
	{
		// KL, create MERCAOTR projection object
		myProjection = new Proj("EPSG:54004");
		setFields();
	}

	function validateQuery( e )
	{
		e = (e)?e:((event)?event:null);
		
		var qryString = dojo.byId("routetext").value;
		if ( !qryString || qryString.lenght == 0) {
			// KL, clear route...
			if (myRoute) {
				myRoute.Clear();
			}
		}
		if ( e.keyCode == 13 ) {
			// KL, we hit the enter key
			reqestNotamFromForm(false);
		}
	}

	//KL, set state of fields depending on the current state
	function setFields ( )
	{
		var useDate = dojo.byId("useDate");
		var searchDateDOJO = dojo.widget.byId("searchDate");
		if ( useDate.checked ) {
			searchDateDOJO.enable();
		} else {
			searchDateDOJO.disable();
		}

		// check for last used callsign 
		var allcookies = document.cookie;
		var pos = allcookies.indexOf("ckCallsign=");
		if ( pos != -1 ) {
			var start = pos + "ckCallsign=".length;
			var end = allcookies.indexOf(";", start);
			if ( end == -1 ) {
				end = allcookies.length;
			}
			var callsign = allcookies.substring(start, end);
			callsign = decodeURIComponent( callsign );

			dojo.byId("idCallsign").value = callsign;
		}
		
	}

	function switchTab(tab)
	{
		var visTab = getObject(tab);
		visTab.display = 'block';
		
		if ( tab == 'tabNotam' ) {
			var hideTab = getObject('tabHelp');
			hideTab.display = 'none';
		} else {
			var hideTab = getObject('tabNotam');
			hideTab.display = 'none';
		}
		drawPage();
	}
	
	// create querystring with user data
	function buildQueryFromUserInput ()
	{
		var qryString = dojo.byId("routetext").value;
		var searchRadius = dojo.byId("D1").value;
	
		// Datum=5.3.2007
		var date2Use = "";
		var useDate = dojo.byId("useDate");
		if ( useDate.checked ) {
			var searchDate = dojo.widget.byId("searchDate");
			date2Use = "Datum=" + searchDate.getValue() + ";";
		}
		return query = date2Use + "Radius=" + searchRadius + ";"+ qryString;
	}
  
	// some helper functions for string validation
	var numb = '0123456789';
	var lwr = 'abcdefghijklmnopqrstuvwxyz';
	var upr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

	function isValid(parm,val) 
	{
		if (parm == "") return false;
		for (i=0; i<parm.length; i++) {
			if (val.indexOf(parm.charAt(i),0) == -1) return false;
		}
		return true;
	}

	function isNum(parm) {return isValid(parm,numb);}
	function isLower(parm) {return isValid(parm,lwr);}
	function isUpper(parm) {return isValid(parm,upr);}
	function isAlpha(parm) {return isValid(parm,lwr+upr);}
	function isAlphanum(parm) {return isValid(parm,lwr+upr+numb);}

	// return true, if char is valid whithin callsign
	function validCSChar ( c ) 
	{
		return isAlphanum(c);
	}
  
	function checkParams ()
	{
		var qryString = dojo.byId("routetext").value;
		if ( qryString.length == 0) {
			alert ('Ihre Eingabe ist leer. Geben Sie ihre Route ein und versuchen es erneut.');
			return false;
		}
		
		var callsign = dojo.byId("idCallsign").value;
		if ( callsign.length == 0) {
			alert ('Geben Sie bitte ein Rufzeichen (Lfz-Kennung oder Flugnummer) aus max. sieben alphanumerischen Zeichen ein und versuchen Sie es erneut.');
			dojo.byId("idCallsign").focus();
			return false;
		}
		
		// strip illegal character
		var i;
		var checkName = "";
		for ( i=0; i<callsign.length; i++) {
			if ( validCSChar(callsign.charAt(i)) ) {
				checkName += callsign.charAt(i);
			}
		}
		checkName = checkName.toUpperCase();
		if ( checkName != callsign && checkName.length > 0 ) {
			callsign = checkName;
			dojo.byId("idCallsign").value = callsign;
		}
		
		// check length
		if ( callsign.length < 4 || callsign.length > 7 ) {
			alert ('Ihr Rufzeichen (Lfz-Kennung oder Flugnummer) muss mindestens 4 und darf höchstens 7 Zeichen lang sein. Korrigieren Sie Ihre Eingabe und versuchen es erneut.');
			dojo.byId("idCallsign").focus();
			return false;
		}

		return true;
	}
  
	function printNotam()
	{ 
		if ( !checkParams () ) {
			return;
		}
		// startet PDF-Generierung, GET-String muss korrekt gebaut werden ....
		var callsign = dojo.byId("idCallsign").value;
		var myPDFurl = '../pdf/getnotamPDF.php?query=' + escape(buildQueryFromUserInput())  + "&call_sign=" + callsign + "&src=W";
		window.open(myPDFurl,'_blank');
	}
  
	function reqestNotamFromForm (centerMap)
	{
		if ( !checkParams () ) {
			return;
		}
		myCenterMapOnRequest = centerMap;
		
		var callsign = dojo.byId("idCallsign").value;
		
		requestNotam ( buildQueryFromUserInput(), callsign, false ); 
		
		// save callsign for 30 days
		document.cookie = "ckCallsign="+encodeURIComponent(callsign)+";"+
						  "max-age="+(60*60*24*30)+";"+
						  "domain="+document.domain+";"+
						  "path="+"/;"
		
	}
	
	function rand ( n )
	{
		return ( Math.floor ( Math.random ( ) * n + 1 ) );
	}

	// KL, basic notam query, called with prepared query
	function requestNotam( query, txtCallsign, setinputField ) 
	{
		dojo.byId("requestStatus").innerHTML = "Übertrage NOTAMS...";
		if (setinputField ) {
			dojo.byId("routetext").value = query;
			// dojo.byId("callsign").value = callsign;
		}
		var txtUrl = "scripts/getnotamjson.php?"+ "call_sign=" + encodeURIComponent(txtCallsign) + 
									"&" + "query=" + encodeURIComponent(query) + 
									"&" + "rand=" + encodeURIComponent(rand(1000));

		dojo.io.bind({
			url: txtUrl,
			load: function(type, data, evt){ NotamsReceived(data); },
			error: function(type, error){ ShowError(error); },
			mimetype: "text/json"
		});
	}

	function requestAllNotams(  ) 
	{
		dojo.io.bind({
			url: "scripts/getnotamjson.php?query=NOF:*",
			load: function(type, data, evt){ allNotamsReceived(data); },
			error: function(type, error){ ShowError(error); },
			mimetype: "text/json"
		});
	}

	function sortNotamsByScope(a,b)
	{
		if ( a.scope > b.scope ) {
			return -1;
		} else if ( a.scope < b.scope ) {
			return 1;
		} else {
			return 0;
		}
	}

	function sortNotamsByLfdr(a,b)
	{
		if ( parseInt(a.lfdnr) < parseInt(b.lfdnr) ) {
			return -1;
		} else if ( parseInt(a.lfdnr) > parseInt(b.lfdnr) ) {
			return 1;
		} else {
			return 0;
		}
	}
	
	// returns all notams in DB
	function allNotamsReceived ( Query ) 
	{
		myAllNotams = Query;
		myAllNotams.notams = Query.notams.sort(sortNotamsByLfdr);
		
		// create/recreate own map canvas
		if ( myNotamLayer ) {
			myKaMap.removeDrawingCanvas(myNotamLayer);
		}
		myNotamLayer = myKaMap.createDrawingCanvas(50);
		if (!myMapObjects) {
			myMapObjects = new Object();
		}

		// KL, for each location create one item on the map
		var curLfdnr = 0;
		var numItems = Query.notams.lenght;
		var numItemOnMap = 0;
		if ( Query && Query.notams ) {
			dojo.lang.forEach(myAllNotams.notams, 
				function(Notam) {
					var lfdrnr = parseInt(Notam.lfdnr);
					if ( curLfdnr != lfdrnr ) {
						addNotam2Map(myNotamLayer, Notam, lfdrnr);
						curLfdnr = lfdrnr;
						numItemOnMap++;
					}
				}
			);
		}
		// KL, debug only ( setting a breakpoint is not possible without a statement )
		var test = numItemOnMap;
		
	}
  
	function NotamsReceived(thisQuery) 
	{
		if (!myAllNotams) {
			dojo.byId("requestStatus").innerHTML = "System nicht bereit, wiederholen Sie die Anfrage";
			return
		}

		var Query = thisQuery;
		
		// alert(Query);
		// alert(Query.notams.length);
		// KL, save last query for callbacks
		myLastQuery = Query;

		// switch to notam tab
		switchTab('tabNotam');

		var oldInfoHeight = parseInt(getObjectHeight(myKaMap.getRawObject('queryData')));
		
		dojo.byId("requestStatus").innerHTML = "Adding NOTAMS ...";
		
		// KL, clear notam list (left pane)
		clearnotams();
		
		// KL, clear old selection in map display (do not clear the route)
		clearMapItemDisplay();
		
		if ( Query && Query.notams ) {

			// set result info fields
			dojo.byId("queryData").style.visibility = 'visible';
			dojo.byId("queryInput").innerHTML = Query.info.querystr;
			if ( Query.info.routestr ) {
				dojo.byId("queryRoute").innerHTML = Query.info.routestr;
			} else {
				dojo.byId("queryRoute").innerHTML = "-";
			}
			dojo.byId("querySearchRadius").innerHTML = Query.info.radius;
			dojo.byId("queryDBDate").innerHTML = Query.info.publicationtimestamp;
			dojo.byId("queryDate").innerHTML = Query.info.created;
			if ( Query.info.validdate ) {
				dojo.byId("validDate").innerHTML = Query.info.validdate;
			} else {
				dojo.byId("validDate").innerHTML = "keine Einschränkung";
			}
		
			// sort items by scope
			var sortedItems = Query.notams.sort(sortNotamsByScope);
			var curGroup = "XX";
		
			dojo.lang.forEach(sortedItems, 
				function(Notam) {
					
					// KL, plain view only
					var scope = Notam.scope;
					if ( curGroup != scope ) {
						// add header to group
						if ( scope == 'W' ) {
							addGroupHeader ('Warnungen');
						} else if ( scope == 'A' ) {
							addGroupHeader ('Flugplätze');
						} else if ( scope == 'AE' || scope == 'AW') {
							addGroupHeader ('Flugplätze/Enroute');
						} else if ( scope == 'E' ) {
							addGroupHeader ('Enroute');
						} else {
							addGroupHeader ('Gruppe: ' + scope);
						}
						curGroup = scope;
					}
					
					addNotam(Notam, 'notamsPlain');
					// set icon on map
					setMapItemIcon(Notam.lfdnr, 'images/icon_notam_marked.png');
				}
			);
		}
		
		// KL, plain view
		if ( sortedItems.length == 0) {
			addEmptyItem('notamsPlain');
		}
		
		// Hajo: Route chainen
		if (!myRoute) myRoute = new VFRRoute(myKaMap);
		myRoute.load(Query.route, myCenterMapOnRequest);
		
		// KL, we must resize our windows, because the prameter window may have changed its size
		var newInfoHeight = getObjectHeight(myKaMap.getRawObject('queryData'));
		if ( newInfoHeight != oldInfoHeight) {
			drawPage();
		}
		
		dojo.byId("requestStatus").innerHTML = "";
		dojo.byId("requestError").innerHTML = "";
	}
	
	function ShowError(error) {
		dojo.byId("requestError").innerHTML = "Error:" + error.message + "<br>";
		dojo.byId("requestStatus").innerHTML = "";
		drawPage();
}

	function addEmptyItem( paneName )
	{
		var newNotam = createElement('div', 'notamItem');

		var newNotamTitle = createElement('div', 'notamBodyAltert');
		newNotamTitle.innerHTML = "<p>Für Ihre Eingabe wurden keine NOTAM gefunden.</p><p>Trennen Sie Wegpunkte durch einen '-' oder sorgen Sie dafür, das Start- und Zielpunkt der Route erkannt werden.</p>";
		newNotam.appendChild(newNotamTitle);

		document.getElementById(paneName).appendChild(newNotam);
	}

	function addNotam(Notam, paneName) 
	{
		var newNotam = createElement('div', 'notamItem', 'onClick="javascript:centerNotamOnMap(this);"');
		newNotam.setAttribute('onClick', 'javascript:centerNotamOnMap(this);');

		newNotam.id = Notam.key;
		newNotam.latitude = Notam.lat;
		newNotam.longitude = Notam.lon;
		newNotam.lfdnr = Notam.lfdnr;
		
		var newNotamTitle = createElement('div', 'notamtitle');
		newNotamTitle.innerHTML = Notam.number + "&nbsp;" + Notam.locator + "&nbsp;" + Notam.qcodedecoded;
		newNotam.appendChild(newNotamTitle);
		
		var newNotamBody = createElement('div', 'notambody');

//		var nText = "von " + Notam.from + " bis " + Notam.to + "<br/>" + Notam.body;
		var nText = Notam.fromto + "<br/>" + Notam.body;
		if ( Notam.locationname ) {
			nText = Notam.locationname + '<br/>' + nText;
		}
		newNotamBody.innerHTML = nText;
		newNotam.appendChild(newNotamBody);
		document.getElementById(paneName).appendChild(newNotam);
	}

	// KL: add a header item to the ungrouped notam list
	function addGroupHeader ( header ) 
	{
		var newNotam = createElement('div', 'notamGroupHeader');
		newNotam.innerHTML = header;
		document.getElementById('notamsPlain').appendChild(newNotam);
	}
	
	// KL, used due to differneces between the browser engines
	function createElement(type, className, addAttribute ) 
	{
	   var element = null;

	   try {
	      // First try the IE way; if this fails then use the standard way
		  if ( addAttribute ) {
			element = document.createElement('<'+type+' class="' + className + '" ' + addAttribute + '>');
		  } else {
			element = document.createElement('<'+type+' class="' + className + '">');
		  }
	   } catch (e) {
	      // Probably failed because we’re not running on IE
	   }
	   if (!element) {
			element = document.createElement(type);
			element.setAttribute('class', className);
	   }
	   return element;
	}
		
	function onMouseOverInfoItem (e) {
		if (myKaMap.isIE4) {
			document.onkeydown = kaTool_redirect_onkeypress;
		}
		document.onkeypress = kaTool_redirect_onkeypress;
	    return false;
	};

	function addNotam2Map(kamapLayer, Notam, lfdrnr)
	{
		if (!myKaMap) {
			alert("FEHLER: Kartenwidget nich definiert...");
			return;
		}

		if (!myProjection) {
			alert("FEHLER: Projektionswidget nich definiert...");
			return;
		}

		if (!kamapLayer) {
			alert("FEHLER: Drawing Canvas nich definiert...");
			return;
		}
	
		var mapItem = createElement('div', 'notamSymbolOverview');
		mapItem.setAttribute('id', Notam.lfdnr + '_notamSymbol');
		mapItem.onmouseover = onMouseOverInfoItem;
		
		mapItem.onclick=showToolTip;
//		mapItem.onmouseover=showToolTip;
//		mapItem.onmouseout=hideToolTip;

		var img = document.createElement('img');
		img.src = 'images/icon_notam.png';

		img.style.position='absolute';
		img.style.left='-7px';
		img.style.top='-7px';

		//append image the our div
		mapItem.appendChild(img);
		mapItem.icon = img;

		//add the object to our map
		var xy = latlon2mercator(Notam.lat, Notam.lon); 
		mapItem.xPos = xy[0];
		mapItem.yPos = xy[1];
		myKaMap.addObjectGeo(kamapLayer, xy[0], xy[1], mapItem);
		
		// KL, store handle to the map div in a map
		myMapObjects[lfdrnr] = mapItem;
		
	}
	
	//KL, set all map items to default image
	function clearMapItemDisplay()
	{
		myLastClickedNotam = null;
		
		for ( i=0; i<myAllNotams.notams.length; i++ ) {
			var notam = myAllNotams.notams[i];
			setMapItemIcon(notam.lfdnr, 'images/icon_notam.png');
		}
	}

	//KL, "marker" imgage for given item
	function setMapItemIcon ( lfdnr, srcImage, putOnTop ) 
	{
		lfdnr = parseInt ( lfdnr );
		var mapItem = myMapObjects[lfdnr];
		if ( mapItem ) {
			// KL, icon attribute set in addNotam2Map!
			var icon = mapItem.icon;
			if ( icon ) {
				if ( srcImage != icon.src) {
					icon.src = srcImage;
					if ( putOnTop ) {
						mapItem.style.zIndex='51';
					} else {
						mapItem.style.zIndex='50';
					}
				}
			}
		}
	}

	function centerNotamOnMap(notamdiv) 
	{
		if (!myKaMap) {
			alert("FEHLER: Kartenwidget nich definiert...");
			return;
		}

		if (!myProjection) {
			alert("FEHLER: Projektionswidget nich definiert...");
			return;
		}

		if ( myLastClickedNotam ) {
			setMapItemIcon(myLastClickedNotam, 'images/icon_notam_marked.png');
		}
		
		var lfdnr = notamdiv.lfdnr;
		setMapItemIcon(lfdnr, 'images/icon_notam_clicked_m.png', true);
		
		myLastClickedNotam = lfdnr;
		
		/**
		 * kaMap.zoomTo( lon, lat [, scale] )
		 *
		 * zoom to some geographic point (in current projection) and optionally scale
		 *
		 * lon - the x coordinate to zoom to
		 * lat - the y coordinate to zoom to
		 * scale - optional. The scale to use
		 */
		var lat = notamdiv.latitude;
		var lng = notamdiv.longitude;

		var xy = latlon2mercator(lat, lng); 
		myKaMap.zoomTo( xy[0], xy[1] );
	}
	
	function showToolTip(e)
	{
		e = (e)?e:((event)?event:null);
		if (e.ctrlKey || e.shiftKey ) {
			return;
		}
		
		// delete old tooltip, because thj height will never shrink again after one manual resize
		if ( myToolTip ) {
			myToolTip.hide();
			var c = dojo.byId('vfr_toolTip')
//			myToolTip.viewport.removeChild(c);
			myToolTip = null;
		}
		myToolTip = new kaToolTip( myKaMap );

		var numItems = 0;
		var headerToShow = '';
		var textToShow = '';
		
		var lfdnr = parseInt(this.id);
		var i;
		for ( i=0; i<myAllNotams.notams.length; i++ ) {
			var notam = myAllNotams.notams[i];
			if ( lfdnr == parseInt(notam.lfdnr) ) {
			
				if ( numItems  == 0) {
					// the first item, create header
					headerToShow = notam.locator;
					if ( notam.locationname ) {
						headerToShow += "&nbsp;" + notam.locationname;
					}
				}
			
				// create title and body text
				var NOTAMTitle;
				var NOTAMBody;
				NOTAMTitle = notam.number + "&nbsp;" + notam.qcodedecoded;
//				NOTAMBody = notam.from + " bis " + notam.to + "<br/>" + notam.body;
				NOTAMBody = notam.fromto + "<br/>" + notam.body;
				// add item to popup
				textToShow += '<span class="vfr_toolTipContentHeader">'+NOTAMTitle+'</span><br/>';
				textToShow += '<span class=".vfr_toolTipContentBody">' + NOTAMBody + '</span><p/>';
				
				numItems++;
			}
		}
		
		myToolTip.setText( headerToShow, textToShow );
		myToolTip.move(e.clientX, e.clientY);
	}

	function hideToolTip ()
	{
		if ( myToolTip ) {
			myToolTip.hide();
			myToolTip = null;
		}
	}

	// convert lat/long 2 mercator (map)
	function latlon2mercator ( lat, lng )
	{
		// *** hack ***
		lat -= 0.14;
		// *** hack ***
		var xy = myProjection.Forward(new Array(lng, lat)); 
		return xy;
	}
	function mercator2latlon ( x, y )
	{
		var latlon = myProjection.Inverse(new Array(x, y)); 
		// *** hack ***
		latlon[1] += 0.14;
		// *** hack ***
		return latlon;
	}
	function clearnotams() 
	{
		// KL remove, ungrpouped results
		var results = dojo.byId('notamsPlain');
		while (results.firstChild)  {
			results.removeChild(results.firstChild);
		}
	}
	
	// HAJO PointInfo Interface
	function RequestPointInfo(lat, lon, scale ) 
	{
		dojo.io.bind({
			url: "scripts/getpointjson.php?lat="+lat+"&lon="+lon+"&scale="+scale,
			load: function(type, data, evt){ PointInfoReceived(data); },
			error: function(type, error){ ShowError(error); },
			mimetype: "text/json"
		//	mimetype: "text/plain"
		});
	}

	function PointInfoReceived(pointinfo) 
	{
	var myval;
	myval = 	document.getElementById("routetext").value 
	if (myval.length>0) 
	 document.getElementById("routetext").value = myval + "-" + pointinfo.point;
	 else
	 document.getElementById("routetext").value = pointinfo.point;
	 // und fetchen:
	 myCenterMapOnRequest = true;
	 reqestNotamFromForm();
	}

