var map;
var poly;
var directionPoints;
var userPoints;
var visiblePoints;
var directionPointsCount;
var userMarkersCount;
var runClickEvent;
var kmlLayers;

Array.prototype.remove = function(from, to) {
	var rest = this.slice((to || from) + 1 || this.length);
	this.length = from < 0 ? this.length + from : from;
	return this.push.apply(this, rest);
};

Array.prototype.move_element = function(index, delta) {

  // This method moves an element within the array
  // index = the array item you want to move
  // delta = the direction and number of spaces to move the item.
  //
  // For example:
  // move_element(myarray, 5, -1); // move up one space
  // move_element(myarray, 2, 1); // move down one space
  //
  // Returns true for success, false for error.

  var index2, temp_item;

  // Make sure the index is within the array bounds
  if (index < 0 || index >= this.length) {
    return false;
  }

  // Make sure the target index is within the array bounds
  index2 = index + delta;
  if (index2 < 0 || index2 >= this.length || index2 == index) {
    return false;
  }

  // Move the elements in the array
  temp_item = this[index2];
  this[index2] = this[index];
  this[index] = temp_item;

  return true;
}


Ext.onReady(function(){	
	Ext.QuickTips.init();
	Map.init()
});

  function customPanel(map,mapname,dirn,div) {
    var html = "";
  
    // ===== local functions =====

    // === waypoint banner ===
    function waypoint(point, type, address) {
      var target = '"' + mapname+".showMapBlowup(new GLatLng("+point.toUrlValue(6)+"))"  +'"';
      html += '<table style="border: 1px solid silver; margin: 10px 0px; background-color: rgb(238, 238, 238); border-collapse: collapse; color: rgb(0, 0, 0);">';
      html += '  <tr style="cursor: pointer;" onclick='+target+'>';
      html += '    <td style="padding: 4px 15px 0px 5px; vertical-align: middle; width: 20px;">';
      html += '      <img src="http://www.google.com/intl/en_ALL/mapfiles/icon-dd-' +type+ '-trans.png">'
      html += '    </td>';
      html += '    <td style="vertical-align: middle; width: 100%;">';
      html +=        address;
      html += '    </td>';
      html += '  </tr>';
      html += '</table>';
    }

    // === route distance ===
    function routeDistance(dist) {
      html += '<div style="text-align: right; padding-bottom: 0.3em;">' + dist + '</div>';
    }      

    // === step detail ===
    function detail(point, num, description, dist) {
      var target = '"' + mapname+".showMapBlowup(new GLatLng("+point.toUrlValue(6)+"))"  +'"';
      html += '<table style="margin: 0px; padding: 0px; border-collapse: collapse;">';
      html += '  <tr style="cursor: pointer;" onclick='+target+'>';
      html += '    <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px; vertical-align: top; text-align: right;">';
      html += '      <a href="javascript:void(0)"> '+num+'. </a>';
      html += '    </td>';
      html += '    <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px; vertical-align: top; width: 100%;">';
      html +=        description;
      html += '    </td>';
      html += '    <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px 0.3em 0.5em; vertical-align: top; text-align: right;">';
      html +=        dist;
      html += '    </td>';
      html += '  </tr>';
      html += '</table>';
    }

    // === Copyright tag ===
    function copyright(text) {
      html += '<div style="font-size: 0.86em;">' + text + "</div>";
    }
    
    // === read through the GRoutes and GSteps ===
    for (var i=0; i<dirn.getNumRoutes(); i++) {
      if (i==0) {
        var type="play";
      } else {
        var type="pause";
      }
      var route = dirn.getRoute(i);
      var geocode = route.getStartGeocode();
      var point = route.getStep(0).getLatLng();
      // === Waypoint at the start of each GRoute
      waypoint(point, type, geocode.address);
      routeDistance(route.getDistance().html+" (about "+route.getDuration().html+")");

      for (var j=0; j<route.getNumSteps(); j++) {
        var step = route.getStep(j);
        // === detail lines for each step ===
        detail(step.getLatLng(), j+1, step.getDescriptionHtml(), step.getDistance().html);
      }
    }
    
    // === the final destination waypoint ===   
    var geocode = route.getEndGeocode();
    var point = route.getEndLatLng();
    waypoint(point, "stop", geocode.address);
             
    // === the copyright text ===
    //copyright(dirn.getCopyrightsHtml());

    // === drop the whole thing into the target div
    div.innerHTML = html;

  }
		
var Map = function(){
	return {
		init : function(){
			
			kmlLayers = [];
			userMarkersCount = 1;
			directionPointsCount = 0;
			
			runClickEvent = true;
			
			directionPoints = { nextId: 1, points: [] };
			userPoints = { nextId: 1, points: {} };
			visiblePoints = {};
			
		    var vp = new Ext.Viewport({
				layout:"border",
				items:[
				new Ext.TabPanel({
					id: 'center-tabs',
					resizeTabs:true,
					activeTab: 0,
					deferredRender:false,
					enableTabScroll:true,
					items:[{
						title: LOCALE_header_map,
						iconCls: 'tabs',
						id: 'gmap',
						html: 'map',
						closable:false
					}],
					defaults: {autoScroll: true},
					//plugins: new Ext.ux.TabCloseMenu(),
					region:"center",
					xtype:"panel",

					listeners: {
						'beforeadd': {
							fn: function(){ PdMarkerCloseAll(); },
							delay: 5
						}
					}
				}),{
					region:"south",
					xtype:"panel",
					height:66,
					split:true,
					resizable:false,
					bodyStyle: { 'padding': '3px' },
					contentEl: 'footer'
				},{
					region:"north",
					xtype:"panel",
					height:120,
					split:true,
					resizable:false,
					bbar: [
						new Ext.Action({
							text: LOCALE_header_about,
							handler: function(){
								Ext.getCmp('center-tabs').add({
									title: LOCALE_header_about,
									iconCls: 'tabs',
									autoLoad: 'about_' + LOCALE_name + '.html',
									closable:true
								}).show();
							},
							iconCls: 'silk-information'
						}),
//						new Ext.Action({
//							text: 'Links',
//							handler: function(){
//								alert('Links...');
//							},
//							iconCls: 'silk-link'
//						}),
						new Ext.Action({
							text: LOCALE_header_help,
							handler: function(){
								Ext.getCmp('center-tabs').add({
									title: LOCALE_header_help,
									iconCls: 'tabs',
									autoLoad: 'help_' + LOCALE_name + '.html',
									closable:true
								}).show();
							},
							iconCls: 'silk-help'
						}),
						'->',
						new Ext.Action({
							text: 'English',
							handler: function(){
								window.location = './en/';
							},
							iconCls: 'flag-en'
						}),
						new Ext.Action({
							text: 'Greek',
							handler: function(){
								window.location = './gr/';
							},
							iconCls: 'flag-gr'
						}),
						new Ext.Action({
							text: 'French',
							handler: function(){
								window.location = './fr/';
							},
							iconCls: 'flag-fr'
						})
					],
					bodyStyle: { 'padding': '7px' },
					contentEl: 'header'
//					html:
//						'<h1 style="font-size: 16px;">Infraculture-med</h1>' +
//						'<h3 style="font-size: 13px;">Γεωγραφική εφαργμογή ανάδειξης πολιτιστικών μνημείων και φυσικών πόρων του νομού Ημαθίας</h3>'
				},
				{
					region:"west",
					title: LOCALE_header_poiand,
					xtype:"panel",
					width:300,
					minWidth:250,
					split:true,
					collapsible:false,
					autoScroll:true,
					bodyStyle: { 'padding': '0px', 'margin': '0px' },
					id: 'west-panel',
					html:
						'<div style="line-height: 16px; padding: 5px;">' +
						'<h2 style="padding-bottom: 5px;"> ' + LOCALE_header_iconhelp + '</h2>' +
						'<img src="images/add.png" align="left" /> ' + LOCALE_legend_add + ' <br />' +
						'<img src="images/information.png" align="left" /> ' + LOCALE_legend_info + ' <br />' +
						'<img src="images/magnifier.png" align="left" /> ' + LOCALE_legend_zoom + ' <br />' +
						'<img src="images/delete.png" align="left" /> ' + LOCALE_legend_del + ' <br />' +
						'<br /><img src="markers/user.png" align="left" /> ' + LOCALE_legend_userpoi + ' <br />' +
						'</div>' +
						'<h1 class="poi-tree-header">' + LOCALE_header_kml + '</h1>' +
						'<div id="poi-kml">&nbsp;</div>' +
						'<h1 class="poi-tree-header">' + LOCALE_header_poi + '</h1>' +
						'<div id="poi-default">&nbsp;</div>' +
						'<h1 class="poi-tree-header">' + LOCALE_header_user + '</h1>' +
						'<div id="poi-user">&nbsp;</div>'
				},{
					region:"east",
					xtype:"panel",
					title: LOCALE_header_routing,
					width:300,
					layout:"fit",
					split:true,
					collapsible:true,
					titleCollapse:true,
					items:[{
						layout:"border",
						border: false,
						items:[{
							xtype:"panel",
							border: false,
							region:"center",
							layout: 'fit',
							bodyStyle: { 'padding-left': '7px', 'padding-right': '7px' },
							autoScroll: true,
							id: 'custom_path'
						},{
							xtype:"panel",
							bodyStyle: { 'padding-left': '7px', 'padding-right': '7px' },
							border: false,
							region:"north",
							height:100,
							split:true,
							id: "path_points-outer",
							html: '<div id="path_points">&nbsp;</div>'
						}]
					}]
				}]
			});
			
			var kmlTree = new Ext.tree.TreePanel({
				el:'poi-kml',
				checkModel: 'cascade',
				useArrows: true,
				autoHeight: true,
				border: false,
				trackMouseOver: true,
				onlyLeafCheckable: true,
				animate: true,
				rootVisible: false,
				loader: new Ext.tree.TreeLoader({
					dataUrl:'./poi-kml.php',
					baseAttrs: { uiProvider: Ext.tree.TreeCheckNodeUI }
				}),
				root: new Ext.tree.AsyncTreeNode({ id:'0' })
			});

			kmlTree.on("check",function(node,checked){
				if (checked)
				{
					this.showKml(node.attributes.id, node.attributes.url);
				}
				else
				{
					this.hideKml(node.attributes.id);
				}
			}, this);
			
			kmlTree.render();
			
			var userPoiTree = new Ext.tree.TreePanel({
				el:'poi-user',
				id: 'poi-user-tree',
				checkModel: 'cascade',
				useArrows: true,
				autoHeight: true,
				border: false,
				trackMouseOver: true,
				onlyLeafCheckable: true,
				animate: true,
				rootVisible: false,
				loader: new Ext.tree.TreeLoader({
					dataUrl:'./poi-user.php',
					baseAttrs: { uiProvider: Ext.tree.TreeCheckNodeUI__poi }
				}),
				columns:[{
					header: 'header',
					width: 220,
					dataIndex: 'text'
				},{
					header: 'header',
					dataIndex: 'actions'
				}],
				root: new Ext.tree.AsyncTreeNode({ id:'0', text: 'My points' })
			});
			
			userPoiTree.on("click",function(node, e){
				//fire the click event for the marker
				map.setCenter(this.getMarker(node.attributes.id).xxc.point);
				this.getMarker(node.attributes.id).showTooltip();
				GEvent.trigger(this.getMarker(node.attributes.id), "click");
			},this);
			
			userPoiTree.render();
			
			var poiTree = new Ext.tree.TreePanel({
				el:'poi-default',
				checkModel: 'cascade',
				useArrows: true,
				autoHeight: true,
				border: false,
				trackMouseOver: true,
				onlyLeafCheckable: false,
				animate: true,
				rootVisible: false,
				loader: new Ext.tree.TreeLoader({
					dataUrl:'./poiNodes',
					baseAttrs: { uiProvider: Ext.tree.TreeCheckNodeUI__poi }
				}),
				columns:[{
					header: 'header',
					width: 220,
					dataIndex: 'text'
				},{
					header: 'header',
					dataIndex: 'actions'
				}],
				root: new Ext.tree.AsyncTreeNode({ id:'0' })
			});

			poiTree.on("check",function(node,checked){
				if (!node.attributes.noPoints)
				{
					if (checked)
					{
						this.showCategory(node.attributes.id);
					}
					else
					{
						this.hideCategory(node.attributes.id);
					}
				}
			}, this);
			
			poiTree.on("click",function(node, e){
				//fire the click event for the marker
				map.setCenter(this.getMarker(node.attributes.id).xxc.point);
				this.getMarker(node.attributes.id).showTooltip();
				GEvent.trigger(this.getMarker(node.attributes.id), "click");
			},this);
			
			poiTree.render();
			
			var gmap = Ext.getCmp('gmap');
			map = new GMap2(gmap.body.dom);
			map.addControl(new GLargeMapControl());
			map.addControl(new GMapTypeControl());
//			map.addControl(new YSliderControl());
			map.disableDoubleClickZoom();
			
			var minMapScale = 8;
			var maxMapScale = 14;
			// get array of map types
			var mapTypes = map.getMapTypes();
			// overwrite the getMinimumResolution() and getMaximumResolution() methods for each map type
			for (var i=0; i<mapTypes.length; i++) {
				mapTypes[i].getMinimumResolution = function() {return minMapScale;}
//				mapTypes[i].getMaximumResolution = function() {return maxMapScale;}
			}
			
            var boxStyleOpts = { 'background-color': 'transparent' };
            var otherOpts = {
              buttonHTML: "<img src='images/magnifier.png' />",
              buttonZoomingHTML: "<img src='images/magnifier_zoom_in.png' />",
              buttonStartingStyle: {width: '17px', height: '17px'},
              overlayRemoveTime: 0 };
            
			map.addControl(new DragZoomControl(boxStyleOpts, otherOpts, {}),
				new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(7,7)));
			
			map.addControl(new GScaleControl());

            // add large map control under the zoom control since the large map control has different sizes...
//			map.addControl(new exgmSliderControl(), new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(7,32)));
            
			map.setCenter(new GLatLng(40.478292, 22.480774), 10);
			map.enableScrollWheelZoom();
			map.enableContinuousZoom();
//			map.addControl(new GOverviewMapControl(new GSize(180,140)));
			bounds = new GLatLngBounds();
			
//			gdir = new GDirections(null, Ext.getCmp("custom_path").body.dom);
			
			gdir = new GDirections(map);
			
//			GEvent.addListener(gdir, "error", function() {
//				alert("Directions Failed: " + gdir.getStatus().code);
//			});
			
			GEvent.addDomListener(map,'mousemove', function(point){ Ext. getDom('cursor-ll').innerHTML = point.toUrlValue();}); 
			
			GEvent.addListener(gdir, "load", function() {
				setTimeout('customPanel(map,"map",gdir,Ext.getCmp("custom_path").body.dom);', 1);
			});
			
			GEvent.addListener(map, "mouseover", function() {
				map.checkResize();
			});
			
			GEvent.addListener(gdir, "load", function() {
				if (poly)
					map.removeOverlay(poly);
				poly = gdir.getPolyline();
				map.addOverlay(poly);
			});
			
//			GEvent.addListener(map, "zoomend", function(oldLevel, newLevel) {
//				PdMarkerCloseAll();
//			});
			
			GEvent.addListener(map, "move", function() {
//				Map.map.checkResize();
				var marker = map.getFirstMarker();
				while (marker != null)
				{
					if (marker.win)
					{
						if (marker.win.isVisible())
						{
							marker.relocateWindow();
						}
					}
					marker = map.getNextMarker();
				}
			});

			function handleErrors(){
				if (gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
				{}	//alert("No corresponding geographic location could be found for one of the specified addresses. This may be due to the fact that the address is relatively new, or it may be incorrect.\nError code: " + gdir.getStatus().code);
				else if (gdir.getStatus().code == G_GEO_SERVER_ERROR)
				{}	//alert("A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: " + gdir.getStatus().code);
				else if (gdir.getStatus().code == G_GEO_MISSING_QUERY)
				{}	//alert("The HTTP q parameter was either missing or had no value. For geocoder requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.\n Error code: " + gdir.getStatus().code);
				else if (gdir.getStatus().code == G_GEO_BAD_KEY)
				{
					alert("The given key is either invalid or does not match the domain for which it was given. \n Error code: " + gdir.getStatus().code);
				}
				else if (gdir.getStatus().code == G_GEO_BAD_REQUEST)
				{}	//alert("A directions request could not be successfully parsed.\n Error code: " + gdir.getStatus().code);
				else
				{
					Map.removeLastDirectionPoint();
					alert(LOCALE_map_gdir_unknown);
				}
			}
		
			GEvent.addListener(gdir, "error", handleErrors);

			GEvent.addListener(map, "click", function(marker, point) {
				
				if (!runClickEvent)
				{
					if (!marker)
					{
						PdMarkerCloseAll();
					}
					return true;
				}
			});
			
			GEvent.addListener(map, "dblclick", function(marker, point) {
				PdMarkerCloseAll();	
				if (!marker)
				{
					var id = userMarkersCount++;
//					var name = 'User point ' + String.fromCharCode( 65 + parseInt( id ) );
					var name = 'User point ' + id ;
					var html = name;
					var icon = false;
					
					var marker = Map.createMarker('0', point, id, name, html, 'user');
		
					map.addOverlay(marker);
				}
			});
		},
		
		showKml: function(id, url)
		{
			var geoXml = new GGeoXml(url);
			GEvent.addListener(geoXml, 'load', function() {
				if (geoXml.loadedCorrectly()) {
					geoXml.gotoDefaultViewport(map);
					kmlLayers[id] = geoXml;
				}
			});
			kmlLayers[id] = geoXml;
			map.addOverlay(kmlLayers[id]);
		},
		
		hideKml: function(id)
		{
			map.removeOverlay(kmlLayers[id]);
		},
		
		hideAllTooltips: function()
		{
			var marker = map.getFirstMarker();
			while (marker != null)
			{
				marker.hideTooltip();
				marker = map.getNextMarker();
			}
		},
		
		getMarker: function(xxcId)
		{
			var marker = map.getFirstMarker();
			while (marker != null)
			{
				if (marker.xxc.id == xxcId)
				{
					return marker;
				}
				marker = map.getNextMarker();
			}
		},
		
		openInfo: function(xxcId)
		{
			var m = this.getMarker(xxcId);
			Ext.getCmp('center-tabs').add({
				title: m.xxc.name,
				iconCls: 'tabs',
				autoLoad: './tabs/' + m.xxc.categoryId + '/' + m.xxc.id,
				closable:true
			}).show();
			
		},
		
		zoomToMarker: function(markerId)
		{
			PdMarkerCloseAll();
			var marker = map.getFirstMarker();
			while (marker != null)
			{
				if (marker.xxc.id==markerId)
				{
					map.setCenter(marker.xxc.point, 15);
					return true;
				}
				else
				{
					marker = map.getNextMarker();
				}
			}
		},
		
		markupDirectionPoints: function()
		{
			this.refreshDirectionPoints();
			
			var Html = "";
			var p;
			for (p=0; p<directionPointsCount; p++)
			{
				if (directionPoints.points[p] != null)
				{
					Html += ' <a href="javascript:Map.removeDirectionPoint(\'' + directionPoints.points[p].id + '\')" title="' + LOCALE_routing_del + '"><img src="images/delete.png" /></a> ';
					Html += ' <a href="javascript:Map.moveUpDirectionPoint(\'' + p + '\')" title="' + LOCALE_routing_up + '""><img src="images/arrow_up.png" /></a> ';
					Html += ' <a href="javascript:Map.moveDownDirectionPoint(\'' + p + '\')" title="' + LOCALE_routing_down + '"><img src="images/arrow_down.png" /></a> ';
					Html += ' <span style="overflow: hidden;">' + directionPoints.points[p].name + '</span >';
					Html += '<br />';
				}
			}
			document.getElementById("path_points").innerHTML = Html;
		},
		
		refreshDirectionPoints: function()
		{
			var p;
			var tempArray = [];
			
			for (p=0; p<directionPoints.points.length; p++)
			{
				if (directionPoints.points[p]!=null)
				{
					directionPoints.points[p].id = p;
				}
			}
		},
		
		moveUpDirectionPoint: function(id)
		{
			if (id>0)
			{
				var temp = directionPoints.points.splice(id, 1);
				temp = temp[0];
				directionPoints.points.splice((id-1), 0, temp);
			}
			this.markupDirectionPoints();
			this.showDirections();
			
		},
		
		moveDownDirectionPoint: function(id)
		{
			if(id!=directionPoints.points.length)
			{
				var temp = directionPoints.points.splice(id, 1);
				temp = temp[0];
				directionPoints.points.splice((id+1), 0, temp);
			}
			this.markupDirectionPoints();
			this.showDirections();
		},
		
		addDirectionPoint: function(xxcId)
		{
			// find the marker
			var m = this.getMarker(xxcId);
			
			var id = directionPointsCount++;
			
			var directionPoint = {
				  name: m.xxc.name
				, id: id
				, marker: m
				, markerId: m.xxc.id
				, point: m.xxc.point
			};
			
			directionPoints.points[id] = directionPoint;
			
			Map.showDirections();
			
			PdMarkerCloseAll();
			
			Map.markupDirectionPoints();
		},
		
		removeLastDirectionPoint: function()
		{
			directionPointsCount = directionPointsCount - 1;
			this.removeDirectionPoint(directionPointsCount);
		},
		
		removeDirectionPoint: function(directionId)
		{
			PdMarkerCloseAll();
			
			directionPoints.points.splice(directionId, 1);
			
			this.markupDirectionPoints();
			
			map.removeOverlay(poly);
			
			this.showDirections();
		},
		
		showCategory: function(categoryId)
		{
			GDownloadUrl("./poiPoints/" + categoryId, this.loadPoints);
		},
		
		hideCategory: function(categoryId)
		{
			var marker = map.getFirstMarker();
			while (marker != null)
			{
				if (marker.xxc.categoryId == categoryId)
				{
					this.removeMarker(marker.xxc.id);
					return this.hideCategory(categoryId);
				}
				marker = map.getNextMarker();
			}
			return true;
		},
		
		removeMarker: function(xxcId)
		{
			PdMarkerCloseAll();
			
			var marker = this.getMarker(xxcId);
			
			// if it's a user defined marker remove the node from the tree
			if (marker.xxc.categoryId=='0')
			{
				Ext.getCmp('poi-user-tree').getNodeById(xxcId).remove();
			}
			
			// remove all direction points based on the marker being removed
			Ext.each(directionPoints.points, function(){
				if (this.markerId==xxcId)
				{
					Map.removeDirectionPoint(this.id);
				}
			});
			
			// remove the marker from the array
			marker.remove();
		},
		
		createMarker: function(categoryId, point, id, name, html, icon)
		{
			if (categoryId=='0') {
				userDefined = true;
			}
			else {
				userDefined = false;
			}
			
	        id = userDefined ? 'userpoi' + id : id;
	        
			
			var gIcon = new GIcon();
			gIcon.shadow = "";
			gIcon.iconSize = new GSize(32, 32);
			gIcon.shadowSize = new GSize(32, 32);
			gIcon.iconAnchor = new GPoint(16, 16);
			gIcon.infoWindowAnchor = new GPoint(0, 32);
			gIcon.infoShadowAnchor = new GPoint(32, 0);
			gIcon.image = "http://64.131.71.17/markers/" + icon + ".png";
			
			
	        // create new pdmarker
			marker = new PdMarker(point, { icon: gIcon });

			// set the tooltip and window html
			marker.setTooltip(name);
			
        	if (userDefined) {
				html = '<a href="#" onclick="Map.addDirectionPoint(\'' + id + '\')"><img src="images/add.png" align="top" /> ' + LOCALE_routing_add + '</a>' +
				'<br />' +
				'<a href="#" onclick="Map.removeMarker(\'' + id + '\')"><img src="images/delete.png" align="top" /> ' + LOCALE_routing_del + '</a>';
			}
			else {
				html = '<p>' + html + '</p><br />' +
				'<a href="#" onclick="Map.openInfo(\'' + id + '\')"><img src="images/information.png" align="top" /> ' + LOCALE_routing_more + '</a>' +
				'<br />' +
				'<a href="#" onclick="Map.addDirectionPoint(\'' + id + '\')"> <img src="images/add.png" align="top" /> ' + LOCALE_routing_add + '</a>';
			}
			
			marker.setDetailWinHTML(html);
		
		    // add custom object with params
			marker.xxc = {
				userDefined: userDefined
				, name: name
				, id: id
				, icon: icon
				, categoryId: categoryId
				, point: point
			};

			// if it's a user defined point create a node in the tree			
			if (userDefined) {
				var tempChild = new Ext.tree.AsyncTreeNode(
					{
						userDefined: true,
						text: name,
						allowDrag: false,
						id: id,
						leaf: true,
						uiProvider: Ext.tree.TreeCheckNodeUI__poi
					}
				);
				
				Ext.getCmp('poi-user-tree').getRootNode().expand();
				
				Ext.getCmp('poi-user-tree').getRootNode().appendChild(tempChild);
			}
			
			return marker;
		},
		
		showDirections: function() {
			PdMarkerCloseAll();
			Ext.getCmp("custom_path").body.dom.innerHTML = '';
			
			var a = "";
			var from = true;
			var p;
			for (p=0; p<directionPointsCount; p++)
			{
				if (directionPoints.points[p] != null)
				{
					a += ( from ? "from: " : " to: " ) + directionPoints.points[p].point.toUrlValue(6);
					from = false;
				}
			}
			
			//gdir.load(a, {getPolyline:true});
			gdir.load(a, {getPolyline:true, getSteps:true});
		},
		
		loadPoints: function(doc) {
			// parse the json doc
			var jsonData = eval('(' + doc + ')');
			
			// create and set the markers on the map
			if (jsonData)
			{
				for (var i=0; i<jsonData.markers.length; i++)
				{
					if (jsonData.markers[i].lat==0 || jsonData.markers[i].lng==0 || jsonData.markers[i].text=='')
					{
						//console.info('test');
					}
					else
					{
						//console.info(jsonData.markers[i]);
						var point = new GLatLng(jsonData.markers[i].lat, jsonData.markers[i].lng);
						var marker = Map.createMarker(jsonData.markers[i].categoryId, point, jsonData.markers[i].id, jsonData.markers[i].text, jsonData.markers[i].html, jsonData.markers[i].mapIcon);
						map.addOverlay(marker);
					}
				}	
			}
			
			// this is used to create polylines from json
//			for (var i=0; i<jsonData.lines.length; i++) {
//				var pts = [];
//				for (var j=0; j<jsonData.lines[i].points.length; j++) {
//					pts[j] = new GLatLng(jsonData.lines[i].points[j].lat, jsonData.lines[i].points[j].lng);
//				}
//				map.addOverlay(new GPolyline(pts, jsonData.lines[i].colour, jsonData.lines[i].width)); 
//			}
		}
    };
}();
