// Ajax and Javascript code written by Simon Densley at Grouptree for NCP
// Some sections adjusted from multimap examples
// Copyright 2007



/***************************************************************/
//initialization, browser, os detection
var d, dom, nu='', brow='', ie, ie4, ie5, ie5x, ie6, ie7;
var ns4, moz, moz_rv_sub, release_date='', moz_brow, moz_brow_nu='', moz_brow_nu_sub='', rv_full=''; 
var mac, win, old, lin, ie5mac, ie5xwin, konq, saf, op, op4, op5, op6, op7;

d=document;
n=navigator;
nav=n.appVersion;
nan=n.appName;
nua=n.userAgent;
old=(nav.substring(0,1)<4);
mac=(nav.indexOf('Mac')!=-1);
win=( ( (nav.indexOf('Win')!=-1) || (nav.indexOf('NT')!=-1) ) && !mac)?true:false;
lin=(nua.indexOf('Linux')!=-1);
// begin primary dom/ns4 test
// this is the most important test on the page
if ( !document.layers )
{
	dom = ( d.getElementById ) ? d.getElementById : false;
}
else { 
	dom = false; 
	ns4 = true;// only netscape 4 supports document layers
}
// end main dom/ns4 test

op=(nua.indexOf('Opera')!=-1);
saf=(nua.indexOf('Safari')!=-1);
konq=(!saf && (nua.indexOf('Konqueror')!=-1) ) ? true : false;
moz=( (!saf && !konq ) && ( nua.indexOf('Gecko')!=-1 ) ) ? true : false;
ie=((nua.indexOf('MSIE')!=-1)&&!op);
if (op)
{
	str_pos=nua.indexOf('Opera');
	nu=nua.substr((str_pos+6),4);
	brow = 'Opera';
}
else if (saf)
{
	str_pos=nua.indexOf('Safari');
	nu=nua.substr((str_pos+7),5);
	brow = 'Safari';
}
else if (konq)
{
	str_pos=nua.indexOf('Konqueror');
	nu=nua.substr((str_pos+10),3);
	brow = 'Konqueror';
}
// this part is complicated a bit, don't mess with it unless you understand regular expressions
// note, for most comparisons that are practical, compare the 3 digit rv nubmer, that is the output
// placed into 'nu'.
else if (moz)
{
	// regular expression pattern that will be used to extract main version/rv numbers
	pattern = /[(); \n]/;
	// moz type array, add to this if you need to
	moz_types = new Array( 'Firebird', 'Phoenix', 'Firefox', 'Iceweasel', 'Galeon', 'K-Meleon', 'Camino', 'Epiphany', 'Netscape6', 'Netscape', 'MultiZilla', 'Gecko Debian', 'rv' );
	rv_pos = nua.indexOf( 'rv' );// find 'rv' position in nua string
	rv_full = nua.substr( rv_pos + 3, 6 );// cut out maximum size it can be, eg: 1.8a2, 1.0.0 etc
	// search for occurance of any of characters in pattern, if found get position of that character
	rv_slice = ( rv_full.search( pattern ) != -1 ) ? rv_full.search( pattern ) : '';
	//check to make sure there was a result, if not do  nothing
	// otherwise slice out the part that you want if there is a slice position
	( rv_slice ) ? rv_full = rv_full.substr( 0, rv_slice ) : '';
	// this is the working id number, 3 digits, you'd use this for 
	// number comparison, like if nu >= 1.3 do something
	nu = rv_full.substr( 0, 3 );
	for (i=0; i < moz_types.length; i++)
	{
		if ( nua.indexOf( moz_types[i]) !=-1 )
		{
			moz_brow = moz_types[i];
			break;
		}
	}
	if ( moz_brow )// if it was found in the array
	{
		str_pos=nua.indexOf(moz_brow);// extract string position
		moz_brow_nu = nua.substr( (str_pos + moz_brow.length + 1 ) ,3);// slice out working number, 3 digit
		// if you got it, use it, else use nu
		moz_brow_nu = ( isNaN( moz_brow_nu ) ) ? moz_brow_nu = nu: moz_brow_nu;
		moz_brow_nu_sub = nua.substr( (str_pos + moz_brow.length + 1 ), 8);
		// this makes sure that it's only the id number
		sub_nu_slice = ( moz_brow_nu_sub.search( pattern ) != -1 ) ? moz_brow_nu_sub.search( pattern ) : '';
		//check to make sure there was a result, if not do  nothing
		( sub_nu_slice ) ? moz_brow_nu_sub = moz_brow_nu_sub.substr( 0, sub_nu_slice ) : '';
	}
	if ( moz_brow == 'Netscape6' )
	{
		moz_brow = 'Netscape';
	}
	else if ( moz_brow == 'rv' || moz_brow == '' )// default value if no other gecko name fit
	{
		moz_brow = 'Mozilla';
	} 
	if ( !moz_brow_nu )// use rv number if nothing else is available
	{
		moz_brow_nu = nu;
		moz_brow_nu_sub = nu;
	}
	if (n.productSub)
	{
		release_date = n.productSub;
	}
}
else if (ie)
{
	str_pos=nua.indexOf('MSIE');
	nu=nua.substr((str_pos+5),3);
	brow = 'Microsoft Internet Explorer';
}
// default to navigator app name
else 
{
	brow = nan;
}
op5=(op&&(nu.substring(0,1)==5));
op6=(op&&(nu.substring(0,1)==6));
op7=(op&&(nu.substring(0,1)==7));
op8=(op&&(nu.substring(0,1)==8));
op9=(op&&(nu.substring(0,1)==9));
ie4=(ie&&!dom);
ie5=(ie&&(nu.substring(0,1)==5));
ie6=(ie&&(nu.substring(0,1)==6));
ie7=(ie&&(nu.substring(0,1)==7));
// default to get number from navigator app version.
if(!nu) 
{
	nu = nav.substring(0,1);
}
/*ie5x tests only for functionavlity. dom or ie5x would be default settings. 
Opera will register true in this test if set to identify as IE 5*/
ie5x=(d.all&&dom);
ie5mac=(mac&&ie5);
ie5xwin=(win&&ie5x);
/***************************************************************/


var mapviewer;
var searcher, markers, search;
//var browse_url = 'http://www.multimap.com/clients/browse.cgi?client=ncp_api_12&rt=browse.json';
var browse_url = 'http://classic.multimap.com/clients/browse.cgi?client=ncp_api_12&rt=browse.json';

var CarParkDBInfo_url = "GTGetCarParksInfo.aspx";
var max_zindex = 1000;
var FLatInp, FLonInp, FScaleInp, FPosLat, FPosLon, FPosPC;
var lvLat, lvLon, lvScale, lvPosLat, lvPosLon;
var rfs = ['name', 'street', 'town','pc', 'lat', 'lon', 'carpark_id'];
var CarParkIDs;
var req; 
var ClosestCP = "";
var AllRecs;
var MarkerLocs;
var IsMerelyAddingCarParks = false;
var CurrentZoomBtn;
var IciMarker;
var route_finder;
var ICIIconPath = 'public/images/ncp/Multimap/youarehere.gif';
var NCPIconPath = 'public/images/ncp/Multimap/NCP.gif';
var inRouteMode = false
var wasRouteMode = false
var ToCP
var FIsFirstSearch = true
var FNextLat, FNextLon
var FRouteNCP
var ClosestLat, ClosestLon
var OrigRoutLocElm, OrigRouteTypeElm
var OrigRoutLoc, OrigRouteType



// *** Event handlers ***

function onLoad() 
{ 
     
    FLatInp = document.getElementById('inplat')
    FLonInp = document.getElementById('inplon') 
    FScaleInp = document.getElementById('inpScale')
    FPosLat = document.getElementById('inposlat')
    FPosLon = document.getElementById('inposlon') 
    FPosPC = document.getElementById('inpospc')
    
    var ARadBtn
    OrigRoutLocElm = document.getElementById('txtEdtSearchRoute')
    ARadBtn =document.getElementById('radpostcodert')
    if (ARadBtn.checked)
    {
        OrigRouteType = "Post code"
    }
    ARadBtn =document.getElementById('radtownrt')
    if (ARadBtn.checked)
    {
        OrigRouteType = "Town"
    }
    ARadBtn =document.getElementById('radstreetrt')
    if (ARadBtn.checked)
    {
        OrigRouteType = "Street"
    }
    
    
    
    OrigRouteTypeElm = document.getElementById('SelRoute')
    OrigRoutLoc = OrigRoutLocElm.value
    
    lvlat = FLatInp.value;
    lvlon = FLonInp.value;  
    FNextLat = lvlat;
    FNextLon = lvlon;  
    
    lvScale = 15
    
    var psn = new MMLatLon( lvlat , lvlon  );
    var lcn = new MMLocation ( psn, lvScale); 
    
    mapviewer = new MultimapViewer( document.getElementById( 'mapimagediv' ) );
    mapviewer.drawAndPositionMap( lcn );
    SetZoomBtns(lvScale)
    
    lvPosLat = lvlat; 
    lvPosLon = lvlon; 

    if (FPosLat.value != "")
    {
        lvPosLat = FPosLat.value; 
        lvPosLon = FPosLon.value; 
        actAfterGotLatLon();
    }
    else
    {
        if (FPosPC.value != "")
        {
            geocoder = new MMGeocoder(actGetLatLon);
            var address = new MMAddress();
            address.street = "";
            address.city = "";
            address.state = "";
            address.postal_code = FPosPC.value;
            address.country_code = "GB";
            address.qs = "";
            geocoder.geocode(address);        
        }
        else
        {
            actAfterGotLatLon();
        }
    }
    
    mapviewer.addEventHandler( 'click', AfterClick );
    mapviewer.addEventHandler( 'changeZoom', AfterZoom );   
    mapviewer.addEventHandler( 'endPan', AfterPan ); 
    
    MarkerLocs = new Array();
  	markers = new Array();
}

function AfterPan (eventType, eventTarget, arg1, arg2, arg3)
{
    if (arg3 != 'goToPosition' && (!inRouteMode || wasRouteMode)) 
    {      
        FNextLat =arg2.lat;
        FNextLon =arg2.lon;

        IsMerelyAddingCarParks = true

        initSearch('', '', '', FNextLat, FNextLon);
    }
    else if (inRouteMode)
    {
    // do nothing
    }
    wasRouteMode = false
    return false;
}


function AfterClick(eventType, eventTarget, arg1, arg2, arg3 )
{
    if(!arg1) // is therefore a marker, not just a click on the map
    {
        if (eventTarget == IciMarker) 
        {
           
            FNextLat =lvPosLat
            FNextLon = lvPosLon
            initSearch('', '', '', lvPosLat, lvPosLon);  
        }    
        else
        {
            var lvCoords = actGetMarkerCoords(eventTarget)
            if (lvCoords) 
            {
                
                FNextLat =lvCoords.lat
                FNextLon = lvCoords.lon
                
                initSearch('', '', '', FNextLat, FNextLon);  
            }
            else {return false;}
        }
    
    }
    return false;   
}

function AfterZoom (eventType, eventTarget, arg1, arg2, arg3)
{
    SetZoomBtns(arg2)
}
    
function FlagClicked()
{
    initSearch('', '', '', lvlat, lvlon);
}

function GoToMapOrigin()
{
    wasRouteMode = inRouteMode
    inRouteMode = false
    mapviewer.goToPosition(new MMLatLon( lvPosLat , lvPosLon  ));
}

function AfterDetailsClick(inLat, inLon)
{
    FNextLat = inLat
    FNextLon = inLon
    
    initSearch('', '', '', FNextLat, FNextLon); 
    window.scrollTo(0,0) 
}


// *** First Line functions (called by event handlers) ***

function SetIci()
{
    var Iciicon = actGetIcon('X')
	var marker = mapviewer.createMarker( new MMLatLon(lvPosLat, lvPosLon), {'icon' : Iciicon});
	return marker; 
}

function actGetLatLon()
{
    results = geocoder.result_set;

    lvPosLat = results[0].coords.lat;
    lvPosLon = results[0].coords.lon;

    actAfterGotLatLon();
    return false;    
}

function actAfterGotLatLon()
{
    IciMarker = SetIci()
    initSearch('', '', '', lvPosLat, lvPosLon);  
    return false;   
}


function SetZoomBtns(inZoomNdx)
{
    var ZmID = "zm" + inZoomNdx
    var NewZoomBtn = document.getElementById(ZmID)
    var CurrentZoomImg
    
    if (CurrentZoomBtn != NewZoomBtn)
    {
        if (CurrentZoomBtn)
        {   
            CurrentZoomImg = "public/images/ncp/zoom/" + CurrentZoomBtn.getAttribute("value") + ".gif";   
            CurrentZoomBtn.setAttribute("src", CurrentZoomImg);
        }
        if (NewZoomBtn) 
        {
            NewZoomBtn.setAttribute("src", "public/images/ncp/zoom/zs.gif");
            CurrentZoomBtn = NewZoomBtn
        }
    }    
}


// *** Deep Logic ***

function initSearch (street, town, pc, inlat, inlon) 
{
    CarParkIDs = ''

    searcher = new MMSearchRequester( resultsLoaded );
    search = new MMSearch(); 
    search.return_fields = rfs;
    search.count = 30

    if (inlat && inlon)
    {
        var apoint = new MMLatLon(inlat, inlon);
	    search.point = apoint;   
    }
    else
    {
	    var address = new MMAddress();
	    address.street = street;
	    address.city = town;
	    address.postal_code = pc.value;
	    address.country_code = 'UK';
	    search.address = address;
    } 	    
    searcher.search( search );
    return false;
}  


function resultsLoaded ( ) 
{
    lvlat = FNextLat;
    lvlon = FNextLon;
        
    var container = document.getElementById('recordListDiv');
    ClosestCP = ""
    AllRecs = new Array();
    if(!IsMerelyAddingCarParks)
    {
	    actResetAllMarkers();
    }
    
    if (FRouteNCP) 
    {
        mapviewer.removeOverlay(FRouteNCP)
        FRouteNCP = null
    }
   	
    if ( searcher.error_code ) {
        var err =  '';
        if ( searcher.error_explanation ) {
            err =  searcher.error_explanation;
        } else {
            err =  'Your request failed. Error code: ' + searcher.error_code;
        }
        alert( err );
        return;
    } 
	
    var results_returned = 1;
    var el = document.createElement ( 'ol' );
    el.id = 'recordList';
    var  start_index_value = 1;
    if  (search.start_index && Number (search.start_index) > 0 ) 
    {
        start_index_value = Number (search.start_index);
        el.start = Number (start_index_value);
    }        
	     
	    // for each record set
	if (searcher.record_sets)
	{
	    for ( var count=0, l = searcher.record_sets.length; count < l; count++ ) 
	    { // for each record	        
	        if ( searcher.record_sets[count].error ) 
	        {
	            var err =  '';
	            if ( searcher.record_sets[count].error.error_explanation ) 
	            {
	                err =  searcher.record_sets[count].error.error_explanation;
	            } else 
	            {
	                err =  'Your request failed. Error code: ' + searcher.record_sets[count].error.error_code;
	            }
	            alert( err );
	            return;  
	        } 
	
	        if ( searcher.record_sets[count].records) 
	        {
	           
	            for (var record_count = 0, rl = searcher.record_sets[count].records.length; record_count < rl; record_count++ ) 
	            {
	                var record = searcher.record_sets[count].records[record_count];      
	                handleRecord(record, start_index_value + record_count);
	                if (record_count==0) 
	                {
	                    ClosestCP = record.name
	                }
	                AllRecs.push(record)
	            }
	            
	        } else 
	        {
	        
	            var total = searcher.record_sets[count].totalRecordCount; 
	            el = document.createElement ('p');
	            if ( total  > 0) 
	            {
	                el.appendChild ( document.createTextNode( 'Total results found: ' + total ) );
	            } else {
	                el.appendChild ( document.createTextNode( 'No results returned' ) ); 
	            }  
	            results_returned = 0;
	        }	        
	    }
    }
	    
       
    if (!IsMerelyAddingCarParks) 
    {
        mapviewer.goToPosition(new MMLatLon( lvlat , lvlon  ));
        if (typeof XMLHttpRequest != "undefined") 
        {
            req = new XMLHttpRequest();  
        } 
        else if (window.ActiveXObject) 
        {    
            req = new ActiveXObject("MSxml2.XMLHTTP");
            if (req = "undefined")
            {
                req = new ActiveXObject("Microsoft.XMLHTTP");
            } 
        }

        var svr =location.protocol + "//" + location.host + "/" + CarParkDBInfo_url    
        req.open("GET", svr + '?ids='+ CarParkIDs, true)
        req.onreadystatechange = actShowDets;
        req.send(null);
    
    } 
    IsMerelyAddingCarParks = false;  
    if (MarkerLocs)
    {
        if (FIsFirstSearch && MarkerLocs[0]) 
        {
            if (MarkerLocs[0].lat != lvlat || MarkerLocs[0].lon != lvlon)
            {
                lvlat = MarkerLocs[0].lat
                lvlon = MarkerLocs[0].lon
                mapviewer.goToPosition(new MMLatLon( lvlat , lvlon  ));
            }
            FIsFirstSearch = false
        } 
    }
    return false;    
}
		
		
function handleRecord ( record, num ) 
{
	var markerText = '<h1>Result #' + num + '<' + '/h1>'; 
	markerText += '<p>';  
	for ( i = 0, j=0; i < rfs.length; i++ ) 
	{
	    if ( record[rfs[i]] )
	    {
	        if ( j > 0) markerText += ', ';
	        markerText += record[rfs[i]];
	        j++;
	    }
	}
	markerText += '<' + '/p>';  
	markerText += actGetDistanceText(record)

    if ( record.point ) 
    {
        var ll = new MMLatLon(record.point.lat, record.point.lon)
        var isFeatured = (!IsMerelyAddingCarParks && num <= 10 && (num <= 4 || record.distance.km < 5))  
               
        var marker = createMarker(ll , num, isFeatured);
        if (isFeatured)
        {
            var pkid = parseInt(record.carpark_id)
            CarParkIDs += (',' + pkid);
            if (num == 1)
            {
                ClosestLat = ll.lat
                ClosestLon = ll.lon
            }
            
        }
        actReplaceMarkerAtPositionOrAdd(marker, ll)
    } 	    	
}
	
	
function createMarker(loctn, num, inIsFeatured) 
{
    var icon  
    var Markertext  
    if (inIsFeatured)
    {
        icon = actGetIcon(num)
        ZNdx = 1000 - num;
        Markertext = ' '; // to indicate later that it is a featured marker
    }
    else
    {
        icon = actGetIcon('NCP')
        ZNdx = 0;
        Markertext = '';
    }

    var marker = mapviewer.createMarker(loctn, {zIndex : ZNdx, 'icon' : icon, 'text': Markertext});
    return marker;
}
		
function actShowDets()
{
    if (req.readyState == 4) 
        {       
        if (req.status == 200)  // only if "OK"
        {
            if (req.responseText != "")
            {
	        var NearName = document.getElementById('NearestCPName'); 
            var NearDets = document.getElementById('Litpanel1'); 
            var NearAdd = document.getElementById('Litpanel2'); 
            var OtherParks = document.getElementById('CarParkListPanel');

            var TheXML = req.responseXML  
            
            var CarParkData = TheXML.getElementsByTagName("carparks")[0];
             
            var DivMain =CarParkData.getElementsByTagName("closest")[0].getElementsByTagName("div_main")[0];
            var Nrst = document.createTextNode("Your nearest NCP - " + ClosestCP);
            NearName.replaceChild(Nrst, NearName.firstChild);
            
            var CPID = GetPlainText(DivMain.getElementsByTagName("div")[2]);
                      
	        var ThisRec = actGetRecordFromID(AllRecs, CPID);	 
	               
	        NearDets.innerHTML = ""
	        var FixedCarPark = FixAllTags(FixCarPark(DivMain, true), ThisRec)
	        AddAppendedElement(NearDets, FixedCarPark)
	        
	        var Dist =actGetDistanceText(ThisRec)
	        NearDets.innerHTML = NearDets.innerHTML.replace("##distance##", Dist);
	        var AddDiv = DivMain.getElementsByTagName("div_additional")[0].getElementsByTagName("div")[0]
	        AddDiv.setAttribute("class", "bgYellow3 fl w520 mh15 mb1");
	        NearAdd.innerHTML = ""
	        var FixedAdrs = FixAllTags(AddDiv, ThisRec)
	        AddAppendedElement(NearAdd, FixedAdrs)
	        
	        OtherParks.innerHTML = '';          
	        var Apark;
	        var Others = CarParkData.getElementsByTagName("others")[0];
	        
	        for ( var count=0; count < Others.childNodes.length; count++ ) 
	        {
	            Apark =Others.getElementsByTagName("div_main")[count];     
	            if (Apark)
    	        {
        	        CPID = GetPlainText(Apark.getElementsByTagName("div")[2]); //.textContent; 
	                ThisRec = actGetRecordFromID(AllRecs, CPID);	
	                Dist =actGetDistanceText(ThisRec)
    	            var CarParkInfo = FixAllTags(FixCarPark(Apark, false), ThisRec);
	                	                      
	                AddAppendedElement(OtherParks, CarParkInfo)
	               // OtherParks.appendChild(CarParkInfo)	                	                      
	                OtherParks.innerHTML = OtherParks.innerHTML.replace("##distance##", Dist);   	            
	            }
	        }
	        }
        } 
        else 
        {
            alert("There was a problem retrieving data: " + req.statusText);
        }    
    }	
}
        
function GetLatLonText(ARec)
{
    return ARec.point.lat + ', ' + ARec.point.lon
}
		
function FixCarPark(inCarParkXML, isMain)
{
    var MainDiv = inCarParkXML.getElementsByTagName("div")[0];    
    MainDiv.setAttribute("class", "bgYellow3 fl w520 mh15 mb1 mt1");
   

    return MainDiv;
}
		
function FixAllTags (inCarParkXML, CPRecord) 
{
    var TDTags =inCarParkXML.getElementsByTagName("td")
    var ATDTag
	for ( var count=0; count < TDTags.length; count++ ) 
	{
	    ATDTag =TDTags[count]
	    ATDTag.setAttribute("class", "w33p");
	}

    var TableTags =inCarParkXML.getElementsByTagName("table")
    var ATableTag
	for ( var count=0; count < TableTags.length; count++ ) 
	{
	    ATableTag =TableTags[count]
	    ATableTag.setAttribute("cellpadding", "0");
	    ATableTag.setAttribute("cellspacing", "0"); 
	    ATableTag.setAttribute("border", "0"); 
	    ATableTag.setAttribute("class", "spaceTable br tbl");
	    ATableTag.setAttribute("summary", ""); 
	}

    var ADetsTags =inCarParkXML.getElementsByTagName("a_details")
    var AnADetsTag
    var AChildADetsTag
    var NewADetsElm
	for ( var count=0; count < ADetsTags.length; count++ ) 
	{    
	    AnADetsTag =ADetsTags[count]
	    AChildADetsTag =AnADetsTag.firstChild;
	    NewADetsElm = AChildADetsTag.cloneNode(true);
	    NewADetsElm.setAttribute("name", "details");
	    NewADetsElm.setAttribute("id", "details");
	    AnADetsTag.parentNode.insertBefore(NewADetsElm,AnADetsTag)
	    AnADetsTag.parentNode.removeChild(AnADetsTag);	    
	    
	}

    var ALinkTags =inCarParkXML.getElementsByTagName("a_link")
    var AnALinkTag
    var AChildALinkTag
    var NewALinkElm
	for ( var count=0; count < ALinkTags.length; count++ ) 
	{
	    AnALinkTag =ALinkTags[count]
	    AChildALinkTag =AnALinkTag.firstChild;
	    NewALinkElm = AChildALinkTag.cloneNode(true);
	    NewALinkElm.setAttribute("class", "blue");
	    try
	    {
	        NewALinkElm.setAttribute("href", "Javascript:AfterDetailsClick(" + GetLatLonText(CPRecord) + ");");
	    }
	    catch(e)
	    {
	    
	    }
	    AnALinkTag.parentNode.insertBefore(NewALinkElm,AnALinkTag)
	    AnALinkTag.parentNode.removeChild(AnALinkTag);	    
	}

    return inCarParkXML;
}	
		
	
function actGetFormatDistanceText(inKMDist, inMiDist)	
{
    return formatDecPlaces(inKMDist) + ' km, ' + formatDecPlaces(inMiDist) + ' mi'
}
	
function actGetDistanceText(record)
{
	    if ( record.distance ) 
	    {
	        var KMDist
	        var MiDist
	        if (lvPosLat == lvlat && lvPosLon == lvlon)
            {
                KMDist =record.distance.km
                MiDist =record.distance.miles
            }
            else
            {
                var Loc = new MMLatLon(lvPosLat, lvPosLon)
                KMDist = mapviewer.getGreatCircleDistance(Loc, record.point)
                MiDist = KMDist * 0.621           
            }
	 	    return '<p>Distance: ' + actGetFormatDistanceText(KMDist, MiDist) + '<' + '/p>'
	    }
	    else
	    {
	        return ""
	    }
}

function actGetRecordFromID(inRecords, ID)
{
    var ARec

    for (var Ndx = 0; Ndx < inRecords.length; Ndx++)   
    {
        ARec = inRecords[Ndx];
        if (parseInt(ARec.carpark_id) == parseInt(ID)) 
        {
            return ARec
        }
    }
    alert("There was a problem finding record: " + ID + "  amongst " + inRecords);
    return null
}

function actReplaceMarkerAtPositionOrAdd(inNewMarker, inLoc)
{
    var AMarker
    var ALoc
    if (markers) 
    {
        for (var Ndx = 0; Ndx < markers.length; Ndx++)   
        {
            AMarker = markers[Ndx];
            ALoc =MarkerLocs[Ndx]
            if (ALoc.lat == inLoc.lat && ALoc.lon == inLoc.lon) 
            {
                if(IsMerelyAddingCarParks)
                {
                    mapviewer.removeOverlay(inNewMarker)
                }
                else
                {
                    mapviewer.removeOverlay(AMarker)
                    markers[Ndx] = inNewMarker
                }
                return null
            }
        }
        markers.push(inNewMarker);
        MarkerLocs.push(inLoc);
    }
}

function actResetAllMarkers()
{
    var AMarker
    var ALoc
    if (markers) 
    {
        for (var Ndx = 0; Ndx < markers.length; Ndx++)   
        {
            AMarker = markers[Ndx];
            if (AMarker.getOption('text') == ' ') // is numbers Marker : replace with generic marker
            {
                ALoc = actGetMarkerCoords(AMarker)
               // ALoc = AMarker.mmbh.coords
                mapviewer.removeOverlay(AMarker)
                markers[Ndx] = createMarker(ALoc, 0, false) 
            }
        }
    }
    return null
}


// *** Routing ***

function ShowRequiredRoute()
{

    if (OrigRoutLocElm.value == OrigRoutLoc)  // still - no change in point of origin
    {
        ShowCPToLocRoute()
    }
    else
    {
        InterpretRoute()
    }
}

function ShowCPToLocRoute()
{
    ToCP = false
    ShowRoute(new MMLocation(new MMLatLon(ClosestLat, ClosestLon)), new MMLocation(new MMLatLon(lvPosLat, lvPosLon)))
}

function ShowLocToCPRoute()
{
   ToCP = true
   ShowRoute(new MMLocation(new MMLatLon(lvPosLat, lvPosLon)), new MMLocation(new MMLatLon(ClosestLat, ClosestLon)))
}

function ShowRoute(startLoc, EndLoc)
{
    if (startLoc != EndLoc)
    {
        route_finder = new MMRouteRequester( RouteFound );
        var locations = new Array();
        locations.push(startLoc)
        locations.push(EndLoc)
        route = new MMRoute( locations );
        
        route_finder.request(route);
        SetShowClarificationSection(false)
    }
}

function RouteFound()
{
    if (route.error_code) {
        // Display an error message, if applicable:
        alert(route.error_code + ': ' + route.error_explanation);
    } else 
    {
        // use getAutoScaleLocation to show the entire route on the map, with the route bounds:
        mapviewer.removeAllOverlays();
        IciMarker = SetIci();
        markers.length = 0
        MarkerLocs.length = 0
        mapviewer.goToPosition( mapviewer.getAutoScaleLocation( route.bounds ) );
        displayStages(route);
        // Show the route on the map with PolyLines, by adding each polyline returned:
        
        
        for( var i = 0, l = route.polyLine.length; i < l; ++i ) {
          route.polyLine[i].options = {'opacity':0.65, 'color':'yellow'};
          mapviewer.addOverlay(route.polyLine[i]);
        }
        
    }
    
    window.scrollTo(0,200) 
    inRouteMode = true
}

function displayStages(route) 
{
    var curr_step = 1;
    var stages = route.stages; 
    var containerHolder = document.getElementById('InfoPanel');  //'routeSteps');
    var VisibleNumber
    containerHolder.innerHTML = '<div><table cellpadding="0" cellspacing="0" border="0" class="spaceTable br tbl" summary=""><tr><td class="w33p"></td></tr></table></div>';
    var container = containerHolder.getElementsByTagName('td')[0]
    var lvCreatedMarker

    var h3 = document.createElement('h3');
    h3.appendChild(document.createTextNode('Travel directions'));
    container.appendChild(h3);
    
    var summary = '';
    // Show the total route distance in Miles:
    summary += '<br />Total Distance: ' + actGetFormatDistanceText(route.distance.km, route.distance.miles);
    // Show the total duration of trip. Note that we display the Days, Hours, and Minutes by
    //  accessing each property: 
    summary += '<br />Estimated Total Time: ';
    if (route.duration.days > 0) { summary += route.duration.days + ' day(s) '; }
    if (route.duration.hours > 0) { summary += route.duration.hours + ' hour(s) '; }
    if (route.duration.minutes > 0) { summary += route.duration.minutes + ' minute(s) '; }
    var p = document.createElement('p');
    p.innerHTML = summary;
    container.appendChild(p);
    
    // The route will be returned in stages. Each stage goes from one specified 'location' to the next:
    for (var count=0; count < stages.length; count++) 
    {
        // Show some summary information about each stage:
        if (stages.length > 1)
        {
            var stage_summary = '';
            stage_summary += '<strong>Stage ' + (count + 1) + '<' + '/strong>';
            stage_summary += '<br />Stage Distance: ' + actGetFormatDistanceText(stages[count].distance.km, stages[count].distance.miles);
            stage_summary += '<br />Estimated Stage Time: ';
            if (stages[count].duration.days > 0) { stage_summary += stages[count].duration.days + ' day(s) '; }
            if (stages[count].duration.hours > 0) { stage_summary += stages[count].duration.hours + ' hour(s) '; }
            if (stages[count].duration.minutes > 0) { stage_summary += stages[count].duration.minutes + ' minute(s) '; }
            var p = document.createElement('p');
            p.innerHTML = stage_summary;
            container.appendChild(p);
        }
        
        var ul = document.createElement('ul');
        ul.className = '"directionslist"';
        ul.id = '"stage_' + count + '"';
        ul.start = curr_step;

        var steps = stages[count].steps;
        // Now we will display each step instruction within this stage:
        for (var stepCount=0; stepCount < steps.length; stepCount++) {
            // Label the current marker with the step number:
            var text = curr_step;
            // Make the higher numbered step markers appear 'on top of' lower ones:
            var zindex = max_zindex - curr_step + 1;
            
            var icon = null
            // Use 'S' as marker text if this is the first step of the entire route:
            VisibleNumber = curr_step + '.   '
            if (count == 0 && stepCount  == 0) 
            {
                if (!ToCP)
                {
                    icon = actGetIcon('NCP')
                    VisibleNumber = 'NCP.'
                    text = '';
                }
            }        
            // Use logo as marker text if this is the last step of the entire route:      
            if (count == stages.length - 1 && stepCount  == steps.length - 1) 
            {
            
                if (ToCP)
                {
                    icon = actGetIcon('NCP')
                    VisibleNumber = 'NCP.'
                    text = '';
                }
            }                
            // Create a written 'instruction' using the roadname and/ or roadnumber:
            var instruction = steps[stepCount].instruction;
            var roadname = steps[stepCount].road_name;
            var roadnumber = steps[stepCount].road_number; 

            if (roadname && roadnumber) 
            {
                instruction += ' ' + roadname + ' (' + roadnumber + ') ';
            } else if (roadname) 
            {
                instruction += ' ' + roadname + ' ';
            } else if (roadnumber) 
            {
                instruction += ' ' + roadnumber + ' ';
            }
            
            // Show the distance of this particular step:
            var distance = '';                    
            if (steps[stepCount].distance.miles > 0) { distance += actGetFormatDistanceText(steps[stepCount].distance.km, steps[stepCount].distance.miles);} 
            if (distance != '') { distance = ' - ' + distance };
            
            var li = document.createElement('li');
            li.innerHTML = '<strong>' + VisibleNumber + '</strong>   ' +  instruction + distance;
            ul.appendChild(li);
            
            // Create the step marker, using the instruction and marker text we previously created:
                lvCreatedMarker = createStepMarker(steps[stepCount].start_point, instruction, text, zindex, icon);   
                if (VisibleNumber == 'NCP.') 
                {
                    FRouteNCP = lvCreatedMarker 
                }                        
            ++curr_step;
        }
        container.appendChild(ul);
    }            
    
    container.style.display = 'block'; 
    
    // Add copyright and disclaimer, as required:
    var copyright = '';
    if (route.copyright) {copyright += 'Copyright: ' + route.copyright; }
    if (route.disclaimer)  {copyright += '<br />Disclaimer:  <a href="' + route.disclaimer +'">' + route.disclaimer +'<' + '/a>'; }
    
    var p = document.createElement('p');
    p.innerHTML = copyright;
    container.appendChild(p);            
}

function createStepMarker(location, instruction, text, zindex, icon) 
{
    var marker
    
    if (icon) 
    {
        marker = mapviewer.createMarker(location, {zIndex: zindex, 'text' : text, 'icon': icon});
    }
    else
    {
        marker = mapviewer.createMarker(location, {zIndex: zindex, 'text' : text});
    }
    marker.setInfoBoxContent('<p>' + instruction + '<' + '/p>');
    return marker
}        


// *** Utility functions ***

/*function actGetMarkerCoords(inMarker)
{
    var MarkerLat, MarkerLon

    if (inMarker.mmbh)
    {
        MarkerLat = inMarker.mmbh.coords.lat
        MarkerLon = inMarker.mmbh.coords.lon       
    }
    else if (inMarker.mmah) 
    {
        MarkerLat = inMarker.mmah.coords.lat
        MarkerLon = inMarker.mmah.coords.lon       
    }
    else if (inMarker.mmdh) 
    {
        MarkerLat = inMarker.mmdh.coords.lat
        MarkerLon = inMarker.mmdh.coords.lon       
    }
    else if (inMarker.mmch) 
    {
        MarkerLat = inMarker.mmch.coords.lat
        MarkerLon = inMarker.mmch.coords.lon       
    }
    else 
    {
        return false;
    }
    
    return new MMLatLon(MarkerLat, MarkerLon)
}*/

function actGetMarkerCoords(inMarker) {

 var position = inMarker.getPosition();

 if (position && position.coords) {

  return position.coords;

 }

 return undefined;

}


function actGetIcon(IconType)
{
    var lvIcon
    if (IconType == 'X') 
    {
    	lvIcon = new MMIcon(ICIIconPath);
        lvIcon.iconSize = new MMDimensions( 19, 21 );
        lvIcon.iconAnchor = new MMPoint( 10, 21 );
        lvIcon.shadowSize = 5
    }
    else if (IconType == 'NCP') 
    {
	    lvIcon = new MMIcon( 'public/images/ncp/Multimap/NCP.gif' );
        lvIcon.iconSize = new MMDimensions( 22, 26 );
        lvIcon.iconAnchor = new MMPoint( 11, 26 ); 
    }
    else 
    {
	    lvIcon = new MMIcon( 'public/images/ncp/Multimap/' + IconType + '.gif' );
        lvIcon.iconSize = new MMDimensions( 19, 26 );
        lvIcon.iconAnchor = new MMPoint( 10, 26 );
    } 
    
    return lvIcon
}

var geocoder
var InputVal, InputTypeVal, InputNdxVal
var address = new MMAddress();
var FInputExtra 
 
function InterpretRoute() { 

    var Extwn = document.getElementById('ExtraTownRt')
    if (Extwn) 
    {
        FInputExtra = Extwn.value 
    }    
        else
    {
        FInputExtra = ""
    }    

    InputVal = OrigRoutLocElm.value
    if (InputVal || InputTypeVal)
    {
            geocoder = new MMGeocoder(actShowPosibilities);
            address.street = "";
            address.city = "";
            address.state = "";
            address.postal_code = "";
            address.country_code = "GB";
            address.qs = "";
            if (document.getElementById('radpostcodert').checked) 
            {
                address.postal_code = InputVal;
                InputNdxVal = 0
            }
            else if (document.getElementById('radtownrt').checked) 
            {
                address.city = InputVal;
                InputNdxVal = 1
            }
            else if (document.getElementById('radstreetrt').checked) 
            {
                address.street = InputVal;
                if (FInputExtra != "")
                {
                    address.city = FInputExtra               
                }
                InputNdxVal = 2               
            }
            else
            {
                address.qs = InputVal;
            }
                  
            geocoder.count = 50          
            geocoder.geocode(address);        
    }

}

function actShowPosibilities()
{

    var List = document.getElementById("Clarification")   
    List.innerHTML = ""
    var results = geocoder.result_set;
    if (results) 
    {
        var ClickNameP = document.getElementById('ClickName')
        if (results.length <= 48) 
        {
            var aspxpage = location.pathname
            var NumFound = document.createTextNode("Searching for '" + InputVal + "' returned " + results.length + " results.");
            List.appendChild(NumFound);
            var ul = document.createElement('ul');
            //loop through the result set
            for (var count=0; count < results.length; count++) 
            {
                var address = results[count].address;
                var li = document.createElement('li');
                //add a link for each result
                var anchor = document.createElement('a');
                                                
                var lvhref = "Javascript:ExtraShowRoute(" + results[count].coords.lat + ", " + results[count].coords.lon + ")"

                anchor.href = lvhref;
                anchor.result_count = count;
                anchor.appendChild(document.createTextNode(address.display_name));
                li.appendChild(anchor);
                ul.appendChild(li);

            }
            List.appendChild(ul);
            
            if (results.length == 1)
            {
                ExtraShowRoute(results[0].coords.lat, results[0].coords.lon)
            }
            else // list between 0 and 48 but not 1
            {
                SetShowClarificationSection(true)
                if (results.length > 1)
                {
                    var ClickNameP = document.createTextNode("Click on a place name to view the route:")
                    List.appendChild(ClickNameP);
                }
            }
            
        }
        else // more than 48
        {
            SetShowClarificationSection(true)
            List.innerHTML = '<strong>There are too many results for "' + InputVal + '". Please indicate the town:</strong> <input type="text" id="ExtraTownRt" name="ExtraTownRt"></input>'
        
        }
    }
}

function RetrySearch()
{
    Extown = document.getElementById('ExtraTownRt');
    address.city =ExtraTownRt.value;
    geocoder.geocode(address);  
    FInputExtra.value = ExtraTownRt.value;
}

function ExtraShowRoute(NewLat, NewLon)
{
    ToCP = true
    ShowRoute(new MMLocation(new MMLatLon(NewLat, NewLon)), new MMLocation(new MMLatLon(ClosestLat, ClosestLon)))
}

function SetShowClarificationSection(show)
{
    var section = document.getElementById('ExtraBody');
    section.style.display = (show ? 'inline' : 'none');
}

function GetPlainText(inElement)
{
           
            if (ie)
            {
                return inElement.text;
            }
            else
            {
                return inElement.textContent;
            }

}

/*function GetPlainText(inElement)
{
    var Result
           
    	    try
	        {
	            Result = inElement.textContent;
	        }
    	    catch(e)
    	    {
        	    try
	            {
	                Result = inElement.text;
	            }
        	    catch(e)
        	    {
	                Result = inElement.innerText
	            }
	        }


     if (!Result)
     {
    	    try
	        {
	            Result = inElement.text;
	        }
    	    catch(e)
    	    {
	                Result = inElement.textContent;
	        }
     }
     return Result
}*/


function AddAppendedElement(inBaseElm, inAddElm)
{
            if (ie)
            {
                inBaseElm.innerHTML = inBaseElm.innerHTML + inAddElm.xml;
            }
            else
            {
                inBaseElm.appendChild(inAddElm);  
            }
            return inBaseElm;
}            

MMAttachEvent( window, 'load', onLoad );
