
Namespace.Register("Cnc.Mapping.Initialise");
Namespace.Register("Cnc.Mapping.UnLoad");
Namespace.Register("Cnc.Mapping.SetClickProcessor");
Namespace.Register("Cnc.Mapping.Move");
Namespace.Register("Cnc.Mapping.AttachHandler");
Namespace.Register("Cnc.Mapping.MarkerSelect");
Namespace.Register("Cnc.Mapping.Utility");


		var iconBlue = new GIcon();
		//iconBlue.image = "http://maps.google.com/mapfiles/ms/icons/ltblu-pushpin.png";
		iconBlue.image = "http://resources.creativenature.com.au/PilbaraHealth/images/blueman.png";
		iconBlue.iconSize = new GSize(14, 38);
		iconBlue.shadowSize = new GSize(0,0);
		iconBlue.iconAnchor = new GPoint(7, 38);
		var iconGreen = new GIcon();
		iconGreen.image = "http://resources.creativenature.com.au/PilbaraHealth/images/greenman.png";
		iconGreen.iconSize = new GSize(14, 38);
		iconGreen.shadowSize = new GSize(0,0);
		iconGreen.iconAnchor = new GPoint(7, 38);
		var optsBlue = new Object();
		optsBlue.clickable = false;
		optsBlue.icon = iconBlue;
		optsBlue.title = "You";
		var optsGreen = new Object();
		optsGreen.clickable = false;
		optsGreen.icon = iconGreen;
		optsGreen.title = "Leader";
		
		var routeArray = new Array();
		routeArray[0] = new GLatLng(-22.92298, 119.19755); // Yandicoogina
		routeArray[1] = new GLatLng(-23.05572, 118.84873); // West Angelas
		routeArray[2] = new GLatLng(-23.25999, 117.69353); // Channar
		routeArray[3] = new GLatLng(-23.26191, 117.68123); // Eastern Range
		routeArray[4] = new GLatLng(-23.23559, 117.60589); // Paraburdoo
		routeArray[5] = new GLatLng(-21.69826, 116.14265); // Mesa J
		routeArray[6] = new GLatLng(-20.64218, 116.72617); // Dampier
		routeArray[7] = new GLatLng(-20.59853, 117.17195); // Cape Lambert
		routeArray[8] = new GLatLng(-22.43491, 117.36145); // Brockman
		routeArray[9] = new GLatLng(-22.74452, 117.75044); // Tom Price
		routeArray[10] = new GLatLng(-22.64285, 118.13281); // Marandoo
		
		var map = null;
		var smallMap = null;
		var smallMapMarker;
		var currentMarkerSet;
		var geoCoder = null;
		var updaterHttp = null;
		var j = 0;
		var zoom = 7;
		var clickProcessor = null;
		var currentSelectedFolio = "";
		var currentSelectedOffer = "";
		var handlers = null;
		var currentMapMarkers = null;
		var currentInfoTabs = null;
	    var newMarker;

		// Initialisation function definition
		Cnc.Mapping.Initialise = function onLoad(leaderSteps, userSteps) 
			{
        		//document.getElementById("loading").style.display = "none";

				if (document.getElementById("map"))
				{
				    map = new GMap2(document.getElementById("map"), {draggableCursor: 'crosshair', draggingCursor: 'pointer'});
				    
				    map.setCenter(new GLatLng(-22, 117.7), zoom);
				    
					//map.addControl(new GSmallMapControl());
					map.disableDragging();
					map.disableContinuousZoom();
					map.disableDoubleClickZoom();
					map.disableScrollWheelZoom();	
					//map.addControl(new GMapTypeControl());
					var polyline = new GPolyline(routeArray, "#ff0000", 10, 0.3);
					//alert(polyline.getLength());
					map.addOverlay(polyline);
					var distArray = new Array();
					var userArray = new Array();
					distArray[0] = routeArray[0];
					userArray[0] = routeArray[0];
					
					if (typeof leaderSteps != 'undefined')
					{
						var leaderMetres = leaderSteps * 0.7;
						var pl;
						for(i=1;i<routeArray.length;i++)
						{
							pl = new GPolyline(distArray);
							if (pl.getLength() < leaderMetres)
							{
								distArray[distArray.length] = routeArray[i];
							}
							else
							{
								break;
							}
						}
						var j = i - 1;
						if (pl.getLength() > leaderMetres)
						{
							// remove the last element and trim the Polyline
							distArray.splice(distArray.length - 1,1);
							var pl = new GPolyline(distArray);	

							// get the start and end of the next segment
							var start = distArray[distArray.length - 1];
							var end = routeArray[j];
							
							// calculate the distance required
							var requiredDistance = leaderMetres - pl.getLength();
							
							var lineArray = new Array();
							lineArray[0] = start;
							lineArray[1] = end;
							var seg = new GPolyline(lineArray);
							if (seg.getLength() > requiredDistance)
							{
								// determine the midpoint
								var midY = start.lat() + ((end.lat() - start.lat()) / 2);
								var midX = start.lng() + ((end.lng() - start.lng()) / 2);
								var midPoint = new GLatLng(midY, midX);
								
								// determine the distance from the start of the segment to the midpoint
								lineArray[0] = start;
								lineArray[1] = midPoint;
								seg = new GPolyline(lineArray);
								var endPoint;
								if (seg.getLength() > requiredDistance)
								{
									endPoint = Cnc.Mapping.CalculateSegment(requiredDistance, start, midPoint, distArray)
								}
								if (seg.getLength() < requiredDistance)
								{
									distArray[distArray.length] = midPoint;
									endPoint = Cnc.Mapping.CalculateSegment(requiredDistance, midPoint, end, distArray);
								}
							}
						}
							
						var leaderLine = new GPolyline(distArray, "#00ff00", 5, 1);
						var leaderMarker = new GMarker(distArray[distArray.length - 1], optsGreen);
						map.addOverlay(leaderLine);
						map.addOverlay(leaderMarker);
						
						if (typeof userSteps != 'undefined')
						{
							var userMetres = userSteps * 0.7;
							var upl;
							for(i=1;i<routeArray.length;i++)
							{
								upl = new GPolyline(userArray);
								if (upl.getLength() < userMetres)
								{
									userArray[userArray.length] = routeArray[i];
								}
								else
								{
									break;
								}
							}
							var j = i - 1;
							if (upl.getLength() > userMetres)
							{
								// remove the last element and trim the Polyline
								userArray.splice(userArray.length - 1,1);
								var upl = new GPolyline(userArray);	

								// get the start and end of the next segment
								var start = userArray[userArray.length - 1];
								var end = routeArray[j];
								
								// calculate the distance required
								var requiredDistance = userMetres - upl.getLength();
								
								var lineArray = new Array();
								lineArray[0] = start;
								lineArray[1] = end;
								var seg = new GPolyline(lineArray);
								if (seg.getLength() > requiredDistance)
								{
									// determine the midpoint
									var midY = start.lat() + ((end.lat() - start.lat()) / 2);
									var midX = start.lng() + ((end.lng() - start.lng()) / 2);
									var midPoint = new GLatLng(midY, midX);
									
									// determine the distance from the start of the segment to the midpoint
									lineArray[0] = start;
									lineArray[1] = midPoint;
									seg = new GPolyline(lineArray);
									var endPoint;
									if (seg.getLength() > requiredDistance)
									{
										endPoint = Cnc.Mapping.CalculateSegment(requiredDistance, start, midPoint, userArray)
									}
									if (seg.getLength() < requiredDistance)
									{
										userArray[distArray.length] = midPoint;
										endPoint = Cnc.Mapping.CalculateSegment(requiredDistance, midPoint, end, userArray);
									}
								}
							}
							var userLine = new GPolyline(userArray, "#0000ff", 5, 1);
							var userMarker = new GMarker(userArray[userArray.length - 1], optsBlue);
							map.addOverlay(userLine);
							map.addOverlay(userMarker);
						}
					}
				}
				if (document.getElementById("small_map"))
				{
					smallMap = new GMap2(document.getElementById("small_map"));
					//smallMap.setCenter(new GLatLng(-26.957076, 132.865202), 3);
					smallMap.setCenter(new GLatLng(-31.957076, 115.865202), 8);
					
					// create the cross hair icon
				      // Lets not bother with a shadow
				    var Icon = new GIcon();
				    Icon.image = "images/map_box.png";
				    Icon.iconSize = new GSize(60, 44);
				    Icon.shadowSize = new GSize(0,0);
				    Icon.iconAnchor = new GPoint(30, 22);
				    Icon.infoWindowAnchor = new GPoint(11, 11);
				    Icon.infoShadowAnchor = new GPoint(11, 11);

				    smallMapMarker = new GMarker(new GLatLng(-31.957076, 115.865202), Icon);            
				    smallMap.addOverlay(smallMapMarker);

					smallMap.disableDragging();
					smallMap.disableContinuousZoom();
					smallMap.disableDoubleClickZoom();
					smallMap.disableScrollWheelZoom();				    
				}
				
				GEvent.addListener(map, "moveend", Cnc.Mapping.Move);

		        geoCoder = new GClientGeocoder();
		        updaterHttp = GXmlHttp.create();
			}
			
		Cnc.Mapping.CalculateSegment = function(len, start, end, arr)
			{
				var endPoint = end;
				var lineArray = new Array();
				lineArray[0] = start;
				lineArray[1] = end;
				var line = new GPolyline(lineArray);
				if (line.getLength() > len)
				{
					// determine the midpoint
					var midY = start.lat() + ((end.lat() - start.lat()) / 2);
					var midX = start.lng() + ((end.lng() - start.lng()) / 2);
					var midPoint = new GLatLng(midY, midX);
					
					// determine the distance from the start of the segment to the midpoint
					lineArray[0] = start;
					lineArray[1] = midPoint;
					var seg = new GPolyline(lineArray);
					if (seg.getLength() > len)
					{
						// too much, so recusively call until we have the correct length
						Cnc.Mapping.CalculateSegment(len, start, midPoint, arr);
					}
					else
					{
						if (Math.round(seg.getLength()) == Math.round(len))
						{
							return;
						}
						else (seg.getLength() < len)
						{
							// add the end point to the array and call again
							arr[arr.length] = midPoint;
							Cnc.Mapping.CalculateSegment(len - seg.getLength(), midPoint, end, arr);
							
						}
					}
				}
			}
			
		// UnLoad static Method
		Cnc.Mapping.UnLoad = function unLoad()
			{
				GUnload();
			}
		
		Cnc.Mapping.SetClickProcessor = function(obj)
		{
		    clickProcessor = obj;
		}
			
		Cnc.Mapping.Move = function moveMiniMap()
		{
			smallMapMarker.setPoint(map.getCenter());
			smallMapMarker.redraw(true);
			//Cnc.Mapping.GetMarkers();
		}
		
		Cnc.Mapping.GetIcon = function getIcon(f, o)
		{
		    var newIcon = new GIcon();
		    var img = 'images/ENT'
		    if (f != "")
		    {
		        img = img + "_" + f;
		    }
		    if (o != "")
		    {
		        img = img + "_" + o;
		    }
		    img = img + '.png';
		    //alert(img);
            newIcon.image = img;
            newIcon.shadow = 'images/ENT_shadow.png';
            newIcon.shadowSize = new GSize(61, 75);
            newIcon.iconSize = new GSize(61, 75);
            newIcon.iconAnchor = new GPoint(15, 15);
            newIcon.infoWindowAnchor = new GPoint(28, 27);
            return newIcon;
		}
		
		Cnc.Mapping.GetMarkers = function getMapMarkers(offer)
		{
		    if (typeof offer != 'undefined')
		    {
		        currentSelectedOffer = offer;
		    }
		    map.clearOverlays();
            var req = GXmlHttp.create();
            req.open("GET", "Query.aspx?filter=" + currentSelectedOffer + "|" + currentSelectedFolio + "&bounds=" + map.getBounds(), true);
            req.onreadystatechange = function() {
                if (req.readyState == 4)
                {
                    var doc = req.responseXml;
                    //alert(doc.xml);
                    Cnc.Mapping.ProcessXml(doc);
                    req = null;
                    //document.getElementById("loading").style.display = "none";
                }
            };
            //document.getElementById("loading").style.display = "block";
            req.send();
		}
		
		Cnc.Mapping.MarkerSelect = function(markerId)
		{
		    if (currentMapMarkers != null)
		    {
		        var mkr = currentMapMarkers[markerId];
		        if (typeof mkr != 'undefined')
		        {
		            //map.panTo(mkr.getPoint());
		            mkr.openInfoWindowTabsHtml(currentInfoTabs[markerId]);
		        }
		    }
		}
		
		Cnc.Mapping.AttachHandler = function(handler)
		{
		    if (handlers == null)
		    {
		        handlers = new Array();
		    }
		    handlers[handlers.length] = handler;
		}
		
		Cnc.Mapping.ProcessXml = function(doc) {
            var util = new Cnc.Mapping.Utility();
            var items = doc.selectNodes("//Item");
            if (items.length == 0)
            {
                alert("No matches for your current criteria");
            }
            if (handlers != null)
            {
                var j;
                for(j=0;j<handlers.length;j++)
                {
                    handlers[j](doc);
                }
            }
            currentMapMarkers = null;
            currentMapMarkers = new Array();
            currentInfoTabs = null;
            currentInfoTabs = new Array();
            for(i=0;i<items.length;i++)
            {
                var pt = new GLatLng(items[i].attributes.getNamedItem("Latitude").value, items[i].attributes.getNamedItem("Longitude").value);
                var accountNo = items[i].selectSingleNode("AccountNumber").text;
                var merchantName = items[i].selectSingleNode("MerchantName").text;
                var folio = items[i].selectSingleNode("BookDetails/Folio").text;
                var page = items[i].selectSingleNode("BookDetails/Page").text;
                var o = items[i].selectSingleNode("BookDetails/Offer").text;
                var value = items[i].selectSingleNode("BookDetails/Value").text;
                var description = items[i].selectSingleNode("Description").text;
                var address = items[i].selectSingleNode("Address").text;
                var suburb = items[i].selectSingleNode("Suburb").text;
                var postcode = items[i].selectSingleNode("Postcode").text;
                var phone = items[i].selectSingleNode("PhoneNumber").text;
                var url = items[i].selectSingleNode("Url").text;
                
                if (o.indexOf("50%") != -1)
                {
                    offer = "50";
                }
                else if (o.indexOf("25%") != -1)
                {
                    offer = "25";
                }
                else
                {
                    offer = "";
                }
                
                var tab1 = HTML1.replace("[[MerchantName]]", merchantName).replace("[[Folio]]",folio).replace("[[Page]]",page).replace("[[Offer]]",o).replace("[[Value]]",value);
                tab1 = tab1.replace("[[Address]]",address).replace("[[Suburb]]",suburb).replace("[[PostCode]]",postcode).replace("[[Phone]]",phone);
                tab1 = tab1.replace("[[Url]]","<a target='_blank', href='http://" + url + "'>" + url + "</a>");
                
                var tab2 = HTML2.replace("[[Description]]",description);
                
                //alert(pt);
                if (typeof currentMapMarkers[accountNo] == 'undefined')
                {
                    var icon = Cnc.Mapping.GetIcon(folio, offer);
                    var marker = util.CreateTabbedMarker(pt, merchantName, tab1, tab2, icon, accountNo);
                    currentMapMarkers[accountNo] = marker;
                    map.addOverlay(marker);
                }
                
            }
		}
			
		//
		// Mapping Utility Class
		// 
		Cnc.Mapping.Utility =  function() { return {
		
            // generic marker function with TABBED bubble
            CreateTabbedMarker : function createMarkerWithTabs(point, title, tab_one_html, tab_two_html, icon, id) {
			        var opts = new Object();
				        opts.clickable = true;
				        opts.icon = icon;
				        opts.title = title;
			        var marker = new GMarker(point, opts);
			        var savedTabs = [
				        new GInfoWindowTab("Details", tab_one_html),
				        new GInfoWindowTab("About", tab_two_html)
			        ];
			        GEvent.addListener(marker, "click", function() {
			            var infoTabs = [
				            new GInfoWindowTab("Details", tab_one_html),
				            new GInfoWindowTab("About", tab_two_html)
			            ];
				        marker.openInfoWindowTabsHtml(infoTabs);
			        });
			        if (typeof currentInfoTabs[id] == 'undefined')
			        {
			            currentInfoTabs[id] = savedTabs;
			        }

			        return marker;
		        },

            // generic marker function with bubble
		    CreateMarker : function createMarker(point, title, html, icon) {
			    var opts = new Object();
				    opts.clickable = true;
				    opts.icon = icon;
				    opts.title = title;
			    var marker = new GMarker(point, opts);
			    GEvent.addListener(marker, "click", function() {
				    marker.openInfoWindowHtml(html);
			    });
			    return marker;
		    },

			// CheckBounds Method
      		// If the map position is out of range, move it back
		    CheckBounds : function checkBounds(allowedBounds, targetMap) {
			    // Perform the check and return if OK
			    if (allowedBounds.contains(targetMap.getCenter())) {
			      return;
			    }
			    // It`s not OK, so find the nearest allowed point and move there
			    var C = targetMap.getCenter();
			    var X = C.lng();
			    var Y = C.lat();
			    
			    var AmaxX = allowedBounds.getNorthEast().lng();
			    var AmaxY = allowedBounds.getNorthEast().lat();
			    var AminX = allowedBounds.getSouthWest().lng();
			    var AminY = allowedBounds.getSouthWest().lat();
			
			    if (X < AminX) {X = AminX;}
			    if (X > AmaxX) {X = AmaxX;}
			    if (Y < AminY) {Y = AminY;}
			    if (Y > AmaxY) {Y = AmaxY;}
//			    alert ("Restricting "+Y+" "+X);
			    targetMap.setCenter(new GLatLng(Y,X));
		    },
		    			
			// LoadKml Method
			LoadKml : function loadKml(obj, loadingDiv)
			{
				var kmlFile = null;
				map.clearOverlays();
				var currentText = obj.innerText;
				switch(obj.id)
				{
					case "tab_gold":
						kmlFile = 'catA.kml';
						break;
						
					case "tab_green":
						kmlFile = 'catB.kml';
						break;
						
					case "tab_purple":
						kmlFile = 'catC.kml';
						break;
						
					case 'tab_blue':
						kmlFile = 'catD.kml';
						break;
						
					case 'tab_gray':
						kmlFile = 'catE.kml';
						break;
						
					case 'tab_orange':
						kmlFile = 'catF.kml';
						break;
						
					default:
						kmlFile = null;
						break;
				}
				if (kmlFile)
				{
					loadingDiv.style.display = "";
				    var geoXml = new GGeoXml("http://gms.creativenature.com.au/kml/" + kmlFile, function() {
				    	if (geoXml.loadedCorrectly())
				    	{
				    		//geoXml.gotoDefaultViewport(map);
				    	}
				    	else
				    	{
				    		alert("KML not loaded");
				    	}
				    });
		
				    //map.setCenter(new google.maps.LatLng(-31.97244, 116.05614), 16);
				    
				    map.addOverlay(geoXml);
	
				    loadingDiv.style.display = "none";
			    }
			},
			
			// GeoCode Method
			GeoCode : function geoCode(id)
			{
				var list = document.all[id].childNodes;
				var i;
				for (i=j;i < j+5;i++)
				{
					var arr = list[i].childNodes[1].childNodes[1].id.split('|');
					var itemId = list[i].id;
					
					//alert("updateLatLong(" + arr[0] + ", " + list[i].childNodes[1].innerText + ", " + arr[1] + ", " + arr[2] + ", " + arr[3] + ", " + list[i].childNodes[2]);
					//var command = "updateLatLong('" + arr[0] + "', '" + list[i].childNodes[1].innerText + "', '" + arr[1] + "', '" + arr[2] + "', '" + arr[3] + "', " + i + ", '" + id + "')";
					//alert(command);
					//setTimeout(command, 10000);				
					updateLatLong(arr[0], list[i].childNodes[1].innerText, arr[1], arr[2], arr[3], i, id);
				}
				j += 5;
			}
			
	    };}
