IsEditing=false;

var POI_TO_ROLLUP = 35;

var InsetMap = true;
var InsetDiv = null;
var InsetMapCutoff = 1.28;
var InsetToggle = null;
var InsetTable = null;
var InsetMapObj = null;
var InsetSize = 100;
var IsEditing = false;

var gPointFilter = "*";

// zooms to show points between
var minZoom = 0;
var maxZoom = 999;
var numbersMinZoom = 0;
var numbersMaxZoom = 0.0025;
var gDatabase_Radius = 5;  // 5km radius initially
var gShowAds = true;

function fakesearch(str)
{
	getObj('search1').value = str;
	search();
}

var sections = new Array("s.search","s.database","s.weather","s.feedback","s.tools","s.more");

var sCurrentSection = "s.search";
var poiLayer = null;
var scratchLayer = null;
var routeLayer = null;
var routeLabelLayer = null;
var gResultsAreaHTML = "";

// variables used for temporary points
var TempPoints = new Array();
var RememberPoints = new Array();
var TPoint_Layer = null;

function InitialLoad()
{
    gResultsAreaHTML=getObj("resultsarea").innerHTML;
}

addLoadEvent(InitialLoad);

var savedSearch = null;

Array.prototype.ShowSearchResults = function(event, element)
{
	ResetSearch();
	AJAX_Search(savedSearch,true);
}


function sectionchange(which)
{
  sCurrentSection = which;
  var prevSel = false;
  
  // icons.png places x,y,w,h
  // tab1_h_l = 0,294,8,16
  // tab1_lh = 9,295,8,15
  // tab1_l_l = 19,295,8,15
  // tab1_hl = 28,295,8,15
  // tab1_ll = 37,295,8,15
  // tab1_h_r = 46,293,8,16
  // tab1_l_r = 57,294,8,15

	for (l=0;l<sections.length;l++) {
		if (which==sections[l]) {
			getObj(sections[l]).style.display="inline"
			getObj(sections[l]+".t").className="tab1mid";
			getObj(sections[l]+".lc").className="tab1mid_edge";
			
			// work out the tab thing to go to the left
			if (l==0) {
				picimg= new Array(0,294,8,16); // "img/tab1_h_l.png";
			} else {
				picimg= new Array(9,295,8,15); //"img/tab1_lh.png";
			}
			pim = PNG("img/icons.png",picimg[2],picimg[3],"",picimg[0],picimg[1],'userctrl_a');
			getObj(sections[l]+".l").innerHTML = pim;
			getObj(sections[l]+".l").height = picimg[3];
			
			prevSel = true;
		} else {
			getObj(sections[l]).style.display="none";
			getObj(sections[l]+".t").className="tab1lomid";
			getObj(sections[l]+".lc").className=prevSel?"tab1mid_edge":"tab1lomid_edge";

			// work out the tab thing to go to the left
			if (l==0) {
				picimg=new Array(19,295,8,15);  //"img/tab1_l_l.png";
			} else {
					if (prevSel) {
						picimg=new Array(28,295,8,15); //"img/tab1_hl.png";
					} else {
						picimg=new Array(37,295,8,15); //"img/tab1_ll.png";
					}
			}
			pim = PNG("img/icons.png",picimg[2],picimg[3],"",picimg[0],picimg[1],'userctrl_a');
			getObj(sections[l]+".l").innerHTML = pim;
			getObj(sections[l]+".l").height = picimg[3];
			
		  prevSel = false;
		}
	}
	
	// now do the last one
	if (which==sections[sections.length-1]) {
		picimg = new Array(47,295,8,15);
		pim = PNG("img/icons.png",picimg[2],picimg[3],"",picimg[0],picimg[1],'userctrl_a');
		getObj(sections[sections.length-1]+".r").innerHTML = pim; //"img/tab1_h_r.png";
		getObj(sections[sections.length-1]+".r").height = picimg[3];
		getObj(sections[sections.length-1]+".rc").className="tab1mid_edge";
	} else {
		picimg = new Array(57,294,8,15);
		pim = PNG("img/icons.png",picimg[2],picimg[3],"",picimg[0],picimg[1],'userctrl_a');
		getObj(sections[sections.length-1]+".r").innerHTML = pim;//"img/tab1_l_r.png";
		getObj(sections[sections.length-1]+".r").height = picimg[3];//15;
		getObj(sections[sections.length-1]+".rc").className="tab1lomid_edge";
	}
	
	if (which=="s.weather" && myMap.GetTileZoom()<=0.02) {
	    ClickCallback(myMap,myMap.GetX(),myMap.GetY());
	}
	
	if (which=="s.tools") {
		myMap.SetCursor("crosshair");
	} else {
		myMap.SetCursor(myMap.GetBaseCursor());
	}
	
	if (which!="s.tools" && scratchLayer!=null) {
		myMap.RemoveLayer(scratchLayer);
		scratchLayer=null;
		myMap.Init(false);
	}
}


var prevCategory = "";

function SearchDatabase(category,datasetName)
{
    if (datasetName=="stats") {
        var lyr = myMap.GetLayer("stats");
        if (lyr==null) {
            lyr = myMap.AddLayer("stats",98,"stats");
        }
        var bits = category.split("/");
        lyr.userData = new Array(bits[0],bits[1]);
        myMap.Init(false);
    }

    if (datasetName=="direc") {
	    // ajax call to search the database for specified category
	    if (category=="") {
	        category=prevCategory;
	    } else {
	        if (prevCategory!=category && poiLayer!=null)
                poiLayer.RemoveAllPoints();
	    }
	    prevCategory = category;
	    MurderChildren(getObj("resultsarea"));
	    dist = DistanceDegree(myMap.GetX(), myMap.GetY(), gDatabase_Radius*1);
	    sUrl = "ajax_points.asp?fmt=js&jscb=AJAX_Database&ctrl="+String(myMap.csContainer)+"&cat="+String(category)+"&x="+String(myMap.GetX())+"&y="+String(myMap.GetY())+"&max=100&r="+String(dist);
			callObj = new JSONscriptRequest(sUrl);
			callObj.Go(myMap.bShowProgress);
   }
}


function DatabaseLink(cls,ctrlname,path,txt,datasetName)
{
	var aTxt = txt.split(":");
	if (aTxt.length==3) {
		return "<span class='"+cls+"' onClick=\"SearchDatabase('"+aTxt[0]+"','"+datasetName+"');\">"+aTxt[1]+"</span>";
	} else {
		return "<span class='"+cls+"' onClick=\"ShowDatabase('"+ctrlname+"','"+path+"',"+datasetName+",'"+datasetName+"');\">"+aTxt[0]+"</span>";
	}
}

function ShowDatabase(ctrlname, path, dataset, datasetName)
{
	var parr = path.split(",");
	var data = dataset;

	var pr = DatabaseLink("direc_heading",ctrlname,"",data[0],datasetName);
	
	// show the path up to here
	var pathsofar = "";

	if (path.length>0) {
		for (var l=0;l<parr.length;l++) {
			if (pathsofar.length) pathsofar+=",";
			pathsofar += parr[l];
			data = data[parr[l]*1];
			heading = DatabaseLink("direc_heading",ctrlname,pathsofar,data[0],datasetName);
			pr = pr + " &#187; " + heading;
		}
	}
	
	pr = pr + " &#187; ";
	
	// show the subsections for the current thing
	basepath = pathsofar;
	for (var l=1;l<data.length;l++) {
		if (isArray(data[l])) {
			pathsofar = path;
			if (pathsofar.length>0) pathsofar+=",";
			pathsofar += String(l);
			heading = DatabaseLink("direc_link_heading",ctrlname,pathsofar,data[l][0],datasetName);
			if (l>1) pr = pr + ", ";
			pr = pr + heading;
		}
		if (isString(data[l])) {
			pathsofar = path;
			if (pathsofar.length>0) pathsofar+=",";
			pathsofar += String(l);
			heading = DatabaseLink("direc_link",ctrlname,pathsofar,data[l],datasetName);
			if (l>1) pr = pr + ", ";
			pr = pr + heading;
		}
	}
	
	container = getObj(ctrlname);
	container.innerHTML = pr;
}


function RecSearch(data,res,sstr,path)
{
	tofind = sstr.toLowerCase();
	var work = data;
	
	for (var l=0;l<work.length;l++) {
		if (isArray(work[l])) {
			// recurse
			var path2 = path;
			if (path2.length) path2+=",";
			path2+=String(l);
			res = RecSearch(work[l],res,sstr,path2);
		}
		if (isString(work[l])) {
			findin = work[l].toLowerCase();
			if (findin.indexOf(tofind)!=-1) {
				res.push( new Array(work[l],l==0,path) );
			} 
		}
	}
	
	return res;
}


function DirSearch(ctrl, ctrlname)
{
	sstr = ctrl.value;

	if (sstr.length==0) {
		ShowDatabase(ctrlname,"",direc,'direc')
		return;
	}

	var result = RecSearch(direc,new Array(),sstr,"");
	pr= "";
	for (l=0;l<result.length;l++) {
		var ent = result[l];
		heading = DatabaseLink(ent[1]?"direc_link_heading":"direc_link",ctrlname,ent[2],ent[0]);
		if (pr.length) pr += ", ";
		pr = pr + heading;
	}
	
	container = getObj(ctrlname);
	container.innerHTML = pr;
}


function submitfeedback()
{
	var em = getObj("feedback_email").value;
	if (em.length<3 || em.indexOf('.')<=0 || em.indexOf('@')<=0) {
		alert("Please supply an e-Mail address in case we need to get hold of you to get more information on your feedback.");
		return;
	}

	var fb = "e-Mail: " + getObj("feedback_email").value + "\r\nComment: " + getObj("feedback").value + "\r\n\r\nLink: "+getObj("link_url").value;
	fb += "\r\nBrowser: " + navigator.userAgent+" \r\nOperating System: "+navigator.platform;
	
  sUrl = "ajax_feedback.asp?fmt=js&jscb=AJAX_Feedback&f="+escape(fb)+"&fr="+getObj("feedback_email").value;
	callObj = new JSONscriptRequest(sUrl);
	callObj.Go(myMap.bShowProgress);
	getObj("feedback").value = "Sending Feedback, Please Stand By...";
}


function AJAX_Feedback(dat)
{
	gWait.Stop();

	if (dat.results.type!="feedback") {
	    alert("AJAX Error");
	    return;
	}

	var err = dat.results.error;
	
  if (err=="") {
  	getObj("feedback").value = "Sent!  Thanks for your feedback!";
  } else {
  	getObj("feedback").value = "There was an error sending the feedback, please try again later.";
  }
}


function CheckCookies()
{
	// session cookie
	var sessionCookie = readCookie("mapsession");
	if (isNull(sessionCookie)) {
			// drop a new one
			var sessionCookie = sessionID();
	}
	createCookie("mapsession",sessionCookie,1/(24*4)); // 15 min session timeout
	
	// user cookie
	var userCookie = readCookie("mapuser");
	if (isNull(userCookie)) {
			// drop a new one
			var userCookie = sessionID();
	}
	createCookie("mapuser",userCookie,30); // 30 day timeout on unique user
}

// pull out the cookies
var recentSearches = readCookie("recent");
if (recentSearches!=null) {
    rs = recentSearches.split("|");
    var html = "";
    
    for (l=0;l<rs.length;l++) {
        for (l2=0;l2<rs.length;l2++) {
            if (l2!=l && rs[l].toLowerCase()==rs[l2].toLowerCase()) {
                // delete dupe, reset l
                rs.splice(l2,1);
                l=0;
            }
        }
    }
    while (rs.length>4) {
        rs.splice(0,1);
    }
    
    // recreate the recentSearches string
    for (l=0;l<rs.length;l++) {
        if (l==0) recentSearches="";
            else recentSearches = recentSearches + "|";
        recentSearches = recentSearches + rs[l];
    }
    createCookie("recent",recentSearches,365);

    for (l=rs.length-1;l>=0;l--) {
        html = html + "<span onClick=\"fakesearch('"+rs[l]+"')\">"+rs[l]+"</span><br>\n";
    }

    getObj("recentdata").innerHTML = html;
} else {
    getObj("recent1").style.display="none";
    getObj("recent2").style.display="none";
    getObj("recent3").style.display="none";
}

var remember = readCookie("points");
	if (remember!=null) {
		var tparr = remember.split("$");
		for (var l=0;l<tparr.length;l++) {
			var ent = tparr[l].split("|");
			if (isNumber(ent[0]) && isNumber(ent[1])) {
				var tp = new TempPoint(ent[0]*1, ent[1]*1, ent[2]);
				RememberPoints.push(tp);
			}
		}
	}


function togglehelp(forcemode)
{
  var help1 = getObj("help1");
  var map1 = getObj("map1");
    
	if (isUndefined(forcemode)) {
    if (help1.style.display=="none") {
        help1.style.display="";
        map1.style.display="none";
        
				MurderChildren(InsetTable);
				InsetMapObj=null;
    } else {
        help1.style.display="none";
        map1.style.display="";
        myMap.Init(false);
				CheckInsetMap();
    }
	} else {
    if (forcemode==1) {
        help1.style.display="";
        map1.style.display="none";
        
				MurderChildren(InsetTable);
				InsetMapObj=null;
    } else {
        help1.style.display="none";
        map1.style.display="";
        myMap.Init(false);
				CheckInsetMap();
    }
	}
}

var routeStartX = 0;
var routeStartY = 0;
var routeEndX = 0;
var routeEndY = 0;




var lastJump = -1;

function DoJumpTo(step,x,y,z)
{
    if (lastJump!=-1) {
        getObj("step_"+String(lastJump)).className = "route_normal";
    }
    
    lastJump = step;
    getObj("step_"+String(step)).className = "route_selected";
    
    myMap.JumpTo(x,y,z);
}

function AppendDirection(tbl, dat, step)
{
    var f = dat.split("|");
    
    c0 = String(step);
    
    
    //parse out the icon indicators from the feature name.
    var featureName = f[1];    
    var featureIcon = "";
    var feature = String(f[1]);
    feature = feature.replace("&#124;", "|");    
    var pipeIndex = feature.indexOf("|");
    if (pipeIndex != -1) {
        featureName = feature.substring(pipeIndex+1);
        var featureIconID = feature.substring(0,pipeIndex);
        switch (featureIconID) {
            case "C" : featureIcon = "roundabout.png"; break;
            case "P" : featureIcon = "parallelramp.png"; break;
            case "R" : featureIcon = "ramp.png"; break;
            case "S" : featureIcon = "slipway.png"; break;
            case "E" : featureIcon = ""; break; //"road.png"; break;
            case "N" : featureIcon = "national.png"; break;
            case "F" : featureIcon = "freeway.png"; break;
        } 
        if (featureIcon.length > 0) {
            featureIcon = "<img src='/img/" + featureIcon + "' />";
        }
    }
    featureIcon = ""; //ignore for now    
    
    c1 = "<span onclick=\"DoJumpTo("+String(step)+","+f[4]+","+f[5]+",0.0025);\"><b>" + f[0] + "</b> "+ featureIcon+ toPC(featureName) + "</span>";
    
    c2 = NiceM(f[2]);
    
    var row = tbl.insertRow(-1);
    row.id = "step_"+String(step);
    row.className = "route_normal";
    row.vAlign = "top";
    var cell = row.insertCell(-1);
        cell.innerHTML = c0;
        cell.className = "route";

    cell = row.insertCell(-1);
        cell.innerHTML = c1;
        cell.className = "route";

    cell = row.insertCell(-1);
        cell.innerHTML = c2;
        cell.align = "right";
        cell.className = "route";
}


function RouteHeader(tbl,head,subhead)
{
    var row = tbl.insertRow(-1);
    row.vAlign = "center";
    
    c0 = "<b>"+head+"</b>" + toPC(subhead);
    
    var cell = row.insertCell(-1);
        cell.innerHTML = c0;
        cell.colSpan = 3;
        cell.className = "routeheader";
}


function ResultPoint(x,y,caption)
{
	this.x=x;
	this.y=y;
	this.caption=caption;
}

var dirLayer = null;
var aResultPoint = new Array();
var aPoints = new Array();

ResultPoint.prototype.ClickResult = function(event, element)
{
	if (dirLayer==null) {
		dirLayer=myMap.AddLayer("point",99,"points");
		dirLayer.SetDefaultAnchor("center","center");
	}
	dirLayer.DeletePoint("result");

	var pt = dirLayer.AddPoint(this.x,this.y,this.caption,"result");
	pt.SetImgFG("img/bubble_yellow_a.png");
	
	myMap.JumpTo(this.x,this.y,0.0025);
//	myMap.Init();
	
}

function PointHeader(rTable,colspan,txt)
{
	var vRow = rTable.insertRow(-1);
	var vCell = vRow.insertCell(-1);
		vCell.className = "searchhead";
		vCell.colSpan = colspan;
		vCell.innerHTML = txt;
		vCell.style.width="100%"
	vRow = rTable.insertRow(-1);
		vRow.style.height=8;
	vCell = vRow.insertCell(-1);
}



function OverPointCategory(rTable,cat)
{
	var vRow = rTable.insertRow(-1);
	vCell = vRow.insertCell(-1);
	    vCell.colSpan=2;
		vCell.className = "category";
		vCell.innerHTML = cat;
    return vCell;
}


function OverPointHeading(rTable,cat)
{
	var vRow = rTable.insertRow(-1);
	vCell = vRow.insertCell(-1);
	    vCell.colSpan=2;
		vCell.className = "heading";
		vCell.innerHTML = cat;
    return vCell;
}


function OverPointResult(rTable,x,y,caption,iconname,category,ctrl)
{
	var vRow = rTable.insertRow(-1);
	var vCell = vRow.insertCell(-1);
		vCell.innerHTML = PNG(iconname,16,16);
	vCell = vRow.insertCell(-1);
		vCell.className = "search1";
		vCell.innerHTML = "<div style='height:100%;width:100%;overflow:hidden;'>"+caption+"</div>";
    return vCell;
}


function PointResult(rTable,x,y,caption,iconname,category,ctrl,area)
{
	var retCell;
	var vRow = rTable.insertRow(-1);
	var vCell = vRow.insertCell(-1);
		vCell.innerHTML = PNG(iconname,16,16);
		vCell.style.verticalAlign = "top";
		vCell.rowSpan = 2;
	vCell = vRow.insertCell(-1);
		vCell.className = "search1";
		vCell.innerHTML = "<div class=search1 style='width:100%;overflow:hidden;'>"+caption+"</div>"
		retCell = vCell;
		
	vCell = vRow.insertCell(-1);
		vCell.className = "search3";
		vCell.rowSpan=2;
		vCell.style.verticalAlign = "bottom";
		vCell.align="right";
		dist = DistanceMeter(myMap.GetX(),myMap.GetY(),x,y)/1000;
		sDist = dist.toFixed(2)+"km";
		if (dist>5) sDist = dist.toFixed(0)+"km";
		fromclick = "myMap.MenuCallback('abs.dir.from',"+String(x)+","+String(y)+",myMap);";
		toclick = "myMap.MenuCallback('abs.dir.to',"+String(x)+","+String(y)+",myMap);";
//		routeClick = "myMap.ShowRoute("+String(myMap.GetX())+","+String(myMap.GetY())+","+String(x)+","+String(y)+",myMap)";
		sDist=sDist + "<br><img style='cursor:pointer;' onclick=\""+fromclick+"\" title='Get directions FROM this point' src='img/dir_from.png'>";
		sDist=sDist + "<img style='cursor:pointer;' onclick=\""+toclick+"\" title='Get directions TO this point' src='img/dir_to.png'>";
//		sDist=sDist + "<br><span class=searchroute onClick='"+routeClick+"'>Directions</span>&nbsp;"
		vCell.innerHTML = sDist;

	var vRow = rTable.insertRow(-1);
	vCell = vRow.insertCell(-1);
		vCell.className = "search2";
		vCell.innerHTML = "<div class=search2 style='width:100%;overflow:hidden;'>"+toPC(area)+"</div>";

    return retCell;
}


function GetDatabaseName(num)
{
    for (lp=0;lp<direcQR.length;lp++) {
        if (direcQR[lp][0]*1==num*1)
            return direcQR[lp][1];
    }
    return "";
}



function ExitMessage(rTable,msg)
{
    PointHeader(rTable, 1, msg);
}

function change_searchradius(ctrl)
{
    newrad = ctrl.value;
    gDatabase_Radius = newrad;
    SearchDatabase("","direc");
}


function AJAX_Database(ctrlname,dat)
{
	gWait.Stop();

	if (dat.results.type!="database") {
	    alert("AJAX Error");
	    return;
	}

    gPoints = false;
    gDatabase = true;

    aResultPoint.splice(0,aResultPoint.length);

    // create the search results pane
    var vDiv = getObj("resultsarea");
        MurderChildren(vDiv);
    var vTable = document.createElement("table");
        vDiv.appendChild(vTable);

    // points for the overlay layer
    if (poiLayer==null) {
        poiLayer = myMap.AddLayer("point",75,"points");
        poiLayer.SetDefaultAnchor("center","center");
    }
        
	var rTable = SetupScroller(getObj("resultsarea"));

    // search radius thing
    var aZooms = new Array("1","2","5","10","25","100");
    var sel = "";
    for (s=0;s<aZooms.length;s++) {
        var desc = (aZooms[s]=="99999")?"No Limit":aZooms[s]+" km";
        var selected = (aZooms[s]*1==gDatabase_Radius*1)?" selected ":"";
        sel = sel + "<option "+selected+" value='"+aZooms[s]+"'>"+desc+"</option>";
    }
    PointHeader(rTable,3,"<b>Search Radius</b> <select onchange='change_searchradius(this);'>"+sel+"</select>");

    if (dat.results.overpoint.length==0) {
        PointHeader(rTable, 3, "<center><b>No Results</b><p>Sorry, we have no entries of that type are on this part of the map.  Use the 'Points' function on the map to find if we have anything else nearby, or expand the scope of the search above.</center>");
        return;
    }

		PointHeader(rTable, 3, "<b>Note:</b> Result distances are relative to map position was when database enquiry was made: Somewhere near "+toPC(dat.results.anchor.area));

    var aList = new Array();

    r = "";

    for (l=0;l<dat.results.overpoint.length;l++) {
        var point = dat.results.overpoint[l];
        
        var x = point.x;
        var y = point.y;
        var ref = point.ref;
        var cat = point.cat;
        var caption = point.caption;
        var metadata = point.metadata;
        var area = point.area;
        var pointref="dir."+ref;

        // find an icon to use.. try cat, then drop to '0'
        var icon = "0";

        for (i=0;i<IconsAvailable.length && icon=="0";i++)
            if (IconsAvailable[i]*1==cat*1) icon = cat;
        
        var iconname="icon_small/"+icon+".png";
        catname = GetDatabaseName(cat);
        
        var thispt = poiLayer.FindPoint(pointref);
        var mode = "icon";

        if (thispt!=null) {
            mode = thispt.style;
            poiLayer.DeletePoint(pointref);
        }

        htmlCaption = CreateCaption(point,pointref,iconname,"database",ctrlname);
        var pt = poiLayer.AddPoint(x*1,y*1,htmlCaption,pointref);

        aList.push( new Array(x,y,pt,iconname,cat,caption,catname,area) );

        pt.SetStyle("icon");
        pt.SetIcon(iconname);
        pt.SetTooltip(caption);
        pt.SetIconAnchor("center","center");
        pt.SetLabelAnchor("iconcenter","iconcenter");
        pt.SetClickBehaviour("toggle_icon_biglabel");
        pt.SetVisible(minZoom,myMap.GetTileZoom()>maxZoom?myMap.GetTileZoom():maxZoom);
        pt.SetStyle(mode);	        
    }

    // create the browsable list
    var lastCat = "";

    for (l=0;l<aList.length;l++) {
        le = aList[l];
        if (lastCat!=le[6]) {
            OverPointCategory(rTable,le[6]);
            lastCat = le[6];
        }
        var hotspot = PointResult(rTable,le[0],le[1],le[5],le[3],le[4],le[2],le[7]);
        hotspot.onclick = associateObjWithEvent(le[2], "ProcessClickJump");
    }

    myMap.Init(false);
}


function AJAX_Weather(dat)
{
	gWait.Stop();

	if (dat==null) return;
	if (dat.results.type!="weather") {
	    alert("AJAX Error");
	    return;
	}

    var vDiv = getObj("weathercell");
    MurderChildren(vDiv);
    var vTable = document.createElement("table");
    iconbase = "http://www.southafricanweather.co.za/v3_sm/";
    vDiv.appendChild(vTable);
    vDataRow = null
    for (l=0;l<dat.results.weather.length;l++) {
        var we = dat.results.weather[l];
        
        var site = we.name;
        var id = we.id;
        var icon = we.icon;
        var day = we.day;
        var seq = we.seq;
        var low = we.low;
        var high = we.high;
        var sky = we.sky;
        var rain = we.rain;
        var temp = we.temp;
        
        if (l==0) {
            vRow = vTable.insertRow(-1);
            vCell = vRow.insertCell(-1);
                vCell.colSpan = 7;
                vCell.className = "weatherheading";
                vCell.innerHTML = "5-Day forecast for <b>"+site+"</b>.  <a href='http://www.southafricanweather.co.za/new/default.asp?Detailedweather="+String(id)+"' target='_new'>More Detail</a> from <a href='http://www.southafricanweather.co.za' target='_new'>southafricanweather.co.za</a>.";
            vDataRow = vTable.insertRow(-1);
        }
        
        vCell = vDataRow.insertCell(-1);
        vCell.className = "weather";
            vCell.width = 110;
            html = "<span style='font-size:11px;' title='header=[Weather&nbsp;Detail&nbsp;for&nbsp;"+day+"] body=[<b>Temperature:</b> "+toPC(temp)+"<br><b>Sky:</b> "+toPC(sky)+"<br><b>Rain:</b> "+toPC(rain)+"]'><img align=left src='"+iconbase+icon+".gif'><b>"+day+"</b><br>"+Math.round(low)+"&deg;&nbsp;-&nbsp;"+Math.round(high)+"&deg;C</span>";
            vCell.innerHTML = html;
    }
}

var pointListXML = null;
var	pointList = null;

function PointEntry(x,y,xml,iconname,cat,caption,catname,default_open)
{
		this.x=x;
		this.y=y;
		this.xml=xml;
		this.iconname=iconname;
		this.cat=cat;
		this.caption=caption;
		this.catname=catname;
		this.default_open=(default_open)?default_open:false;
}


function CMPovers(a,b)
{
	// [6] = category
	// [5] = heading
	if (a.catname>b.catname) return +1;
	if (a.catname<b.catname) return -1;
	if (a.caption>b.caption) return +1;
	if (a.caption<b.caption) return -1;
	return 0;
}


var pointPopup = "";

function CPointData(x,y,cat,ref,caption,metadata)
{
	this.x = x;
	this.y = y;
	this.cat = cat;
	this.ref = ref;
	this.caption=caption;
	this.metadata = metadata;
}


function PointHeadingCallback(tree, node)
{
}


function PtsReplaceBubbleInplace(pt)
{
	if (pt.pCaption.length>0) {
		RemoveBubble(String(pt.userRef),"point."+String(pt.userRef),'poiLayer',pt.parent.csContainer);
	} else {
		ReplaceBubble(String(pt.userRef),"point."+String(pt.userRef),'poiLayer',pt.parent.csContainer);
	}
}


function PointCallback(tree, node)
{
	var ref = "point."+node.entrydata.ref;
	var thispt = poiLayer.FindPoint(ref);
	PtsReplaceBubbleInplace(thispt);
//	thispt.ProcessClick(null,null);
}


function LeafShowCallback(node)
{
	// see if this entry needs to be popped up
  var ref = node.entrydata.ref;
  var pointref="point."+ref;
  var spl = pointPopup.split(",");
  var poppedup = false;
  for (var l=0;l<spl.length && !poppedup;l++) {
  	if (spl[l]==pointref) poppedup = true;
  }

	var pt = GetPoint(node.entrydata, IconName(node), poppedup);
}


var treeState = "";

function TreeDrawEnd(tree)
{
	myMap.Init(false);
	treeState = tree.GetState();
}


function TreeDrawBegin(tree)
{
    // points for the overlay layer
    if (poiLayer==null) {
        poiLayer = myMap.AddLayer("point",49,"points");
        poiLayer.SetDefaultAnchor("center","center");
    }
    
    poiLayer.RemoveAllPoints();
}


function AJAX_Points(ctrlname,dat)
{
	gWait.Stop();

	if (dat==null) return;
	if (dat.results.type!="points") {
	    alert("AJAX Error");
	    return;
	}

		var treedata = new Array();
		treedata = TreeRec(direc,0,treedata,null);
		tree = new CTree(getObj("resultsarea"), treedata);
		tree.LeafCallback = PointCallback;
		tree.NonLeafCallback = PointHeadingCallback;
		tree.LeafShowCallback = LeafShowCallback;
		tree.DrawEndCallback = TreeDrawEnd;
		tree.DrawBeginCallback = TreeDrawBegin;

    if (dat.results.overpoint.length==0) {
		    var rTable = SetupScroller(getObj("resultsarea"));
        ExitMessage(rTable,"<center><b>No Results</b><p>Sorry, we have no points of interest on this part of the map.  To find nearby points, please use the Database above.  For help on using this feature, select 'Help' from the top-right of the window.</center>");
        myMap.Init(false);
        return;
    }

    for (var l=0;l<dat.results.overpoint.length;l++) {
        var point = dat.results.overpoint[l];
        
        point.caption = point.caption;

				node = tree.AddEntryUnder(point.cat*1,point.caption,point);
    }
    
  // grab the old POI references
  pointPopup = "";
  if (poiLayer!=null) {
  	for (var l=0;l<poiLayer.aPoints.length;l++) {
  		var pt = poiLayer.aPoints[l];
  		if (pt.style=="label") {
				if (pointPopup.length>0) pointPopup += ",";
				pointPopup += pt.id;
			}
  	}
  }

	tree.TrimNoLeaf();
	if (tree.tdata.length<32) tree.ExpandAll();
	tree.SetState(treeState);
	tree.Redraw();

}


function SetupScroller(vDiv)
{
		MurderChildren(vDiv);
    var vTable = document.createElement("table");
    vDiv.appendChild(vTable);
        
    vTable.className = "findTab";
    vTable.cellSpacing = 0;
    vTable.cellPadding = 3;
    vTable.style.height = "100%";

    vRow = vTable.insertRow(-1);
    vCell = vRow.insertCell(-1);
    vCell.colSpan = 3;
    vCell.style.height = "50%";
	
    var vScroller = document.createElement("div");
    vScroller.style.overflowX = "hidden";
    vScroller.style.overflowY = "auto";
    vScroller.style.position = "static";
    vScroller.style.height=getObj("resultsarea").clientHeight - 32;
    vScroller.style.backgroundColor="#ffffff";
    vCell.appendChild(vScroller);

    var rTable = document.createElement("table");
        rTable.cellSpacing = 0;
        rTable.cellPadding = 1;
        rTable.style.width = "100%";
        rTable.style.backgroundColor="#ffffff";
    vScroller.appendChild(rTable);
    
    return rTable;
}


function UpdateSpots(filter)
{
    // create the search results pane
    var rTable = SetupScroller(getObj("resultsarea"));
    OverPointHeading(rTable,"Points of Interest");

    var lastCat = "";
    var showIcon = "";
    
    poiLayer.RemoveAllPoints();
  	
  	for (l=0;l<pointList.length;l++) {
      le = pointList[l];
      if (lastCat!=le.catname) {
          var hotspot = OverPointCategory(rTable,le.catname+" ("+CountCategory(pointList,le.catname)+")");
          hotspot.onclick = associateObjWithEvent(pointList[l], "HotspotClick");
          lastCat = le.catname;
      }
      if (filter=="" || filter==le.catname) {
      	var pt = GetPoint(le.xml);
      	if (le.default_open) {
      		pt.SetStyle("label");
      	}
	      var hotspot = OverPointResult(rTable,le.x,le.y,le.caption,le.iconname,le.cat,pt);
	      hotspot.onclick = associateObjWithEvent(pt, "ProcessClick");
	    }
    }

	   myMap.Init(false);
}




PointEntry.prototype.HotspotClick = function(event, element)
{
	gPointFilter = this.catname;
	UpdateSpots(gPointFilter);
}


function GetPoint(pnt,iconname,poppedup)
{
		htmlCaption = "";
		var id = "point."+pnt.ref;
    var pt = poiLayer.AddPoint(pnt.x*1,pnt.y*1,htmlCaption,id);
    pt.userRef=pnt.ref;
    poppedUp=-1;
    pt.SetStyle(id==poppedUp?"label":"icon");
    if (pnt.icon.indexOf("://")>0)
    	pt.SetIcon(pnt.icon+"_16.png");
    else
    	pt.SetIcon("icons/"+pnt.icon+"_16.png");
    pt.SetCallback(PtsReplaceBubbleInplace);
    pt.SetTooltip(pnt.caption);
    pt.SetIconAnchor("center","center");
    pt.SetLabelAnchor("left","bottom");
    pt.SetClickBehaviour("toggle_icon_biglabel");
    pt.SetVisible(0,pnt.cutoff);

}


function CountCategory(aList, hdg)
{
	var ret = 0;
	for (var l=0;l<aList.length;l++)
		if (aList[l].catname==hdg) ret++;
	return ret;
}

function AJAX_Route(dat)
{
	gWait.Stop();

		if (dat==null) return;

		if (dat.results.type!="route") {
		    alert("AJAX Error");
		    return;
		}
		
    MurderChildren(getObj("resultsarea"));
    var vDiv = getObj("resultsarea");

    var vScroller = document.createElement("div");
    vScroller.style.overflowX = "hidden";
    vScroller.style.overflowY = "auto";
    vScroller.style.position = "static";
    vScroller.style.height=getObj("resultsarea").clientHeight - 32;
    vDiv.appendChild(vScroller);

    var vTable = document.createElement("table");
    vTable.width = "95%"
    vTable.className = "route";
    vTable.cellPadding = 2;
    vTable.cellSpacing = 0;
    vScroller.appendChild(vTable);

    RouteHeader(vTable,"Route From: ",dat.results.start.data);
    
    minX = 9999;
    maxX = -9999;
    minY = 9999;
    maxY = -9999;
    var totdist = 0;

    for (l=0;l<dat.results.route.length;l++) {
        var thisdat = dat.results.route[l].data;
        AppendDirection(vTable,thisdat,l+1);
        
        var f = thisdat.split("|");
      	if (f[4]*1!=0 && f[5]*1!=0) {
	        if (f[4]*1 > maxX) maxX = f[4]*1;
	        if (f[4]*1 < minX) minX = f[4]*1;
	        if (f[5]*1 > maxY) maxY = f[5]*1;
	        if (f[5]*1 < minY) minY = f[5]*1;
	      }

	      totdist = f[3];
    }
    
    cenX = (maxX+minX)/2;
    cenY = (maxY+minY)/2;

    if ( (maxX-minX) > (maxY-minY) ) {
        zm = (maxX-minX)/1.5;
    } else {
        zm = (maxY-minY)/1.5;
    }

    myMap.Jump(cenX, cenY, myMap.FindZoom(zm));
    myMap.Init(false);
    RouteHeader(vTable,"Route To: ",dat.results.end.data+"<br> Total Distance: "+NiceM(totdist));
}



function ErrorTable(caption,txt)
{
    return "<table width=100% bgcolor=white><tr><td><table width=100% class=error><tr><td class=errorhead>"+caption+"</td></tr><tr><td class=error>"+txt+"</td></tr></table></td></tr></table>";
}

var POIWindowName = "";


function Global_POI_Close()
{
    document.body.removeChild(getObj(POIWindowName));
}


function Global_POI(map,x,y)
{
    var winW=0;
    var winH=0;
    
    if (parseInt(navigator.appVersion)>3) {
     if (navigator.appName=="Netscape") {
      winW = window.innerWidth;
      winH = window.innerHeight;
     }
     if (navigator.appName.indexOf("Microsoft")!=-1) {
      winW = document.body.offsetWidth;
      winH = document.body.offsetHeight;
     }
    }

	var uDiv = document.createElement("div");
	POIWindowName = "poi_window_"+String(RandomInt(99999));
	uDiv.id = POIWindowName;
	uDiv.style.position = "absolute";
    var fWidth = 480;
    var fHeight = 450;
	uDiv.style.width=fWidth;
	uDiv.style.height=fHeight;
	uDiv.style.left=winW/2-fWidth/2;
	uDiv.style.top=winH/2-fHeight/2;
	uDiv.style.border="2px solid black";
	uDiv.style.zIndex=500;
	uDiv.innerHTML = "<div><iframe src='poi/map.asp?x="+String(x)+"&y="+String(y)+"&wn="+POIWindowName+"' width=100% height=100% frameborder=0 ALLOWTRANSPARENCY=false background=white></iframe></div>";
	document.body.appendChild(uDiv);
}


function Global_UserPhoto_Close()
{
    document.body.removeChild(getObj("UserPhoto_Window"));
}



function Global_UserPhoto(map,x,y)
{
    var winW=640;
    var winH=480;
    
    if (parseInt(navigator.appVersion)>3) {
     if (navigator.appName=="Netscape") {
      winW = window.innerWidth;
      winH = window.innerHeight;
     }
     if (navigator.appName.indexOf("Microsoft")!=-1) {
      winW = document.body.offsetWidth;
      winH = document.body.offsetHeight;
     }
    }

	var uDiv = document.createElement("div");
	uDiv.id = "UserPhoto_Window";
	uDiv.style.position = "absolute";
//	this.cScratch.style.visibility = "hidden";
    var fWidth = 400;
    var fHeight = 500;
	uDiv.style.width=fWidth;
	uDiv.style.height=fHeight;
	uDiv.style.left=winW/2-fWidth/2;
	uDiv.style.top=winH/2-fHeight/2;
	uDiv.style.border="2px solid black";
	uDiv.innerHTML = "<iframe src='UserPhoto.asp?x="+String(x)+"&y="+String(y)+"' width=100% height=100% frameborder=0 ALLOWTRANSPARENCY=false background=white>";
	document.body.appendChild(uDiv);
}

getObj("search1").onkeyup = searchkeyup;
getObj("search1").onkeydown = searchkeydown;



function searchkeyup(e)
{
  if (window.event) e=window.event;
	var KeyID = e.keyCode;

  StopPropagation(e);	
}


function searchkeydown(e)
{
    if (window.event) e=window.event;
	var KeyID = e.keyCode;

    StopPropagation(e);	

	switch (KeyID) {
		case 13 :
			search();
			break;
	}
	
}

function ResetSearch()
{
	togglehelp(0);
	rRoads.splice(0,rRoads.length);
	rFeatures.splice(0,rFeatures.length);
	rPoints.splice(0,rPoints.length);
	MurderChildren(getObj("resultsarea"));
	getObj("searchbutton").disabled=true;
}

function search() 
{
	ResetSearch();
	if (isNull(recentSearches)) {
	    recentSearches = getObj("search1").value;
	} else {
	    recentSearches = recentSearches + "|" + getObj("search1").value;
	}
	createCookie("recent",recentSearches,365);
	sUrl = "ajax_search.asp?raw=1&fmt=js&jscb=AJAX_Search&s1="+getObj("search1").value+"&cc=ZAF";
	callObj = new JSONscriptRequest(sUrl);
	callObj.Go(myMap.bShowProgress);
}

function AJAX_Error(source)
{
    MurderChildren(getObj("resultsarea"));
    html = ErrorTable("Internet Error", "There was an error communicating with the server. Please wait a little while and try the action again.");
    getObj("resultsarea").innerHTML = html;
    getObj("searchbutton").disabled=false;
}
	
var myMap = null;

function ClickCallback(obj,x,y)
{
    if (sCurrentSection=="s.tools") {
    	getObj("c_deg_x").value = x.toFixed(6);
			getObj("c_deg_y").value = y.toFixed(6);
    	ConvertFrom(1);
    	UpdateCoordinate();
    }
    
    if (sCurrentSection=="s.weather") {
	    MurderChildren(getObj("weathercell"));
	    sUrl = "ajax_weather.asp?fmt=js&jscb=AJAX_Weather&x="+String(x)+"&y="+String(y);
			callObj = new JSONscriptRequest(sUrl);
			callObj.Go(myMap.bShowProgress);
    }
}

var redrawLastX = 0;
var redrawLastY = 0;
var layerCadastral = null;

function CadastralClick()
{
	if (layerCadastral==null)
		CadastralLayer(true);
	else
		CadastralLayer(false);
}

function CadastralLayer(active)
{
	if (active) {
		if (layerCadastral==null) {
			// create it
			layerCadastral = myMap.AddLayer("custom",98,"cadastral");
			layerCadastral.SetCustomUrl(myMap.GetBaseUrl()+"/maptile/f_parcels/%width%_%height%/%scale%/%y%_%x%.png");
			myMap.Init(false);
		}
	} else {
		// if cadastrals are active, remove the layer
		if (layerCadastral!=null) {
			myMap.RemoveLayer(layerCadastral);
			layerCadastral=null;
			myMap.Init(false);
		}
	}
}

function CMPstat(a,b)
{
	if (a.pri>b.pri) return -1;
	if (a.pri<b.pri) return 1;
	if (a.caption<b.caption) return -1;
	if (a.caption>b.caption) return 1;
	return 0;
}


Object.prototype.PopPoint = function(event, element)
{
	// pop all points on the layer down to icons
	for (l=0;l<fixedPoiLayer.aPoints.length;l++) {
		fixedPoiLayer.aPoints[l].SetStyle("icon");
	}

	var pt = fixedPoiLayer.FindPoint("point."+String(this.ref));
	if (pt==null) {
		// add this point to the layer then pop it up
		var pt = fixedPoiLayer.AddPoint(this.x*1,this.y*1,"","point."+this.ref);
		pt.userRef=this.ref;
    pt.SetIcon(GetIconName(this.cat));
    pt.SetCallback(ReplaceBubbleInplace);
    pt.SetTooltip(this.caption);
    pt.SetIconAnchor("center","center");
    pt.SetLabelAnchor("left","bottom");
    pt.SetClickBehaviour("toggle_icon_biglabel");
    pt.SetVisible(0,this.cutoff);
	}
	ReplaceBubbleInplace(pt)
}

function MakeCaption(pt)
{
	ret = "";
	if (pt.pri>0) {
		ret = "<div class=ad_1_h>"+pt.caption+"</div><div class=ad_1_b>"+pt.category+"</div>";
	} else {
		ret = "<div class=ad_2_h>"+pt.caption+"</div><div class=ad_2_b>"+pt.category+"</div>";
	}
	return ret;
}

function AJAX_Status_Callback(dat)
{
	gWait.Stop();

	if (dat.results.type!="status") {
	    alert("AJAX Error");
	    return;
	}

	if (myMap.GetTileZoom() < 1) {
		ShowFadeDiv(myMap.cContainer, FadeCaption(dat.area));
	}

	var mustRedraw = true;

    for (l=0;l<dat.results.status.length;l++) {
        var st = dat.results.status[l];
        
        var stype = st.type;
        var value = st.value;

        if (stype=="cadastral") {
        	if (value=="yes") {
        		getObj("more_cadastral").disabled = false;
        		getObj("more_cadastral_text").className = "sectiontext";
        		
        		// if its checked and we've just come back into range, show the layer
        		if (layerCadastral==null && getObj("more_cadastral").checked) CadastralLayer(true);
        	} else {
        		getObj("more_cadastral").disabled = true;
        		getObj("more_cadastral_text").className = "sectiontextdisabled";

						CadastralLayer(false);
        	}
        }

        if (stype=="satellite") {
					if (value=="yes") {
						// there are satellite views for this
						if (!myMap.isSatellite) {
							mustRedraw = true;
							myMap.isSatellite = true;
						}
					} else {
						// no satellite views for this
						if (myMap.isSatellite) {
							mustRedraw = true;
							myMap.isSatellite = false;
						}
		
						// if we're in satellite/hybrid mode, switch to map mode
						var isSat = false;
						for (l=0;l<myMap.aLayers.length;l++) {
							if (myMap.aLayers[l].nType=="hyb") isSat=true;
							if (myMap.aLayers[l].nType=="sat") isSat=true;
						}
						if (isSat) myMap.doControlMap();
		
					}
        }
    }

    var pts = dat.results.points;
    
		if (dat.oldnew.length || (pts!=null && myMap.gAds && gShowAds)) {
			// create a scrollable area in the results pane    
			var vDiv = getObj("resultsarea");
	
	    var vScroller = document.createElement("div");
	    vScroller.style.overflowX = "hidden";
	    vScroller.style.overflowY = "auto";
	    vScroller.style.position = "static";
	    vScroller.style.height=getObj("resultsarea").clientHeight - 32;
	    	vScroller.style.width="100%"
	
			MurderChildren(vDiv);
			vDiv.appendChild(vScroller);
	
	    var vTable = document.createElement("table");
	    	vTable.width="100%"
		}    	
    
    if (dat.oldnew.length) {
				// put a notice that there are road name changes
				vRow = vTable.insertRow(-1);
				vRow.vAlign = "top";
				vCell = vRow.insertCell(-1);
				vCell.colSpan = 2;
					vCell.onclick = associateObjWithEvent(dat.oldnew, "NameChanges");
					vCell.innerHTML = "<div class=nchange_h>Road Name Changes</div><div class=nchange_b>There are roads on this map whose names have changed recently, click here for a list.</div>";
    }
    
    // print the points out in the results area
    var showHd1 = false;
    var showHd2 = false;
    if (pts!=null && myMap.gAds && gShowAds) {
			pts.sort(CMPstat);

				if (savedSearch!=null) {
					vRow = vTable.insertRow(-1);
					vRow.vAlign = "top";
					vCell = vRow.insertCell(-1);
					vCell.colSpan=2;
					vCell.innerHTML = "<div  class=ad_action>&lt;&lt; Back to Search Results</div>";
					vCell.onclick = associateObjWithEvent(pts, "ShowSearchResults");
				}
			    
			for (l=0;l<pts.length;l++) {
				if (pts[l].pri>0 && !showHd1) {
					vRow = vTable.insertRow(-1);
					vRow.vAlign = "top";
					vCell = vRow.insertCell(-1);
					vCell.colSpan=2;
					vCell.innerHTML = "<div class=ad_title>Sponsored Points</div>";
					showHd1 = true;
				}

				if (pts[l].pri==0 && !showHd2) {

					// put our ad in here quickly
					vRow = vTable.insertRow(-1);
					vRow.vAlign = "top";
					vCell = vRow.insertCell(-1);
				    vCell.style.width = "32px";
		      	    vCell.innerHTML = "<img src='"+ScriptBase()+"img/streetmaps_32.png'>";
					vCell = vRow.insertCell(-1);
					vCell.onclick = associateObjWithEvent(pts[l], "Promote");
					vCell.innerHTML = "<div class=ad_1_hr  >Promote Your Business Here</div><div class=ad_1_b>Click for details</div>";
				
					
                	
					
					vRow = vTable.insertRow(-1);
					vRow.vAlign = "top";
					vCell = vRow.insertCell(-1);
					vCell.colSpan=2;
					vCell.innerHTML = "<div class=ad_title>Nearby Points</div>";
					showHd2 = true;
				}
				
				vRow = vTable.insertRow(-1);
				vRow.vAlign = "top";
				if (pts[l].pri>0) {
					vCell = vRow.insertCell(-1);
						vCell.style.width = "32px";
		      	vCell.innerHTML = "<img src='"+CheckIcon(pts[l].icon,32)+"'>";
						
					vCell = vRow.insertCell(-1);
						vCell.style.cursor = "pointer";
						vCell.onclick = associateObjWithEvent(pts[l], "PopPoint");
						vCell.innerHTML = MakeCaption(pts[l]);
				} else {
					vCell = vRow.insertCell(-1);
						vCell.colSpan=2;
						vCell.style.cursor = "pointer";
						vCell.onclick = associateObjWithEvent(pts[l], "PopPoint");
						vCell.innerHTML = MakeCaption(pts[l]);
				}
			}
	
	    vScroller.appendChild(vTable);
	  }

    if (mustRedraw) myMap.Init();
    
	if (dat.pointcount*1>0 && !gPoints) {
		PulsePoints();
	}

}


function CheckInsetMap()
{
		if (InsetMapObj==null) {
			// create a new div for this
			InsetTable = document.createElement("table");
			document.body.appendChild(InsetTable);
			InsetTable.style.position = "absolute";
			InsetTable.style.tableLayout = "fixed";
			InsetTable.style.zOrder = 300;
			InsetTable.cellSpacing = 0;
			InsetTable.cellPadding = 0;
			InsetTable.style.backgroundColor = "white";
			InsetTable.style.width = PX(InsetSize + 5);
			InsetTable.style.height = PX(InsetSize + 5);
			InsetTable.style.borderLeft = "1px solid #888888";
			InsetTable.style.borderTop = "1px solid #888888";
			leftpos = XAbsolute(myMap.nCtrlWidth - (InsetSize + 5), myMap.cContainer);
			InsetTable.style.left = PX( leftpos );
			InsetTable.style.top = PX( YAbsolute(myMap.nCtrlHeight - (InsetSize + 5), myMap.cContainer) );
			myMap.SetCopyrightXMargin(105);

				tr = InsetTable.insertRow(-1);
				tr.style.height = "4px";
					td = tr.insertCell(-1);
						td.style.width = "4px";
					td = tr.insertCell(-1);
						td.style.width = PX(InsetSize);
						
					if (BrowserDetect.browser!="Explorer") {
						// for some reason IE leaves a see-through bit here
						td = tr.insertCell(-1);
							td.style.width="2px";
					}

				tr = InsetTable.insertRow(-1);
				tr.style.height = PX(InsetSize);
					td = tr.insertCell(-1);
						td.style.width = "4px";
					td = tr.insertCell(-1);
					td.style.backgroundColor = "green";
						td.style.width = PX(InsetSize);
						td.style.height = PX(InsetSize);
						InsetDiv = document.createElement("div");
						td.appendChild(InsetDiv);
						if (BrowserDetect.browser=="Explorer") {
							InsetDiv.style.width = PX(InsetSize);
							InsetDiv.style.height = PX(InsetSize);
						} else {
							InsetDiv.style.width = PX(InsetSize+2);
							InsetDiv.style.height = PX(InsetSize+2);
						}
						InsetDiv.style.backgroundColor = "#dddddd";
						InsetDiv.id="map_inset";
				
				// everything is set up, create the map
				InsetMapObj = new CAatMap();
				InsetMapObj.SetOutput("map_inset");
				InsetMapObj.AddLayer("map",100);
				InsetMapObj.SetPopupMenu(false);
				InsetMapObj.SetNavigate(false);
				InsetMapObj.SetPointsButtons(false);
				InsetMapObj.SetModeButtons(false);
				InsetMapObj.SetScaleBar(false);
				InsetMapObj.zIndexBase = 100;
				InsetMapObj.Jump(thisx, thisy, thiszm);
				InsetMapObj.RedrawCallback=InsetRedrawCallback;
				InsetMapObj.baseOverride = myMap.baseOverride;
				InsetMapObj.bNoBranding=true;
				InsetMapObj.NoStatusCallback=true;
				InsetMapObj.SetHotkeys(false);
				InsetMapObj.Init(false);

			// inset toggle
			InsetToggle = document.createElement("div");
			document.body.appendChild(InsetToggle);
			InsetToggle.style.position = "absolute";
			InsetToggle.width = "16px";
			InsetToggle.height = "16px";
			InsetToggle.style.zOrder = 310;
			InsetToggle.onclick = ToggleInset;
			if (BrowserDetect.browser=="Explorer") {
				InsetToggle.style.left = PX( XAbsolute(myMap.nCtrlWidth - 17, myMap.cContainer) );
				InsetToggle.style.top = PX( YAbsolute(myMap.nCtrlHeight - 17, myMap.cContainer) );
			} else {
				InsetToggle.style.left = PX( XAbsolute(myMap.nCtrlWidth - 15, myMap.cContainer) );
				InsetToggle.style.top = PX( YAbsolute(myMap.nCtrlHeight - 15, myMap.cContainer) );
			}
			InsetToggle.style.cursor = "pointer";
			InsetToggle.innerHTML = "<img width=16 height=16 src='img/inset_close.gif' border=0>";

		} // create map
}

function RedrawCallback(obj,x,y,source,forcemove)
{
    // update the link

    var plink = getObj("action_print");
    var email = getObj("action_email");
    var href = String(window.location);
    gShowAds = true;

    if (href.indexOf("?")>0) {
        href = href.slice(0,href.indexOf("?"));
    }

    if (href.indexOf("#")>0) {
        href = href.slice(0,href.indexOf("#"));
    }
    
    var phref = href
    var dhref = href
    var sref = href

    if (phref.indexOf("default.asp")>0) {
        phref = phref.slice(0,phref.indexOf("default.asp"));
    }

	var s = "m";
	for (l=0;l<myMap.aLayers.length;l++) {
		if (myMap.aLayers[l].nType=="sat") s="s";
	}
	if (myMap.hybridLayer!=null) s="h";
	p=gPoints?"1":"0";

    sref = sref + "static_map.asp?x="+String(myMap.GetX())+"&y="+String(myMap.GetY())+"&z="+String(myMap.GetZoom())+"&s="+s+"&width="+String(myMap.nCtrlWidth)+"&height="+String(myMap.nCtrlHeight)
    href = href + "?x="+String(myMap.GetX())+"&y="+String(myMap.GetY())+"&z="+String(myMap.GetTileZoom())+"&s="+s+"&p="+p;
    phref = phref + "print.asp?x="+String(myMap.GetX())+"&y="+String(myMap.GetY())+"&z="+String(myMap.GetTileZoom())+"&s="+s+"&p="+p;
    dhref = dhref + "developer.asp?x="+String(myMap.GetX())+"&y="+String(myMap.GetY())+"&z="+String(myMap.GetTileZoom())+"&s="+s+"&p="+p;

	if (routeStartX!=0 && routeStartY!=0 && routeEndX!=0 && routeEndY!=0) {
		href = href + "&r="+routeStartX.toFixed(6)+","+routeStartY.toFixed(6)+","+routeEndX.toFixed(6)+","+routeEndY.toFixed(6);
		phref = phref + "&r="+routeStartX.toFixed(6)+","+routeStartY.toFixed(6)+","+routeEndX.toFixed(6)+","+routeEndY.toFixed(6);
		dhref = dhref + "&r="+routeStartX.toFixed(6)+","+routeStartY.toFixed(6)+","+routeEndX.toFixed(6)+","+routeEndY.toFixed(6);
		gShowAds = false;
	}

	// temporary points

	if (RememberPoints.length>0) {
		href += "&tp=";
		phref += "&tp=";
		for (var l=0;l<RememberPoints.length;l++) {
			var bit = "";
			if (l>0) bit += "$";
			bit += String(RememberPoints[l].x.toFixed(6))+"|"+String(RememberPoints[l].y.toFixed(6))+"|"+RememberPoints[l].label;
			href += URLEncode(bit);
			phref += URLEncode(bit);
			dhref += URLEncode(bit);
		}
	}

    getObj("link_url").value=href;
    getObj("link_developer").href=dhref;
    getObj("snapshot_url").value=sref;
    getObj("snapshot_url_link").href=sref;

    plink.href=phref;
   
    email.href="mailto:?subject="+escape("Map from www.streetmaps.co.za")+"&body="+escape(href);

		CheckCookies();

    if (sCurrentSection=="s.weather") {
	    MurderChildren(getObj("weathercell"));
	    url = "ajax_weather.asp?x="+String(x)+"&y="+String(y);
        AjaxRequest.get({
             'url':url
            ,'onSuccess':AJAX_Weather
            ,'groupName':'weather'
            ,'onGroupBegin':function(req) { gWait.Start(); }
            ,'onGroupEnd':function(req) { gWait.Stop(); }
            ,'onError':function(req) { AJAX_Error("weather"); }
        });
//	    makeRequest(url, "Getting Weather, Stand By");
    }
    
    if (gDatabase) {
        // need to update the database
        SearchDatabase("","direc");
    }

    // check if we need to turn a numbers layer off
    if (obj.GetTileZoom()<numbersMinZoom || obj.GetTileZoom()>numbersMaxZoom) {
    		var found = false;
				for (l=0;l<myMap.aLayers.length && !found;l++) {
					if (myMap.aLayers[l].nType=="num") {
						myMap.RemoveLayer(myMap.aLayers[l]);
						found = true;
						myMap.Init(false);
					}
				}
    }
    
    if (obj.GetTileZoom()>=minZoom && obj.GetTileZoom()<=maxZoom) {
        if (gPoints) {
            // only force a redraw if we moved > 5% of the screen
            var moved = Math.sqrt(Math.pow(obj.GetX()-redrawLastX,2)+Math.pow(obj.GetY()-redrawLastY,2));
            var hasMoved = moved>obj.GetZoom()/20;
            if (!isUndefined(forcemove) && forcemove) hasMoved = true;
            if (hasMoved) {

                sUrl = "ajax_points.asp?fmt=js&ctrl="+String(obj.csContainer)+"&jscb=AJAX_Points&x="+String(obj.GetX()-obj.DegWidth()*0.6)+"&y="+String(obj.GetY()-obj.DegHeight()*0.6)+
                    "&x1="+String(obj.GetX()+obj.DegWidth()*0.6)+"&y1="+String(obj.GetY()+obj.DegHeight()*0.6)+
                    "&z="+String(obj.GetTileZoom());

								callObj = new JSONscriptRequest(sUrl);
								callObj.Go(myMap.bShowProgress);

	            redrawLastX = obj.GetX();
	            redrawLastY = obj.GetY();
	        }
	    }
    }
    
    if (!gDatabase && !gPoints && poiLayer!=null && routeMarkerLayer==null) {
        myMap.RemoveLayer(poiLayer);
        poiLayer=null;
        myMap.Init(false);
        redrawLastX=0;
        redrawLastY=0;
        getObj("resultsarea").innerHTML=gResultsAreaHTML;
    }
    
	// handle the inset map
	// update inset values we might need later
	thisx= myMap.GetX(); 
	thisy= myMap.GetY();

		// calculate inset map coordinates 
		zm = myMap.GetTileZoom(); 
		thiszm = myMap.snaps[0]*2; 
		var goback = 4;  // number of snaps to go up 
		for (var l=goback;l<myMap.snaps.length;l++) { 
			if (myMap.snaps[l]==zm) thiszm = myMap.snaps[l-goback]; 
		} 

	if (InsetMap && myMap.GetTileZoom()<InsetMapCutoff) {
		CheckInsetMap();
		InsetMapObj.JumpTo(thisx, thisy, thiszm);
	}
	
	if (InsetMap && myMap.GetTileZoom()>InsetMapCutoff && InsetMapObj!=null) {
			MurderChildren(InsetTable);
			InsetMapObj=null;
	}
	

   
}


function ToggleInset()
{
	if (InsetMap) {
		// toggle off
		InsetMap = false;
		InsetToggle.innerHTML = "<img width=16 height=16 src='img/inset_open.gif' border=0>";
		MurderChildren(InsetTable);
		InsetMapObj=null;
		myMap.SetCopyrightXMargin(0);
		myMap.Init(true);
	} else {
		// toggle on
		InsetMap = true;
		MurderChildren(InsetToggle);
		myMap.SetCopyrightXMargin(105);
		myMap.Init(true);
	}
}


var InsetX=-1;
var InsetY=-1;

function InsetRedrawCallback(obj,x,y,source,forcemove)
{
	if (InsetX==-1 || InsetY==-1) {
		InsetX=x;
		InsetY=y;
	}
	
	if (InsetX!=x || InsetY!=y) {
		// inset map has been scrolled, move the main map accordingly
		myMap.Jump(x,y,myMap.GetTileZoom());
		myMap.Init(false);
	}

	InsetX=x;
	InsetY=y;
}


function AJAX_RouteLoad(dat)
{
	gWait.Stop();

	if (dat==null) return;
	if (dat.results.type!="routeload") {
	    alert("AJAX Error");
	    return;
	}

    for (l=0;l<dat.results.result.length;l++) {
        var item = dat.results.result[l];
        rdata = item.routedata;
        
        // create the route later
        slist = rdata.split("|");
        
				if (routeLayer==null) {
						routeLayer=myMap.AddLayer("multiroute",95,"multiroute");
				}
				if (routeLabelLayer==null) {
						routeLabelLayer=myMap.AddLayer("point",94,"routepoint");
				} else {
					routeLabelLayer.RemoveAllPoints();
				}
				// make up the list
				var rt = "";
				var minx=999;
				var maxx=-999;
				var miny=999;
				var maxy=-999;
        for (l=0;l<slist.length;l++) {
					if (rt.length>1) rt+=",";
					prm = slist[l].split(",");
					if (prm[0].length>1) {
						var pt = routeLabelLayer.AddPoint(prm[1]*1,prm[2]*1,prm[0],"searchmarker");
						if (prm[1]*1<minx) minx=prm[1]*1;
						if (prm[1]*1>maxx) maxx=prm[1]*1;
						if (prm[2]*1<miny) miny=prm[2]*1;
						if (prm[2]*1>maxy) maxy=prm[2]*1;
						pt.SetStyle("label")
						pt.SetIcon("/icon_small/0.png");
						pt.SetLabelAnchor("left","bottom");
					}
					rt += prm[1]+","+prm[2];
        }
				routeLayer.args1 = rt;
				
				// recenter the map
				var nscale=0.01;
				if (maxx-minx > maxy-miny) nscale = maxx-minx;
					else nscale=maxy-miny;
				nscale/=(myMap.nCtrlWidth/myMap.nTileSize);
				nscale*=1.5;
				var cenx = (maxx+minx)/2;
				var ceny = (maxy+miny)/2;
				myMap.JumpTo(cenx,ceny,myMap.FindZoom(nscale));
				myMap.Init();
    }
}






function CTree(ctrl, treedata)
{
	this.ctrl = ctrl;
	this.tdata = treedata;
	this.LeafCallback = null;
	this.NonLeafCallback = null;
	this.LeafShowCallback = null;
	this.DrawEndCallback = null;
	this.DrawBeginCallback = null;
	
	for (var l=0;l<this.tdata.length;l++) {
		this.tdata[l].parent = this;
	}

	this.SetupTree(1);
	this.Redraw();

}



CTree.prototype.Redraw = function()
{
	if (this.DrawBeginCallback!=null) this.DrawBeginCallback(this);

	for(var l=0;l<this.tdata.length;l++)
		this.tdata[l].arrayplace=l;

  var vTable = SetupScroller(this.ctrl);
	for (var l=0;l<this.tdata.length;l++) {

		if (this.tdata[l].visible) {
			var vRow = vTable.insertRow(-1);
				vRow.vAlign = "middle";

			for (var ind=0;ind<this.tdata[l].level;ind++) {
				var vCell = vRow.insertCell(-1);
					vCell.style.width = "8px";
			}

				var vCell = vRow.insertCell(-1);
				vCell.colSpan = 10 - this.tdata[l].level;
				var htm;
				if (this.tdata[l].isHeading) {
					vCell.className = "tree_heading";
					htm = "<img src='"+this.tdata[l].icon+"' style='vertical-align:middle;'> " + this.tdata[l].heading + "&nbsp;("+this.LeafCount(l)+")";
				} else {
					vCell.className = "tree_leaf";
					htm = "<img src='"+this.tdata[l].icon+"' style='vertical-align:middle;'> " + this.tdata[l].heading;
					if (this.LeafShowCallback!=null) LeafShowCallback(this.tdata[l]);
				}
				vCell.innerHTML = htm;

				if (this.tdata[l].clickhandler.length) 
					vCell.onclick = associateObjWithEvent(this.tdata[l], this.tdata[l].clickhandler);

				this.tdata[l].hotarea = vCell;
				if (this.tdata[l].isHeading)
					vRow.onclick = associateObjWithEvent(this.tdata[l], "ClickNode");
				else
					vRow.onclick = associateObjWithEvent(this.tdata[l], "ClickLeaf");
		 }
	}

	if (this.DrawEndCallback!=null) this.DrawEndCallback(this);
}



CTree.prototype.SetupTree = function (expandlev)
{
	for (var l=0;l<this.tdata.length;l++) {
		if (this.tdata[l].level<=expandlev) {
			this.tdata[l].visible = true;
		} else {
			this.tdata[l].visible = false;
		}

		if (this.tdata[l].level<=expandlev-1) {
			this.tdata[l].expanded = true;
		} else {
			this.tdata[l].expanded = false;
		}

	}
}


CTree.prototype.LeafCount = function(start)
{
	var level = this.tdata[start].level;
	var place = start+1;
	var leafcount = 0;
	while (place<this.tdata.length && this.tdata[place].level>level) {
		if (!this.tdata[place].isHeading) leafcount++;
		place++;
	}
	return leafcount;
}


CTree.prototype.KillSubtree = function(start)
{
	var level = this.tdata[start].level;
	var place = start;
	count = 0;
	while (place<this.tdata.length && (this.tdata[place].level>level || count==0)) {
		var removed = this.tdata.splice(place,1);
		count++;
	}
	return 1;
}


CTree.prototype.TrimNoLeaf = function ()
{
	for (var l=0;l<this.tdata.length;l++) {
		if (this.tdata[l].isHeading) {
			var lc = this.LeafCount(l);
			if (lc==0) {
				// kill this node and children
				this.KillSubtree(l);
				l--;
			}
		}
	}
}


CTree.prototype.ExpandAll = function ()
{
	for (var l=0;l<this.tdata.length;l++) {
		this.tdata[l].expanded = true;
		this.tdata[l].visible = true;
	}
}



CTree.prototype.SetState = function (state)
{
	cmds = state.split(";");
	for (var l=0;l<cmds.length;l++) {
		var f = cmds[l].split("=");
		if (f[1]=="E") {
			// expanded

			var found=false;
			for (var loop=0;loop<this.tdata.length && !found;loop++) {
				if (this.tdata[loop].ref*1 == f[0]*1) {
					found = true;
					this.tdata[loop].expanded = true;
					node = this.tdata[loop];
					loop++;
					while (loop<this.tdata.length && this.tdata[loop].level > node.level) {
						if (this.tdata[loop].level==node.level+1) this.tdata[loop].visible = true;
						loop++;
					}
				}
			}

		}
	}
}


CTree.prototype.GetState = function ()
{
	var ret = "";
	for (var l=0;l<this.tdata.length;l++) {
		if (this.tdata[l].expanded) {
			if (ret.length>0) ret+=";";
			ret+=String(this.tdata[l].ref)+"=E";
		}
	}
	return ret;
}


CTree.prototype.AddEntryUnder = function(underref, itemheading, userdata)
{
	var pnode = -1;
	var seekinglevel = -1;
	var insertat = -1;

	for (var l=0;l<this.tdata.length && insertat==-1;l++) {
		if (seekinglevel >= 0 && insertat==-1 && this.tdata[l].level<=seekinglevel) {
			insertat = l;
		}
		
		if (this.tdata[l].ref==underref) {
			pnode=l;
			seekinglevel = this.tdata[l].level;
		}
	}

	if (pnode==-1) return null;
	var putat = -1;
	if (insertat==-1) {
		insertat = this.tdata.length;
		putat = insertat;
	} else {
			// find a place to insert this alphabetially
			putat = pnode+1;
			while (putat<insertat && itemheading.toLowerCase()>this.tdata[putat].heading.toLowerCase())
				putat++;
		}

	var newnode = new CTreeNode(-1,itemheading,this.tdata[pnode].level+1, false, this.tdata[pnode], userdata);
	newnode.parent = this;
	newnode.icon = IconName(userdata.icon);
	this.tdata.splice(putat,0,newnode);
	return newnode;
}



function IconName(iname)
{
if (iname==null) return "icon_small/0.png";
ret = "icons/" + iname + "_16.png";
return ret;

	var found = false;
	var node = ofnode;
	do {
		for (var l=0;l<IconsAvailable.length;l++) {
			if (IconsAvailable[l]==node.ref) found=1;
		}
		
		if (!found) {
			node = node.pathup;
		}
		
	} while (!found && node!=null);
	
	if (node==null) {
		return "icon_small/0.png"
	} else {
		return "icon_small/"+node.ref+".png"
	}
}


function TreeRec(data, level, tdata, pathup, entrydata)
{
	var aTxt = data[0].split(":");
	var node0 = new CTreeNode(aTxt[1]*1,aTxt[0],level, true, pathup, entrydata);
  node0.icon=IconName(entrydata?entrydata.icon:null);
	node0.arrayplace = tdata.length;
	tdata.push(node0);

	for (var l=1;l<data.length;l++) {
		if (isArray(data[l])) {
			tdata = TreeRec(data[l], level+1, tdata, node0);
		}
		

		if (isString(data[l])) {
			var aTxt = data[l].split(":");
			if (aTxt.length==3) {
				node = new CTreeNode(aTxt[2]*1,aTxt[1],level+1, true, node0, entrydata);
				node.icon = IconName(entrydata?entrydata.icon:null);
			} else {
				node = new CTreeNode(aTxt[1]*1,aTxt[0],level+1, true, node0, entrydata);
				node.icon = IconName(entrydata?entrydata.icon:null);
			}
			node.arrayplace = tdata.length;
			tdata.push(node);
		}
	}
	return tdata;
}

function CTreeNode(ref, heading, level, isHeading, pathup, entrydata)
{
	this.ref = ref;
	this.heading = heading;
	this.level = level;
	this.isHeading = isHeading;
	this.expanded = false;
	this.visible = false;
	this.arrayplace = -1;
	this.parent = null;
	this.icon = "";
	this.pathup = pathup;
	this.clickhandler = "";
	this.entrydata = entrydata;
}



CTreeNode.prototype.ClickLeaf = function(event, element)
{
	if (this.parent.LeafCallback != null && !this.isHeading) {
		this.parent.LeafCallback(this.parent,this);
	}
}


CTreeNode.prototype.ClickNode = function(event, element)
{
	var loop = this.arrayplace+1;

	if (this.expanded) {
		this.expanded = false;
		while (loop<this.parent.tdata.length && this.parent.tdata[loop].level>this.level) {
			this.parent.tdata[loop].visible = false;
			this.parent.tdata[loop].expanded = false;
			loop++;
		}
	} else {
		this.expanded = true;
		while (loop<this.parent.tdata.length && this.parent.tdata[loop].level > this.level) {
			if (this.parent.tdata[loop].level==this.level+1) this.parent.tdata[loop].visible = true;
			loop++;
		}
	}

	if (this.parent.NonLeafCallback != null && this.isHeading) {
		this.parent.NonLeafCallback(this.parent,this);
	}
	
	this.parent.Redraw();
}



function UpdateCoordinate()
{
  // points for the overlay layer
  if (scratchLayer==null) {
      scratchLayer = myMap.AddLayer("point",80,"points");
      scratchLayer.SetDefaultAnchor("center","center");
  }
  scratchLayer.DeletePoint("coordinates");
  var caption = "<b>Selected Coordinates</b><p>X: "+getObj("c_deg_x").value+"<br>Y: "+getObj("c_deg_y").value;
	var pt = scratchLayer.AddPoint(getObj("c_deg_x").value*1, getObj("c_deg_y").value*1, caption, "coordinates");
	pt.SetStyle("biglabel")
	pt.SetIcon("icon_small/0.png");
	pt.SetLabelAnchor("iconcenter","iconcenter");
	pt.SetIconAnchor("center","center");
	myMap.Init(false);
}


function JumpFrom(num)
{
	ConvertFrom(num);

	myMap.JumpTo(getObj("c_deg_x").value*1, getObj("c_deg_y").value*1, 0.005);
	
	UpdateCoordinate();
}
	
function Ten(num)
{
	if (num<10) return "0" + String(num);
		else return String(num);
}

function ClearCoords(num)
{
	getObj("c_deg_x").value = "";
	getObj("c_deg_y").value = "";
	getObj("c_dms_x1").value = "";
	getObj("c_dms_y1").value = "";
	getObj("c_dms_x2").value = "";
	getObj("c_dms_y2").value = "";
	getObj("c_dms_x3").value = "";
	getObj("c_dms_y3").value = "";
	getObj("c_gps_x1").value = "";
	getObj("c_gps_y1").value = "";
	getObj("c_gps_x2").value = "";
	getObj("c_gps_y2").value = "";
}

	
function ConvertFrom(num)
{
	// convert to decimal
	var xv=0;
	var yv=0;
	switch (num) {
		case 1 :
			xv = getObj("c_deg_x").value * 1;
			yv = getObj("c_deg_y").value * 1;
			break;
		case 2 :
			xv = getObj("c_dms_x1").value * 1 + getObj("c_dms_x2").value / 60 + getObj("c_dms_x3").value / (60*60);
			ysgn = getObj("c_dms_y1").value*1 < 0?-1:1;
			yv = getObj("c_dms_y1").value * 1 + ysgn*getObj("c_dms_y2").value / 60 + ysgn*getObj("c_dms_y3").value / (60*60);
			break;
		case 3 :
			xv = getObj("c_gps_x1").value * 1 + getObj("c_gps_x2").value / 60;
			ysgn = getObj("c_gps_y1").value*1 < 0?-1:1;
			yv = getObj("c_gps_y1").value * 1 + ysgn*getObj("c_gps_y2").value / 60;
			break;
	}
	
	// convert to the others
	getObj("c_deg_x").value = xv.toFixed(6);
	getObj("c_deg_y").value = yv.toFixed(6);

	ysgn = yv<0?-1:+1;
	xsgn = xv<0?-1:+1;
	
	xd = Math.floor(xv);
	yd = Math.floor(Math.abs(yv))*ysgn;
	xm = (xv-xd)*60;
	ym = Math.abs(yv-yd)*60;
	xs = ((xv-xd)*60-Math.floor(xm))*60;
	ys = (Math.abs(yv-yd)*60-Math.floor(ym))*60;

	getObj("c_dms_x1").value = Math.floor(xd);
	getObj("c_dms_x2").value = Ten(Math.floor(xm));
	getObj("c_dms_x3").value = Math.floor(xs);
	getObj("c_dms_y1").value = Math.floor(yd);
	getObj("c_dms_y2").value = Ten(Math.floor(ym));
	getObj("c_dms_y3").value = Math.floor(ys);
	
	getObj("c_gps_x1").value = Math.floor(xd);
	getObj("c_gps_x2").value = (Math.floor(xm) + xs/60).toFixed(4);
		if ((Math.floor(xm) + xs/60)<10) getObj("c_gps_x2").value = "0" + getObj("c_gps_x2").value;
	getObj("c_gps_y1").value = Math.floor(yd);
	getObj("c_gps_y2").value = (Math.floor(ym) + ys/60).toFixed(4);
		if ((Math.floor(ym) + ys/60)<10) getObj("c_gps_y2").value = "0" + getObj("c_gps_y2").value;
}


function ajaxlog(url)
{
			callObj = new JSONscriptRequest(url);
			callObj.Go(false);
}


function ToggleLink()
{
	var lp = getObj("link_div")
	if (lp.style.visibility=="hidden")
		lp.style.visibility="visible";
	else 
		lp.style.visibility="hidden"
}

function Resize()
{
	// center the temp point popup window
	MurderChildren(InsetTable);
	InsetMapObj=null;

	var tp = getObj("tpoint_div");
	tp.style.left = PX( GetWindowSize("w")/2 - tp.clientWidth/2 );
	tp.style.top = PX( GetWindowSize("h")/2 - tp.clientHeight/2 );
	
	// position the link box
	var lp = getObj("link_div")
	var la = getObj("action_link")
	lft = getAbsoluteLeft(la) - lp.clientWidth/2 + la.clientWidth/2;
	if (lft + lp.clientWidth > GetWindowSize("w")-16) lft = GetWindowSize("w")-lp.clientWidth-16;
	lp.style.left = PX(lft);
	lp.style.top = PX(getAbsoluteTop(la) + la.clientHeight);

	myMap.Init(true);
}


function PopupMenuCallback(obj,selected,x,y)
{
	if (selected=="user.photo") {
	    Global_UserPhoto(obj,x,y);
	}
	
	if (selected=="zoom.street") {
		obj.JumpTo(x,y, 0.005);
	}

	if (selected=="poi.add") {
		Global_POI(obj,x,y);
	}

	if (selected=="placemarker.add") {
		getObj("tpoint_x").value=x;
		getObj("tpoint_y").value=y;
		getObj("tpoint_div").style.visibility="visible";
		getObj("tpoint_label").focus();
	}

	if (selected=="placemarker.remove") {
		RememberPoints.splice(0,RememberPoints.length);
		TempPoints.splice(0,RememberPoints.length);
		TPoint_SaveCookie();
		TPoint_DrawLayer();
	}
}

function TempPoint(x,y,label)
{
	this.x = x;
	this.y = y;
	this.label = label;
}

function TPoint_DrawLayer()
{
	if (TPoint_Layer==null) {
		TPoint_Layer = myMap.AddLayer("point",50,"route");
	}
	TPoint_Layer.RemoveAllPoints();

	for (var l=0;l<RememberPoints.length;l++) {
		var pt = TPoint_Layer.AddPoint(RememberPoints[l].x, RememberPoints[l].y, "<b>"+RememberPoints[l].label+"</b><p>(Your Personal Placemarker)<br><span style='color:blue;text-decoration:underline;cursor:pointer;' onclick='TPoint_Remove("+String(l)+");'>Remove Placemarker</span>", "tp");
		pt.SetStyle("label")
		pt.SetIcon("icon_small/0.png");
		pt.SetLabelAnchor("iconcenter","iconcenter");
	}
	
	for (var l=0;l<TempPoints.length;l++) {
		// make sure this point isnt in our remembered points
		var found=false;
		for (var l2=0;l<RememberPoints.length;l++) {
			if (RememberPoints[l2].x==TempPoints[l].x && RememberPoints[l2].y==TempPoints[l].y) found=true;
		}
		
		if (!found) {
			var pt = TPoint_Layer.AddPoint(TempPoints[l].x, TempPoints[l].y, "<b>"+TempPoints[l].label+"</b><br>&nbsp;<br>(Placemarker from Another User)", "tp");
			pt.SetStyle("biglabel")
			pt.SetIcon("icon_small/0.png");
			pt.SetLabelAnchor("iconcenter","iconcenter");
			pt.SetIconAnchor("center","center");
		}
	}

	myMap.Init(true);
}


function TPoint_SaveCookie()
{
	// save the points into a cookie
	remember = "";

  while (RememberPoints.length>5) {
      RememberPoints.splice(0,1);
  }
  
	for (var l=0;l<RememberPoints.length;l++) {
		if (l>0) remember+="$";
		var rp = RememberPoints[l];
		remember += rp.x.toFixed(6)+"|"+rp.y.toFixed(6)+"|"+rp.label
	}
	createCookie("points",remember,365);
}


function TPoint_Remove(num)
{
	RememberPoints.splice(num,1);
	TPoint_SaveCookie();
	TPoint_DrawLayer();
}



function TPoint_Accept()
{
	var tp = new TempPoint(getObj("tpoint_x").value*1, getObj("tpoint_y").value*1, getObj("tpoint_label").value);
	RememberPoints.push(tp);
	getObj("tpoint_div").style.visibility="hidden";
	TPoint_SaveCookie();
	TPoint_DrawLayer();
}


function TPoint_Cancel()
{
		getObj("tpoint_div").style.visibility="hidden";
		getObj("tpoint_label").value="";
}


function RandomInt(max)
{
	return Math.floor(Math.random()*max);
}

function ShowMapTips()
{
	
	// choose 2 tips to display
	var tip1 = RandomInt(MapTips.length);
	
	getObj("tip_area_1a").innerHTML = MapTips[tip1].tip_title;
	getObj("tip_area_1b").innerHTML = MapTips[tip1].tip_text;

}

// show the map tips
ShowMapTips();

myMap = new CAatMap();
//myMap.SetDebug();
myMap.SetCopyright("&copy; 2006-2008");

myMap.SetBranding("img/is.png",64,27,"In Association with Internet Solutions","http://www.is.co.za");

myMap.SetOutput("map1");
myMap.AddLayer("map",100);
myMap.SetPopupMenu(true);
myMap.bShowProgress = true;

var qs = new Querystring();
var x = qs.get("x","24.75");
var y = qs.get("y","-28.5");
var z = qs.get("z","0");
var s = qs.get("s","m");
var p = qs.get("p","0");
var r = qs.get("r","");
var rt = qs.get("rt","");
var tp = qs.get("tp","");


// check if we have any temporary points .. don't add them to our list if there are, just show them
if (tp.length>0) {
	var tparr = URLDecode(tp).split("$");
	for (var l=0;l<tparr.length;l++) {
		var ent = tparr[l].split("|");
		var tp = new TempPoint(ent[0]*1, ent[1]*1, Safe(ent[2]));
		TempPoints.push(tp);
	}
	TPoint_DrawLayer();
}

if (p=="1") gPoints=true;
if (s=="h") myMap.doControlHybrid();
if (s=="s") myMap.doControlSatellite();

sectionchange(sections[0]);

if (rt!="") {
	// got a user route
	lurl = "route/ajax_routeload.asp?id="+rt;
  AjaxRequest.get({
       'url':lurl
      ,'onSuccess':AJAX_RouteLoad
            ,'groupName':'points'
            ,'onGroupBegin':function(req) { gWait.Start(); }
            ,'onGroupEnd':function(req) { gWait.Stop(); }
            ,'onError':function(req) { AJAX_Error("points"); }
   });
}

if (r!="") {
	// got a route
	rs = r.split(",");
	if (rs.length==4) {
		routeStartX = rs[0]*1;
		routeStartY = rs[1]*1;
		routeEndX = rs[2]*1;
		routeEndY = rs[3]*1;
		myMap.CalcRoute(routeStartX, routeStartY, routeEndX, routeEndY, myMap);
	}
}



window.onresize = Resize;

//ShowDatabase("d.database","",direc,'direc');

myMap.Jump(x,y,z);

myMap.ClickCallback=ClickCallback;
myMap.RedrawCallback=RedrawCallback;
myMap.PopupMenuCallback=PopupMenuCallback;
myMap.AJAX_Status_Callback=AJAX_Status_Callback;

Resize();
if (RememberPoints.length>0 || TempPoints.length>0) TPoint_DrawLayer();



function set_opacity(div, val) {
	if (div==null) return;
  if (div.filters) {  //For IE
    val *= 100;
    try {
      div.filters.item("DXImageTransform.Microsoft.Alpha").opacity = val;
    } catch (e) { 
      // If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
      div.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity='+val+')';
    }
  } else {
    div.style.opacity = val;
    div.style.MozOpacity = val;  //This is for older Mozilla Browsers
  }
} 

var fadeDiv = null;
var fadeTransparency = 0;

function FadeUpdate()
{
	if (fadeDiv==null) return;
	
	fadeTransparency-=0.1;
	if (fadeTransparency<1) {
		set_opacity(fadeDiv,fadeTransparency);
	}
	
	if (fadeTransparency<=0) {
		document.body.removeChild(fadeDiv);
		fadeDiv=null;
	} else {
		setTimeout("FadeUpdate()",100);
	}
}

function ShowFadeDiv(container, caption) 
{
	if (fadeDiv!=null) {
		document.body.removeChild(fadeDiv);
	}
	
	fadeDiv = document.createElement("div");
	fadeDiv.width=100;
	fadeDiv.height=100;
	fadeDiv.innerHTML=caption;
	fadeDiv.style.position = "absolute";
	fadeDiv.zOrder=1000;
	document.body.appendChild(fadeDiv);
	fadeDiv.style.border = "1px solid black";
	fadeDiv.style.top = YAbsolute(25, container);
	fadeDiv.style.left = XAbsolute(( container.clientWidth - fadeDiv.clientWidth)/2 - 8 , container );
	fadeDiv.width=100;
	fadeTransparency=3;
	set_opacity(fadeDiv,0.99);
	setTimeout("FadeUpdate()",100);
}


function FadeCaption(caption)
{
	var ret = "";
	ret += "<table cellpadding=4 cellspacing=0 bgcolor=red><tr><td style='color:white;font-weight:bold;font-size:12px;'>"+caption+"</td></td></table>";
	return ret;
}
	

var pulseDiv = null;
var pulseCycle = 0;
var pulseTicker = 0;

function PulseUpdate()
{
	if (pulseDiv==null) return;
	pulseTicker++;
	var fadeamt = pulseTicker<10? pulseTicker/10 : (20-pulseTicker)/10;
	set_opacity(pulseDiv,fadeamt);	
	if (pulseTicker>20) {
		pulseTicker=0;
		pulseCycle++;
	}
	if (pulseCycle<3) {
		setTimeout("PulseUpdate()",100);
	} else {
		document.body.removeChild(pulseDiv);
		pulseDiv=null;
	}
}

function PulsePoints()
{
	var ob = getObj("userctrl_points");
	if (ob!=null) {
		if (pulseDiv!=null) {
			document.body.removeChild(pulseDiv);
		}

		pulseDiv = ob.cloneNode(false);
		pulseDiv.onclick = associateObjWithEvent(myMap, "doPoints");
		pulseDiv.style.left = XContainerToDoc(unPX(pulseDiv.style.left)*1, myMap.cContainer);
		pulseDiv.style.top = YContainerToDoc(unPX(pulseDiv.style.top)*1, myMap.cContainer);
		pulseDiv.style.zIndex = ob.style.zIndex+1;
		document.body.appendChild(pulseDiv);
		html = PNG(myMap.sImageBase+"icons.png",19,78,"Turn Places On and Off",114,171,'userctrl_points_pulse');
		pulseDiv.innerHTML=html;

		pulseCycle = 0;
		pulseTicker = 0;
		setTimeout("PulseUpdate()",100);
	}
}


var oldbrowser_y=0;
var oldbrowser_timer=null;
// check for old browser


if (BrowserDetect.browser=="Explorer" && BrowserDetect.version<7 ) {
	var ob = getObj("oldbrowser");
	ob.style.visibility="visible";
	oldbrowser_timer=setTimeout("oldbrowser_off();",20000);
}
	
function oldbrowser_off()
{
	var ob = getObj("oldbrowser");
	if (oldbrowser_timer!=null) {
		clearTimeout(oldbrowser_timer);
	}

	if (oldbrowser_y + unPX(ob.style.height)*1 > -8) {
		setTimeout("oldbrowser_off()",50);
		oldbrowser_y--;
		ob.style.top=oldbrowser_y;
	} else {
		ob.style.visibility="hidden";
	}
}
	
Object.prototype.Promote = function(event, element)
{
	window.open('http://www.streetmaps.co.za/poi','promote','') 
}

var NameChanges_div = null;

function DoNameChangesClose()
{
	if (NameChanges_div==null) return;
	
	MurderChildren(NameChanges_div);
	document.body.removeChild(NameChanges_div);
	
	NameChanges_div=null;
}

Object.prototype.NameChangesClose = function(event, element)
{
	DoNameChangesClose();
}

Object.prototype.NameChanges = function(event, element)
{
	DoNameChangesClose();
	
    var vCell, vRow, vTable;
    var vDiv = document.createElement("div");
    	vDiv.className = "nchange";
    vDiv.style.position="absolute";
    vDiv.style.left=10;
    vDiv.style.top=10;
    vTable = document.createElement("table");
    	vTable.cellPadding=3;
    	vTable.cellSpacing=0;
    	vTable.style.border="2px solid black";

    	vDiv.appendChild(vTable);
    	vRow = vTable.insertRow(-1);
    	var vCell = vRow.insertCell(-1);
    		vCell.colSpan = 2;
	    	vCell.innerHTML="Road Name Changes";
	    	vCell.className = "nchange_header"

    	vDiv.appendChild(vTable);
    	vRow = vTable.insertRow(-1);
    	var vCell = vRow.insertCell(-1);
	    	vCell.innerHTML="Old Name";
	    	vCell.className = "nchange_rowhead"
	    vCell = vRow.insertCell(-1);
	    	vCell.innerHTML="New Name"
	    	vCell.className = "nchange_rowhead"
	    	
	  for (cl=0;cl<this.length;cl++) {
    	vRow = vTable.insertRow(-1);
    	var vCell = vRow.insertCell(-1);
	    	vCell.innerHTML=this[cl][0];
	    	vCell.className = "nchange_row"
	    vCell = vRow.insertCell(-1);
	    	vCell.innerHTML=this[cl][1];
	    	vCell.className = "nchange_row"
	  }
	  
	  vRow = vTable.insertRow(-1);
    vCell = vRow.insertCell(-1);
    	vCell.innerHTML=" ";
    	vCell.style.height=16;

  	vDiv.appendChild(vTable);
  	vRow = vTable.insertRow(-1);
  	var vCell = vRow.insertCell(-1);
  		vCell.colSpan = 2;
    	vCell.innerHTML="Click here to close";
    	vCell.className = "nchange_footer"
    	vCell.onclick = associateObjWithEvent(this, "NameChangesClose");
	    	
    document.body.appendChild(vDiv);
    NameChanges_div = vDiv;
    
    // now center this
    CenterElement(vDiv);
}
