﻿/*!
 * Main Forward Living Javascript
 */

//jQuery.noConflict();

// == global members ==

google = undefined // see unloade

function loadGoogleApis() { // this has to be a global function. It's called by name by google loader. see Lfl.loadGoogleLoader
    Lfl.loadGoogleApis() // just delegate to the private function
}

function onGaugeLoaded (gaugeId) { // this has to be a global function. It's called by name by Gauge flash object.
    Lfl.onGaugeLoaded(gaugeId) // just delegate to the private function
}

// == Lexus Forward Living namespace ==

Lfl = (function($, U) {
           
// Lfl variables
var afterWelcomeInitialized = false;
var config;
var appRoot = "";
var homePage = "";
var skipWelcome = false;
var iFrameNumber = 0;

var journeyWaypoints = [];
var journeyURL = "";

var map1 = null;
var googleEarthInstance = null;
var myDirections = null;
var journeyLength = 0;
var journeyDuration = 0;
var path = [];	

var googleEarthHelpers = null;
var simulator = null;
var mapMarker = null;
var simulatorDefaultSpeed = 4;
var simulatorMinimumSpeed = 0;
var simulatorMaximumSpeed = 7;
var simulatorStep = 1;
var oldFlyToSpeed = 0;
var loaddelay = 1300;
var modelPlacemark = null;
var model = null;

var carIcon = null;
var interval = null;
var directionsLoaded = false;

var customPOI = [];
var candidatePoi = [];
var localSearchPoi = [];
var routebounds = null;
var fakeJourney = false;
var closestLexusDealer = null;
var startMarkerFunc;
var startMarkerHTML;
var endMarkerFunc;
var endMarkerHTML;
var resetSimulatorBeforeStart = false;

var iconExt = ".png"
var lexusRight;
var lexusLeft;
var lexusUp;

var mediaHome = ""
var mediaHomeExtPath = ""
var configHome = ""
var configHomeExtPath = "/range/rx/forward-living/xml/"
var javascriptHome = ""
var javascriptHomeExtPath = "/sys/js/"

var newShare = true

// NG - Adjusted so that file names are supplied in collection
var iconData = {
  "startend":	{ ie6_hl:"start_stop_normal_hl.gif", ie6:"/Images/start_stop_normal_tcm584-902216.gif", filename_hl:"start_stop_normal_hl.png", filename:"/Images/start_stop_normal_tcm584-902217.png", 	width: 18, height: 19, anchorX: 9, anchorY: 18, infoAnchorX:9, infoAnchorY:0 },
  "bc":	{ ie6_hl:"/Images/bars_clubs_hl_tcm584-901953.gif", ie6:"/Images/bars_clubs_tcm584-901950.gif", filename_hl:"/Images/bars_clubs_hl_tcm584-901954.png", filename:"/Images/bars_clubs_tcm584-901951.png", 	width: 25, height: 25, anchorX: 12, anchorY: 24, infoAnchorX:10, infoAnchorY:4 },
  "cc": { ie6_hl:"/Images/car_content_hl_tcm584-902005.gif", ie6:"/Images/car_content_tcm584-902001.gif", filename_hl:"/Images/car_content_hl_tcm584-902006.png", filename:"/Images/car_content_tcm584-902002.png",	width: 30, height: 25, anchorX: 11, anchorY: 24, infoAnchorX:11, infoAnchorY:3 },
  "cu": { ie6_hl:"/Images/culture_hl_tcm584-902017.gif", ie6:"/Images/culture_tcm584-902014.gif", filename_hl:"/Images/culture_hl_tcm584-902018.png", filename:"/Images/culture_tcm584-902015.png",		width: 25, height: 25, anchorX: 9, anchorY: 22, infoAnchorX:9, infoAnchorY:1 },
  "dt": { ie6_hl:"/Images/design_tech_hl_tcm584-902030.gif", ie6:"/Images/design_tech_tcm584-902027.gif", filename_hl:"/Images/design_tech_hl_tcm584-902031.png", filename:"/Images/design_tech_tcm584-902028.png",	width: 25, height: 25, anchorX: 13, anchorY: 25, infoAnchorX:11, infoAnchorY:1 },
  "fl": { ie6_hl:"/Images/forward_living_hl_tcm584-902051.gif", ie6:"/Images/forward_living_tcm584-902049.gif", filename_hl:"/Images/forward_living_hl_tcm584-902052.png", filename:"/Images/forward_living_tcm584-902050.png",width: 25, height: 25, anchorX: 9, anchorY: 23, infoAnchorX:9, infoAnchorY:1 },
  "gr": { ie6_hl:"/Images/green_hl_tcm584-902061.gif", ie6:"/Images/green_tcm584-902058.gif", filename_hl:"/Images/green_hl_tcm584-902062.png", filename:"/Images/green_tcm584-902059.png",			width: 25, height: 25, anchorX: 4, anchorY: 22, infoAnchorX:13, infoAnchorY:1 },
  "la": { ie6_hl:"/Images/landmarks_hl_tcm584-902135.gif", ie6:"/Images/landmarks_tcm584-902132.gif", filename_hl:"/Images/landmarks_hl_tcm584-902136.png", filename:"/Images/landmarks_tcm584-902133.png",		width: 25, height: 25, anchorX: 11, anchorY: 21, infoAnchorX:9, infoAnchorY:2 },
  "re": { ie6_hl:"/Images/restaurants_hl_tcm584-902187.gif", ie6:"/Images/restaurants_tcm584-902184.gif", filename_hl:"/Images/restaurants_hl_tcm584-902188.png", filename:"/Images/restaurants_tcm584-902185.png",	width: 25, height: 25, anchorX: 12, anchorY: 22, infoAnchorX:10, infoAnchorY:1 },
  "lexuscenter" : { ie6_hl:"/Images/lexus_centers_hl_tcm584-902151.gif", ie6:"/Images/lexus_centers_tcm584-902148.gif", filename_hl:"/Images/lexus_centers_hl_tcm584-902152.png", filename:"/Images/lexus_centers_tcm584-902149.png",	width: 25, height: 25, anchorX: 13, anchorY: 12, infoAnchorX:13, infoAnchorY:4 }
};

var closestMarker = null;
var isAtMarkerThreshold = 10;
var framecount = 0;

// ui components
var ddPredefinedJourneys = null;
var gaugeLexusFC, gaugeLexusCE, loadedGauges = {}

// INIT ==============================================================================

function initWidgets() {

    if (!config.configOptions.useCarCompare) $("#car-compare").css("display","none");    
    
    // init predefinedJourneys dropdown
    if (config.predefinedJourneys.length > 0)
    {   ddPredefinedJourneys = brUI.makeDropDown(
		    $("#predefinedJourneys"), 
		    config.labels.predefinedJourney, 
		    config.predefinedJourneys,
		    function(selected){
			    U.track("WT.pn=Main screen","WT.ti=predefined_"+selected.display);
			    selectPredefinedJourney(selected);
		    },
		    {dropUp: true}
	    )
    }
    else
    { // set the langauge button to full width style
    }

    // init language site dropdown
	if (config.countries.length > 1)
	{    brUI.makeDropDown(
		    jQuery("#languages"), 
		    config.labels.changeCountry, 
		    config.countries,
		    function(selected) { 
			    U.track("WT.pn=Main screen","WT.ti=country_"+selected.display);
			    window.location = selected.url;
		     },
		    {dropUp: true}
	    )		
	}
    else
    { // set the predefined journey button to full width style
    }	
	
	// init galleries dropdown
	brUI.makeDropDown(
		jQuery("#galleries"), 
		config.labels.mediaMenuText, 
		[{
			display: config.labels.videoGallery,
			galleryHtml: config.configOptions.videoUrl,
			tracking:'video-gallery'
		},{
			display: config.labels.imageGallery,
			galleryHtml: config.configOptions.imageUrl,
			tracking:'image-gallery'
		}],
		function(selected) { 
			//MS:tracking removed - done at page level
			//U.track("WT.pn=Galleries","WT.ti="+selected.tracking);
			showGallery( selected.galleryHtml );
		},
		{menuMode: true}
	)	    

	brUI.makeDropDown(
		jQuery("#carFeatures"), 
		config.labels.carFeaturesMenuText, 
		config.carFeatureOptions,
		function(selected) { 
			showCarInfo(selected.url,"_dropdown"); 
		},
		{menuMode: true}
	);

	var ctablockmarkup = '';
	$.each(config.ctadata, function(i,ctablock){
		ctablockmarkup += 
		'<a href="'+ctablock.url_link+'" class="panel-ft" id="'+ctablock.analytics+'" title = "'+ctablock.title+'">'+
			'<span class = "inner">'+
				'<span class= "img"></span>' +
				'<span class = "txt">'+ctablock.title+'</span>'+
			'</span>'+
		'</a>';
	});
	$("#yourCarPanel").after(ctablockmarkup);
	
	// init listeners
	$("#car-compare").click( function(event) { 
		event.preventDefault(); 
		if (!directionsLoaded) return;
		$("#car-compare").addClass("selectedbtn");
	    showCentralFrame(config.configOptions.compareUrl) 
	});
    if (config.configOptions.useCustomJourney) {
		$("#update-journey, #add-destination").click(function(event){
			event.preventDefault();
			stopSim();
			$("#update-journey").addClass("selectedbtn");
			showCentralFrame(config.configOptions.destinationUrl+"?shc")//&WT.pn=Main screen&WT.ti=Update journey") //MS:Added query string params
		})
	} else {
		$("#update-journey, #add-destination").css("color","grey");		
	}
	

  $('#aShareRoute').click(function(event){
		event.preventDefault();
                                stopSim();
		tb_show(config.labels.dialogCaption, U.createShareUrl("",journeyURL))
	});	
	
    //iterate through each link
    $("#fl div.call-to-action ul li").each(function(event) {
        //check for specific file(s
        var $sCTAlink = $(this).find("A");

        if($sCTAlink.attr("href").toLowerCase().indexOf("help.aspx") > 0)
        {   $sCTAlink.addClass("aHelp")
            $sCTAlink.click(function(event) {
                event.preventDefault()
                stopSim();
                showCentralFrame(config.configOptions.helpUrl)
            })
        }

        if($sCTAlink.attr("href").toLowerCase().indexOf("share.aspx") > 0)
        {	$sCTAlink.addClass("aShare")
            $sCTAlink.click(function(event) {
                event.preventDefault()
                stopSim();
                tb_show(config.labels.dialogCaption, U.createShareUrl("",homePage))
            })
        }
    })
	
	//General click handler for start
	$('#map1').click( function( event ) {
        var $target = $(event.target);
        if( $target.is('#startSim') ) {
           	event.preventDefault(); 
			startSim(true);
            return false;
        }
       if( $target.is('#compareCars') ) {
           	event.preventDefault(); 
			showCentralFrame(config.configOptions.compareUrl) 
            return false;
        }		
    }); 
	
    $(document).ready(function() {
        $("*[id^=cta-]").click(function(event) {
            var target = $(this).text();
            if (target) U.track("WT.pn=CallToActions","WT.ti="+target+"-topleft");
        })

        $("*[id^=base-menu-container] ul li a").click(function(event) {
            var target = $(this).text();        
            if (target) U.track("WT.pn=CallToActions","WT.ti="+target+"-bottom");
        } )
    } );

    //Init Marker HTML
    function openStartEndMarker(title,paragraphs) {
        var markup = 	'<div id="border">'		+
                '<div id="startendwindow_header">'+title+'</div>'	+
                '<div id="ss_copy">'
        for ( var i = 0; i<paragraphs.length; i++) {
            if (paragraphs[i]&&paragraphs[i].length>0)
            markup += '<p>'+paragraphs[i]+'</p>'
        }
        return markup	
    }
	
	function createStartMarkerButton(text) {

		var sID;
		if (config.labels.startDrivingLabel != text)
		  { sID = "compareCars" }
		else
		  { sID = "startSim" }

		return '<div class="ss_button">'+
			'<div class="left_button"></div>'+
            '<div class="content">'+
            	'<span class="leftMarker">&nbsp;</span><a href="#" id="'+sID+'">'+text+'</a><span class="rightMarker">&nbsp;</span>'+
            '</div>'+
            '<div class="right_button"></div>'+
        '</div>'
	}
	
	function closeStartEndMarker() {
		return 	'</div>' +
				'</div>'
	}
	
	startMarkerHTML = 	openStartEndMarker(config.labels.startJourneyLabel,[config.labels.startJourneyParagraph1,config.labels.startJourneyParagraph2]) +
						'<span class="img">&nbsp;</span>'	+
						(config.configOptions.useCarCompare?createStartMarkerButton(config.labels.compareCarsLabel):"")	+
						createStartMarkerButton(config.labels.startDrivingLabel) +
						'<br/><br/><br/><br/><br/><br/><br/><br/>' +
						closeStartEndMarker()

	var endMarkerCTABlock = ''
	$.each(config.ctadata, function(i,ctablock){
		endMarkerCTABlock += '<li'+(i==0?' class="first"':'')+'><a id="'+ctablock.analytics+'_topleft" href="'+ctablock.url_link+'">'+ctablock.title+'</a><span class="arrow"></span></li>'
	})
	if (config.configOptions.useCarCompare)
		endMarkerCTABlock += '<li'+(endMarkerCTABlock.length==0?' class="first"':'')+'><a id="compareCars" href="#">'+config.labels.compareCarsLabel+'</a><span class="arrow"></span></li>'
	endMarkerHTML = openStartEndMarker(config.labels.endJourneyLabel,[config.labels.endJourneyParagraph1,config.labels.endJourneyParagraph2]) +
					'<ul class="call-to-action">'+
					endMarkerCTABlock+
					'</ul>'+
					'<br/><br/><br/><br/><br/><br/><br/><br/>' +
					closeStartEndMarker()
	//End Init Marker HTML
}

function isGaugesLoaded () {
    var loaded = (loadedGauges['gaugeLexusFC'] && loadedGauges['gaugeLexusCE']); 
    return loaded;
}

function onGaugeLoaded (gaugeId) {
    loadedGauges[gaugeId] = true
}

function createGauge(id, holderId, onLoadedStr, options) {
    var defaults = { colour: '0xFFFFFF' }
    options = $.extend({}, defaults, options)
	var gauge = new SWFObject(mediaHome+'/Images/Gauge_tcm584-901686.swf', id,' 98', '12', '9.0.0.0', '#E6E6E6');
	gauge.addParam   ("wmode",       "transparent");
	gauge.addVariable("id", id);
	gauge.addVariable("onLoaded", onLoadedStr);
	gauge.addVariable("gaugeColour", options.color);
	gauge.write(holderId);
	return document.getElementById( id ); 
}

function initGauges() {
    gaugeLexusFC = createGauge('gaugeLexusFC', 'spanLexusFC', 'onGaugeLoaded', {color: '0x63C7E7'})
    gaugeLexusCE = createGauge('gaugeLexusCE', 'spanLexusCE', 'onGaugeLoaded', {color: '0x80C342'})    
}

function initFilterPoi() {
	
	// build markup
    var filterPoiMarkup = ''
    for (var cid in config.categories) {
        var category = config.categories[cid]
        if (category.active) {
            category._filterpoi_checked = true // by default all categories are on
            filterPoiMarkup += 
                '<a href = "#">' + 
                    '<img src = "' + category.iconon + '" alt = "' + cid + '" title="' + category.name + '"/>' + 
                '</a>'
        }
    }

    // event handlers
    function onClick(event) {
        event.preventDefault()
        var $target = $(event.target);
        var cid = $target.attr('alt');
        var category = config.categories[cid];
        category._filterpoi_checked = ! category._filterpoi_checked; // toggle checked
        $target.attr('src',  category._filterpoi_checked ? category.iconon : category.iconoff);
		$.each(candidatePoi, function(i,loc){ 
			if (loc.cat == cid) category._filterpoi_checked ? loc.marker.show() : loc.marker.hide()
		});
		$.each(localSearchPoi, function(i,loc){ 
			if (loc.cat == cid) category._filterpoi_checked ? loc.marker.show() : loc.marker.hide()
		})        
    }
    
    function makeOnHover(over) { // over: true - over, false - out
        return function(event) {
            var $target = $(event.target)
            var cid = $target.attr('alt')
            var category = config.categories[cid]
            if (over) {
                $target.attr('src', category.iconover)
                $("#filterPoiName").text( category.name )
            }
            else {
                $target.attr('src', category._filterpoi_checked ? category.iconon : category.iconoff)
                $("#filterPoiName").text("")                
            }
        }
    }
   
    // inject markup and register events    
    $("#filterPoiIcons")
        .html( filterPoiMarkup )
        .find('img')
            .click(onClick)
            .hover(makeOnHover(true), makeOnHover(false))
}

function initOther() { 
	carIcon = new google.maps.Icon();
	carIcon.iconSize = new google.maps.Size(42, 42);
	carIcon.iconAnchor = new google.maps.Point(21, 21);
	carIcon.image = (config.configOptions.carIconType=='direction') ? lexusUp : lexusRight;
	if (config.configOptions.useCustomPOI) {
		$.getJSON(appRoot + config.configOptions.customPOI, function(data) {
			$.each(data.locations, function(i, loc) {
				ltlg = new GLatLng(loc.lat, loc.lng);
				customPOI.push({
					"id": "fl_" + loc.id,
					"cat": loc.cat,
					"latlng": ltlg
				});//, "dist":0, "marker":null, "shortTxt":null, "longTxt":null, "url":null } );		
			});
		});
	}
	if (window.itg) {
		$.each(window.itg.dealers.dealer, function(i, dealer) {
			dealer.id = dealer.guid
			dealer.latlng =  new GLatLng(dealer.latitude, dealer.longitude);
			dealer.cat = "lexuscenter"
		})
	}
	for (var icon in iconData) {
		getIconByFileName(iconData[icon],"iconNormal",null);
		getIconByFileName(iconData[icon],"iconHighlight","_hl");
	}    
}


function maybeResumeSimulation() {
    if (simulator && config.configOptions.resumeSimAfterContent && simulator.running && simulator.paused) { 
        startSim();
    }    
}

/**
either predefinedJourney or (waypoints, directions) has to be provided.
*/
function onUpdateJourneyGo(predefinedJourney, waypoints, directions) {
    function _doGo() {
        if (predefinedJourney) {
            selectPredefinedJourney( predefinedJourney )
        }
        else {
            ddPredefinedJourneys.select(null);
            $('#from').html( waypoints[0] );
            $('#to')  .html( waypoints[waypoints.length - 1] );
    		journeyWaypoints = waypoints;
    		myDirections = directions // TODO pass as parameter?
    		myDirectionsLoaded()
	    }        
    }
    
    if (afterWelcomeInitialized) {
        hideCentralFrame(function() {
            _doGo()                
        })
    }
    else { 
        initAfterWelcome( _doGo )
    }
}

function getIconByFileName ( iconDataItem ,propName, mod ) {
	var icon = null;	
	if (!iconDataItem) return GIcon.G_DEFAULT_ICON;
                // NG - Adjusted so that file names are supplied in collection
                //var filename = mediaHome+"icons/" + iconDataItem.filename + (mod||"") + iconExt;
	var filename = mediaHome+ ($.browser.msie && $.browser.version < 7) ? iconDataItem["ie6" + (mod||"")] : iconDataItem["filename" + (mod||"")]; //"icons/" + iconDataItem.filename + (mod||"") + iconExt;
	
	icon = new GIcon();
	icon.image = filename;
	icon.iconSize = new GSize(iconDataItem.width, iconDataItem.height);
	icon.iconAnchor = new GPoint(iconDataItem.anchorX, iconDataItem.anchorY);
	icon.infoWindowAnchor = new GPoint(iconDataItem.infoAnchorX, iconDataItem.infoAnchorY);
	icon.shadow = filename;
	icon.shadowSize = new GSize(iconDataItem.width, iconDataItem.height);
	iconDataItem[propName] = icon;
	iconDataItem[propName+"FN"] = filename;
	return icon;
}

function initPoiScrollPane () {
    $("#poiScrollPane").jScrollPane({
        showArrows:     true,
        arrowSize:      12, 
        scrollbarWidth: 12,
        dragMinHeight:  16,
        dragMaxHeight:  16,
        animateTo:      true
    })

    // jScrollPane registers a document wide event handler to scrollTo local links.
    // It causes "Syntax error, unrecognized expression: #" in jQuery 1.3.2
    // Ditch it.
    $(document).unbind('click')
}

/* show / hide panels */
function addShowHidePanels () {
	$("a.hide-show").text(config.labels.hideLinkText);
	$("a.hide-show").click(
                    function(){ 
						$(".options").hide(); 
						var panelId = this.href.substr((this.href.indexOf("id=")+3), this.href.length);	
					 	var hyperlink = this;	
						
						if(hyperlink.className.indexOf(" hide") != -1) { $("#" + panelId).slideUp(700, function() { hyperlink.className = "hide-show show"; hyperlink.innerHTML = config.labels.showLinkText; } );  }
						else { $("#" + panelId).slideDown(700, function() { hyperlink.className = "hide-show hide"; hyperlink.innerHTML = config.labels.hideLinkText; } );  }
                                                                                                 $("a.hide-show").blur();
						return false;
                    }
               );  
}

//initialize maps
function initMaps () {
	map1 = new google.maps.Map2( $("#map1").get(0) ); // create google map for map1
	
	function lfLinkCallback (link) {
	   if (closestLexusDealer) {
		GEvent.trigger(closestLexusDealer.marker,'click')
	   }
	}
	
	var locStrings = config.configOptions.mapStartLoc.split(",");
    map1.setCenter (new GLatLng(parseFloat(locStrings[0]), parseFloat(locStrings[1])), config.configOptions.mapStartZoom);	
    map1.addControl( brUI.makeZoomControl(google, 'flZoomControl') );
        
    var mapOpts = [];
    if (config.configOptions.useFindLexusCentre) mapOpts.push({id: 'flLink1', image: '/Images/flLink1_tcm584-902045.png', label: config.labels.findLexusCentre,         callback: lfLinkCallback});
    if (config.configOptions.useCustomPOI) mapOpts.push({id: 'flLink2', image: '/Images/flLink2_tcm584-902046.png', label: config.labels.findForwardLiving       , callback: lfLinkCallback});
    
    map1.addControl(brUI.makeLinkControl(google, 'flLinkControl', mapOpts, mediaHome))
    if (config.configOptions.useMapMakerView) map1.setMapType(G_MAPMAKER_NORMAL_MAP);
    map1.enableContinuousZoom();                             // enable zoom
    //map1.closeInfoWindow();                                // Closes the info window, if it is open, and disables the opening of a new info window.
	
	//google.maps.Event.addListener(map1, "click", function() { pauseSim(); });	//stop simulation when maps 1 is clicked	
	//google.maps.Event.addListener(map1, "move", function() { pauseSim(); });	//stop simulation when maps 1 is clicked	
}

function initGoogleEarth(initializedCallback) {
	// try to create google.earth.createInstance for map2 -> google.earth.createInstance([div.id], [onsuccess], [onfailure]);
	if (config.configOptions.useGoogleEarth) {
        //alert('initGoogleEarth(initializedCallback) - google earth OK in config file');
		google.earth.createInstance("map2", function(ge) { // on success
			googleEarthInstance = ge;
			googleEarthInstance.getWindow()   .setVisibility(true);
			googleEarthInstance.getLayerRoot().enableLayerById(googleEarthInstance.LAYER_BUILDINGS, true);
			googleEarthInstance.getLayerRoot().enableLayerById(googleEarthInstance.LAYER_BORDERS, true);
			googleEarthInstance.getOptions()  .setMouseNavigationEnabled(false); // disable mouse
			googleEarthHelpers = new GEHelpers(googleEarthInstance); // instantiate helpers from GEHelpers class: geplugin-helpers.js


            //alert('initGoogleEarth(initializedCallback) - loadModel now')
			loadModel(function() { // load virtual car
                //alert('initGoogleEarth(initializedCallback)> loadModel - addSumulation now')
			    addSimulation(); // TODO should it be called at the very last moment?
                //alert('initGoogleEarth(initializedCallback)> loadModel - addSumulation return')
   
			    if (initializedCallback) {
			        initializedCallback()
			    }
                else {
                    //alert('initGoogleEarth(initializedCallback) - NO initializedCallback() ');
                }
			});
		}, function() { // on error		
            //alert('initGoogleEarth(null) : error instantiating googleEarth');

			var vidPlayer = new SWFObject(mediaHome+'/Images/video_tcm584-901697.swf', "earthReplacementVideo",'235', '129', '8.0.0.0', '#000000');
			vidPlayer.addVariable("xmladdress", "/sys/dotnet/xml/vidPlayer.xml");
			vidPlayer.addVariable('autoPlay', 'false');
            vidPlayer.addParam ("wmode", "transparent");
			vidPlayer.write("map2");
			$("#map2").prepend('<div class=\"no-plugin\"><a href=\"http://code.google.com/apis/earth/\" target="_google"><img src = "'+mediaHome+'//Images/download-google_tcm584-902039.gif"></img>  '+config.labels.noEarthText+'</a></div>');
			addSimulation();
			if (initializedCallback) {
				initializedCallback()
			}
		});
	} else {
        //alert('initGoogleEarth(null) : GoogleEarth is off in config - instantiate video');
        	
        var vidPlayer = new SWFObject(mediaHome+'/Images/video_tcm584-901697.swf', "earthReplacementVideo",'235', '129', '8.0.0.0', '#000000');
        vidPlayer.addVariable("xmladdress", "/sys/dotnet/xml/vidPlayer.xml");
		vidPlayer.addVariable('autoPlay', 'false');
        vidPlayer.addParam ("wmode", "transparent");
       	vidPlayer.write("map2");
//		$("#map2").prepend("<div class=\"no-plugin\"><a href=\"http://code.google.com/apis/earth/\"><img src = "'+mediaHome+'/Images/download-google_tcm584-902039.gif"></img>Google earth can not be loaded. Download Google Earth Plugin here. Only supported by IE and Firefox.</a></div>");
		$("#map2").prepend("<div class=\"no-plugin\"></div>");
		addSimulation();
		if (initializedCallback) {
			initializedCallback()
		}
	}
}

// END INIT =============================================================================

//helpers ===============================================================================
function centreOnJourney (usePan) {
	map1.closeExtInfoWindow();
	//zoomLevel = map1.getBoundsZoomLevel(bounds);			//get zoom level for resetting when simulation starts (see simStart)
	//mapCenter = bounds.getCenter();								//get center for resetting when simulation starts (see simStart)
	//map1.setCenter(routebounds.getCenter(map1), map1.getBoundsZoomLevel(routebounds));
	if (usePan) {
		map1.setZoom(map1.getBoundsZoomLevel(routebounds))
		map1.panTo(routebounds.getCenter(map1));
	} else {
		map1.setCenter(routebounds.getCenter(map1), map1.getBoundsZoomLevel(routebounds));
	}
}

function findElementPosition (elem){
	var curleft = curtop = 0;
	if (elem.offsetParent) {
	
		curleft = elem.offsetLeft
		curtop = elem.offsetTop
		while (elem = elem.offsetParent) {
			curleft += elem.offsetLeft
			curtop += elem.offsetTop
		}
	}
	return [curleft,curtop];
}

//covers screen under iframe
function addCoverScreen () {
	$("#container").prepend("<iframe id=\"coverScreen1\" src=\"#\" frameborder=\"0\" style=\"top:" + (30 + $("#header").height()) + "px; height:" + ( 20 + $("#content").height() ) + "px; width:" + ( 10 + $("#content").width() ) + "px; \"></iframe>")
	$(".fadeout").fadeTo(500, 0.5)
}

//removes cover screen
function removeCoverScreen () {
	$("#coverScreen1").remove();
	$(".fadeout").fadeTo(500, 1);
}


function selectPredefinedJourney(journey){
	destroySim();
	$("#from").html(journey.waypoints[0].longAddress);
	$("#to").html(journey.waypoints[journey.waypoints.length - 1].longAddress);
	if ((journey.polylineurl)&&(journey.polylineurl.length>0)) {
		fakeJourney = true;

		$.ajax({
    		type:     "GET",
    		url:      U.config().configOptions.configHome+journey.polylineurl,
    		dataType: "xml",
    		success:   fakeDirections
    	});	
	}
	else {
		fakeJourney = false;
		journeyWaypoints = [];
		for (var i = 0; i < journey.waypoints.length; i++) {
			journeyWaypoints.push(journey.waypoints[i].longAddress);
		}
		loadDirections();
	}
}
//end helpers ===========================================================================

//directions ============================================================================
//load directions
function loadDirections () { //TODO use Utils.loadDirections
	myDirections = new google.maps.Directions();
	google.maps.Event.addListener(myDirections, "load", myDirectionsLoaded); 
	google.maps.Event.addListener(myDirections, "error", function(){ 
		//alert(myDirections.getStatus().code)
	});	
	myDirections.loadFromWaypoints(journeyWaypoints, {getSteps: true, getPolyline: true, locale:"en"});
}

function resetDirState() {
	//Clear everything
	if (map1) {
		map1.closeExtInfoWindow(); // this has to be called before clearOverlays
		map1.clearOverlays();
	}
	if(googleEarthInstance) googleEarthHelpers.clearFeatures();
	destroySim();
	closestMarker = null;
	candidatePoi = [];
	localSearchPoi = [];
    $("#poiScrollPane").empty()	
}

function createStartEndMarkers(startPos,endPos) {
	var startMarker = createMarker(startPos,config.labels.startJourneyLabel,iconData["startend"].iconNormal,null);
	map1.addOverlay(startMarker);
	startMarkerFunc = function() {
			startMarker.openExtInfoWindow(
			map1,
			"startendwindow",
			startMarkerHTML,
			//"<html><body><div class='title'>"+config.labels.startJourneyInfoText+"</div><body><html>",
			{beakOffset: 0, paddingX:25,paddingY:25});
	};
	GEvent.addListener(startMarker, 'click', startMarkerFunc);
	var endMarker = createMarker(endPos,config.labels.endJourneyLabel,iconData["startend"].iconNormal,null);
	map1.addOverlay(endMarker);
	endMarkerFunc = function() {
		endMarker.openExtInfoWindow(
		map1,
		"startendwindow",
		endMarkerHTML,
		//"<div class='title'>"+config.labels.endJourneyInfoText+"</div>",
		{beakOffset: 0, paddingX:25,paddingY:25});			
	};
	GEvent.addListener(endMarker, 'click', endMarkerFunc);	
	if (googleEarthInstance) {
		//Create Earth start/end markers
		googleEarthHelpers.createPointPlacemark(startPos, {
			description: "",
//			standardIcon: "dd-start"
			icon:mediaHome+"/Images/dd-start_tcm584-902025.png"
		});
		googleEarthHelpers.createPointPlacemark(endPos, {
			description: "",
//			standardIcon: 'dd-end'
			icon:mediaHome+"/Images/dd-end_tcm584-902024.png"
		});
	}	
}



function createGoogleEarthRoute() {
	var lineStringKml = '<LineString><coordinates>\n';
	for (var i = 0; i < path.length; i++) {
		lineStringKml += path[i].loc.lng().toString() + ',' + path[i].loc.lat().toString() + ',0.5\n';
	}
	lineStringKml += '</coordinates></LineString>';
	var routeLineString = googleEarthInstance.parseKml(lineStringKml);
	routeLineString.setTessellate(true);
	var routePlacemark = googleEarthInstance.createPlacemark("");
	routePlacemark.setGeometry(routeLineString);
	routePlacemark.setStyleSelector(googleEarthHelpers.createLineStyle({
		width: 6,
		color: "88ff0000"
		//color: "88BBEB1B"
	}));
	googleEarthInstance.getFeatures().appendChild(routePlacemark);	
}

function updateJourneyStats() {
	var meters = U.carCalculations( config.carData[U.config().baseCarID], journeyDuration, journeyLength, config.configOptions.useMetric, config.labels )
	$("#distance")       .html( meters.distance.toString() + config.labels.distance );
	$("#time")           .html( meters.time ); // exception: not amount.
	$("#fuelConsumption").html( meters.fuelConsumption.toString() + config.labels.volume );
	$("#co2Emission")    .html( meters.co2Emission.toString() + config.labels.mass );

    U.safeCall(
        isGaugesLoaded,
        function() {
            gaugeLexusFC.setGauge(0.3, 2);
            gaugeLexusCE.setGauge(0.3, 2);             
        }
    )
}

//Initialization after directions are loaded
function myDirectionsLoaded() {


	
	journeyURL =  "?";
	for (var p = 0; p < journeyWaypoints.length; p++) {
		journeyURL += ((p==0) ? "" : "&") + "wp=" + journeyWaypoints[p]
	}
	journeyURL = homePage + encodeURI(journeyURL);
	directionsLoaded = true;
	resetDirState();
	
	var points = []; 
	var poly = myDirections.getPolyline(); 
	for (var i = 0; i < poly.getVertexCount(); i++) { 
		points[i] = poly.getVertex(i); 
	} 
	
	var mypoly = new GPolyline(points, "#000000", 5, 1); 
	map1.addOverlay(mypoly);
	journeyLength = myDirections.getDistance().meters || 1000
	journeyDuration = myDirections.getDuration().seconds
	routebounds = myDirections.getBounds();
	createStartEndMarkers(points[0],points[points.length-1]);
	centreOnJourney();
	buildPathStepArrays();	
	createSimulator();
	createPOI( routebounds.getCenter() ,  myDirections.getDistance().meters*config.configOptions.distanceFactor );
	
	mapMarker = new GMarker(points[0], {icon: carIcon,zIndexProcess:function(){return 1}});
	map1.addOverlay(mapMarker);
	if (googleEarthInstance) createGoogleEarthRoute();
  	flyToLatLng(points[0]);
  	startMarkerFunc();
	updateJourneyStats();
	map1.setCenter(points[0], map1.getBoundsZoomLevel(routebounds));
}	



function fakeDirections(xml) {

	journeyURL =  "";
	directionsLoaded = true;
	resetDirState();
	
	var points = []; 
	$(xml).find('point').each(function(){
		var $j = $(this)
		points.push(new GLatLng(parseFloat($j.attr('lat')),parseFloat($j.attr('lon'))));
	});
	
	var mypoly = new GPolyline(points, "#000000", 5, 1); 
	map1.addOverlay(mypoly);
	journeyLength = mypoly.getLength();
	journeyDuration = 0;
	routebounds = mypoly.getBounds();
	createStartEndMarkers(points[0],points[points.length-1]);
	centreOnJourney();
	buildFakePathStepArrays(points)
	createSimulator();
	createPOI( routebounds.getCenter() ,  journeyLength*config.configOptions.distanceFactor );
	
	mapMarker = new GMarker(points[0], {icon: carIcon,zIndexProcess:function(){return 1}});
	map1.addOverlay(mapMarker);	
	if (googleEarthInstance) createGoogleEarthRoute();
	flyToLatLng(points[0]);
	startMarkerFunc();
	updateJourneyStats();
	map1.setCenter(points[0], map1.getBoundsZoomLevel(routebounds));
}

function buildPathStepArrays(){

	path = [];
	
	var polyline = myDirections.getPolyline();
	var r;
	var traveledDistance = 0;
	var usableTraveledDistance = 0;
	var numRoutes = myDirections.getNumRoutes() ;
	
	var thisIndex = 1;
	var thisVertex;
	var prevVertex = polyline.getVertex(0);
	var distance;
	var stepDistance;
	var step;
	
	var usableDistance = 0
	//var skipMatchExp = /\bferry|train|boat\b/i
	
	var skipMatchExp = /^(Take the .* (train|ferry|boat))/i
	
	for (r = 0; r < numRoutes; r++) {
		var route = myDirections.getRoute(r);
		for (var s = 0; s < route.getNumSteps(); s++) {
			step = route.getStep(s);
			if (skipMatchExp.test(step.getDescriptionHtml())) {
			}
			else {
				usableDistance += step.getDistance().meters;
			}
		}
	}	
	journeyLength = usableDistance;
	//Lexus CC POI injector setup
	var carPOIcount = config.carPOI.length;
	var journeyDistance = myDirections.getDistance().meters;
	var distancePerPOI = usableDistance / (carPOIcount+1);
 	distancePerPOI = Math.floor(distancePerPOI);
	var poiCounter = 0;
	
	for (r = 0; r < numRoutes; r++) {
		var route = myDirections.getRoute(r);
		
		var firstStep = true;
		var stepIndex = 0;
		var nextStepVertexIndex;
		var skip = false
		var lastIndex = (r==numRoutes-1) ? polyline.getVertexCount() : myDirections.getRoute(r+1).getStep(0).getPolylineIndex();
		
		while (thisIndex<lastIndex) {
			
			if ((firstStep)||(thisIndex==nextStepVertexIndex)) {
				step = route.getStep(stepIndex++);
				nextStepVertexIndex = (stepIndex == route.getNumSteps()) ? -1 : route.getStep(stepIndex).getPolylineIndex();
						
				stepDistance = step.getDistance().meters;
				firstStep = false;
				
				skip = skipMatchExp.test(step.getDescriptionHtml())
			}
			
			thisVertex = polyline.getVertex(thisIndex);
			distance = thisVertex.distanceFrom(prevVertex);
			path.push({
				loc: prevVertex,
				distance: distance,
				duration: step.getDuration().seconds * distance / stepDistance,
				skip: skip
			});
			
			traveledDistance += distance;
			if (!skip) usableTraveledDistance += distance;
			if ((poiCounter < carPOIcount) && (usableTraveledDistance > (distancePerPOI * (poiCounter + 1)))) {
				var nextcarPOI = config.carPOI[poiCounter++];
				nextcarPOI.dist = 0; //Fix this
				nextcarPOI.latlng = prevVertex;
				candidatePoi.push(nextcarPOI);
			}
			
			prevVertex = thisVertex;
			thisIndex++;
		}
	}
	path.push({
		loc: prevVertex,
		distance: distance,
		duration: step.getDuration().seconds * distance / stepDistance
	});
}

function buildFakePathStepArrays(points){
	path = [];
	
	var thisVertex;
	var prevVertex;
	var first = true;
	var distance
	//Lexus CC POI injector setup
	var carPOIcount = config.carPOI.length;
	var distancePerPOI = journeyLength / (carPOIcount+1);
 	distancePerPOI = Math.floor(distancePerPOI);
	var poiCounter = 0;
	var traveledDistance = 0;
	
	var polylinelength = points.length;
	for (var i=0; i<polylinelength; i++) {
		thisVertex = points[i];
		if (!first) {
			distance = thisVertex.distanceFrom(prevVertex);
			path.push({
				loc: prevVertex,
				distance: thisVertex.distanceFrom(prevVertex),
				duration: 60
			});
			traveledDistance += distance;
			journeyDuration += 60;
			if ((poiCounter < carPOIcount) && (traveledDistance > (distancePerPOI * (poiCounter + 1)))) {
				var nextcarPOI = config.carPOI[poiCounter++];
				nextcarPOI.dist = 0; //Fix this
				nextcarPOI.latlng = prevVertex;
				candidatePoi.push(nextcarPOI);
			}
		}
		first = false;
		prevVertex = thisVertex;		
	}
}

function createSimulator () {
  	destroySim(); 
	simulator = new DDSimulator(path, {
	on_tick: function() {
		framecount++;
		syncViewsWithSimulator();
		displayClosestPOI(simulator.currentLoc,true);	
	},
	on_changeStep: function(stepNum) { },
	on_finish: function() { 
		stopSim();
		resetSimulatorBeforeStart = true;
		if (endMarkerFunc) endMarkerFunc(); },
		
	on_skip: function() { 
		stopSim();
		var marker = createMarker(routebounds.getCenter(map1), "", null);
		marker.openExtInfoWindow(
			map1,
			"warningwindow",
			"<html><body><div class='title'>"+config.labels.journeyWarning+"</div><body><html>",
			{beakOffset: 15, paddingX:25,paddingY:25});	
		
		return false;
	},
	after_skip:function() { 
		setTimeout(startSim, 8000);
		return false
	}
	});
	
	//set speed
	try { $("#slider").slider("option", "value", simulatorDefaultSpeed); } catch(err) {}
	simulator.options.speed = getSpeed(simulatorDefaultSpeed);
	//local init of stuff..	
	
	if (googleEarthInstance) {
			googleEarthInstance.getFeatures().appendChild(modelPlacemark);
			myDrive(path[0].loc,googleEarthHelpers.getHeading(path[0].loc, path[1].loc));
			window.google.earth.addEventListener(googleEarthInstance, 'frameend', simulator.tickListener);
	} 
	else { interval = setInterval ( simulator.tickListener, 1); }
	framecount = 0;
	$("#startStopButton").attr("class", "start").unbind('click').click(function(){startSim(true);}); 
	//resetViewState();
}

function syncViewsWithSimulator(){
	mapMarker.setLatLng(simulator.currentLoc);
	myDrive(simulator.currentLoc,simulator.currentHeading);
	var type = config.configOptions.carIconType;
	if (type == "fixed") {
	
	} else if (type == "leftright") {
		mapMarker.setImage(simulator.currentHeading < 0 ? lexusLeft : lexusRight);	
	} else {
		var imgCount = 15
		var seg =  Math.round( 360/imgCount )
		var h = Math.ceil((simulator.currentHeading - (seg / 2)) / seg);
		if (h<0) h = imgCount+h+1
		
		var img = '';
		switch (h) {
			case 0:img = ($.browser.msie && $.browser.version < 7) ? "/Images/0_tcm584-901896.gif" : "/Images/FL-CO-0_tcm584-901897.png";break;
			case 1:img ="/Images/FL-CO-1_tcm584-901919.png";break
			case 2:img = "/Images/FL-CO-2_tcm584-901929.png";break;
			case 3:img = "/Images/FL-CO-3_tcm584-901930.png";break;
			case 4:img = "/Images/FL-CO-4_tcm584-901931.png";break;
			case 5:img = "/Images/FL-CO-5_tcm584-901932.png";break;
			case 6:img = "/Images/FL-CO-6_tcm584-901933.png";break;
			case 7:img = "/Images/FL-CO-7_tcm584-901934.png";break;						
			case 8:img = "/Images/FL-CO-8_tcm584-901935.png";break;
			case 9:img = "/Images/FL-CO-9_tcm584-901936.png";break;
			case 10:img = "/Images/FL-CO-10_tcm584-901920.png";break
			case 11:img = "/Images/FL-CO-11_tcm584-901922.png";break;
			case 12:img = "/Images/FL-CO-12_tcm584-901924.png";break;
			case 13:img = "/Images/FL-CO-13_tcm584-901926.png";break;
			case 14:img = "/Images/FL-CO-14_tcm584-901927.png";break;
			case 15:img = "/Images/FL-CO-15_tcm584-901928.png";break;

		}
		
		//mapMarker.setImage(mediaHome+'icons/caroverhead/' + h + '.png');
		mapMarker.setImage(mediaHome+img);
	}
}

function createPOI ( center , filterDistance ) {

	$.each(customPOI, function(i, loc){
		var dist = center.distanceFrom(loc.latlng);
		if (dist <= filterDistance) {
			//Clone the POI and enrich with distance
			candidatePoi.push({
				"id": loc.id,
				"cat": loc.cat,
				"latlng": loc.latlng,
				"dist": dist,
				"marker": null,
				"shortTxt": "some short txt",
				"longTxt": "some long txt",
				"url": null,
				isVisited: false,
				hasBeenClosest: false
			});
		}
	});
	
	candidatePoi.sort(function(a, b) { return a.dist - b.dist });
	
	//Create all the markers & build poi markup
	var poiMarkup = "";
  	$.each(candidatePoi, function(i, loc) { 
  		var marker = createMarker(loc.latlng, loc.title, iconData[loc.cat].iconNormal, 
			function() { 
	        	flyToLatLng(loc.latlng); 
	        	highlightPoi(loc.id, true);
				showCarInfo(loc.id);
	        	}
	    	); 
		var cat    = config.categories[loc.cat];
		
		if (googleEarthInstance&&config.configOptions.displayIconsOnEarth) {
			googleEarthHelpers.createPointPlacemark(loc.latlng, {
			description: "",
			icon:iconData[loc.cat].iconNormalFN
			});
		}
		
		loc.marker = marker;		
		map1.addOverlay(marker);
        if (loc.cat == "cc") {
            var divClass = "lexus",
                divText  = loc.title,
                divText2 = loc.subText,
                imageurl = loc.imageurl
        }
        else {
            var divClass = "general",
                divText  = "",
                divText2 = "Address"
                imageurl = cat.imageurl
        }

        poiMarkup += 
                '<div id="' + loc.id + '" class="item"> \n' + 
                    '<div class="poi-title ' + divClass + '">' + divText + '</div> \n' +
        		    '<div class="poi-content"> \n' + 
        			    '<div class="left-column"><div class="text">' + divText2 + '</div><a href="#">'+config.labels.viewOnMap+'</a></div> \n' +
        			    '<div class="right-column"><img src="' + imageurl + '" alt="" /></div> \n' +
        			'</div> \n' + 
        		'</div> \n';
        				
		if (loc.cat != "cc") {
			var lpContentURL = loc.id.replace(/fl_/,"") + ".xml";

			$.ajax({
				type: "GET",
				url: appRoot+config.configOptions.customPOIdetailLocation+lpContentURL,
				dataType: "xml",
				success: function(xml) {
					$(xml).find("copy[locale='en']").each(function() {
						$("#" + loc.id + " div:first").append($(this).find('title').text());
					});
				}
			});
		}
	});
	
	// inject markup & register events
	$("#poiScrollPane")	
                    .html( poiMarkup )
                    .unbind('click')
                    .click(function(event) {
            event.preventDefault()
            if (event.target.tagName === 'A') {
                var poiId = $(event.target).parents('.item').attr('id')
                highlightPoi( poiId );
                showCarInfo( poiId , "_journey" );
				//U.track("WT.pn=Car features","WT.ti="+$(event.target).parents('.item').find('.poi-title').text()+"_journey");
                // TODO showPoiInfo
            }
        })
	
	initPoiScrollPane(); // reinitialize scrollpane
	
	closestLexusDealer = null;
	
	if (window.itg) {
		var closestDist = 9999999999;
		$.each(window.itg.dealers.dealer, function(i, dealer) {
			dealer.marker = null;
			var dist = center.distanceFrom(dealer.latlng);
			if (dist < closestDist) {
				closestLexusDealer = dealer;
				closestDist = dist; 
			}
			if (dist <= filterDistance) {
				createDealerOnMap(dealer)
			}
		})
		createDealerOnMap(closestLexusDealer)
	}
	
	if (config.configOptions.useLocalSearch) {
		for ( var cat in config.categories ) {
			doLocalSearch(cat, config.categories[cat]);
		}
	}		
}

function createDealerOnMap(dealer) {
	if (dealer.marker != null) {
		return;
	}
	var marker = createMarker(dealer.latlng, dealer.name, iconData[dealer.cat].iconNormal, 
		function() { 
        	flyToLatLng(dealer.latlng); 
                var centreImg = ($.browser.msie && $.browser.version < 7) ? "/Images/lexus_center_off_tcm584-936387.gif" : "/Images/lexus_center_off_tcm584-902153.png";
                var dealerURL = "";
                if (dealer.url != "")
                {
                    dealerURL = (dealer.url.indexOf("http://") > -1) ? dealer.url : "http://"+dealer.url;
                }
			marker.openExtInfoWindow(
  				map1,
  				"lexuswindow",
  				"<img class='icon' alt='' src='"+mediaHome+centreImg+"'/><div class='title'>"
				 + dealer.name + "</div>" + "<div class='address'>" + dealer.address
				 + "<br>" + dealer.city
				 + "<br>" + dealer.zipcode 
				 + "<br><span class='extraheight'>"+config.labels.telephoneAbbr+":"+dealer.phone+"</span>"
				 + "<br><span class='extraheight'>"+config.labels.faxAbbr+":"+dealer.fax+"</span>"
				 + "<br><span class='extraheight'>"+config.labels.emailAbbr+":"+dealer.email+"</span>"
				 + "<br><a class='dealerlink' target='_blank' href='"+dealerURL+"'>"+config.labels.lexusDealerLink+"</a>" 
				 + "</div><div class='hr'><hr/></div><a class='sharelink' href='#' onclick='tb_show(\""+config.labels.dialogCaption+"\", \""+U.createShareUrl('',dealer.url)+"\");'><img src='"+mediaHome+"/Images/cross-yellow_tcm584-902013.gif' width='7' height='7'/><span>"+config.labels.share+"</span></a>",
  				{paddingX:20,paddingY:25}  
			); 
        	}
	); 
	map1.addOverlay(marker);
	dealer.marker = marker;
	return;
}

function doLocalSearch (catid,cat) {

	if (!cat.active || !cat.searchterm || cat.searchterm.length==0) return;
	var searchControl = new google.search.SearchControl();
	searchControl.setResultSetSize(google.search.Search.LARGE_RESULTSET);
    var ls = new google.search.LocalSearch();
	ls.setCenterPoint(map1);

    var options = new google.search.SearcherOptions();
    options.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);
    searchControl.addSearcher(ls, options);

    searchControl.setSearchCompleteCallback(this, 
		function (searchControl ,searcher) {
			var thisResult = [];
			$.each(searcher.results,function(i,result) {
				if (filterText(result.titleNoFormatting)) {
					var location = new GLatLng(parseFloat(result.lat), parseFloat(result.lng));
					var marker = createMarker(location, result.titleNoFormatting, iconData[catid].iconNormal);//, function(){
					//	map1.openInfoWindowHtml(location, "<b>" + result.titleNoFormatting + "</b>" + "<br>" + result.streetAddress + "<br>" + result.city + "<br>");
					//  .region						
					//	flyToLatLng(location);
					//});
					GEvent.addListener(marker, 'click', function(){
						pauseSim();
						marker.openExtInfoWindow(
              			map1,
              			"poiwindow",
              			"<img class='icon' alt='' src='"+cat.iconon+"'/><div class='title'>" + result.titleNoFormatting + "</div>" + "<div class='address'>" + result.streetAddress + "<br>" + result.city + "<br></div><div class='hr'><hr/></div><a href='#' onclick='tb_show(\""+config.labels.dialogCaption+"\", \""+U.createShareUrl('',result.url)+"\");'><img src='"+mediaHome+"/Images/cross-yellow_tcm584-902013.gif' width='7' height='7'/><span>"+config.labels.share+"</span></a>",
						//onclick="openShare(homePage)";
              			{paddingX:20,paddingY:25}
            		); 
					flyToLatLng(location);
					});
					thisResult.push(marker);
					localSearchPoi.push({
						"cat": catid,
						marker: marker
					});
					
					map1.addOverlay(marker)
					
					if (googleEarthInstance&&config.configOptions.displayIconsOnEarth) {
						googleEarthHelpers.createPointPlacemark(location, {
							description: result.titleNoFormatting,
							icon:mediaHome+iconData[catid].filename+"_earth.png"
							//icon:appRoot+iconData[catid].iconNormalFN
						});
					}
					
				}			
			} );
		}
	);
    searchControl.draw(null);
    searchControl.execute(cat.searchterm);
}

function filterText (text) {
	for (var i = 0; i < config.regExpFilters.length; i++) {
		if (config.regExpFilters[i].test(text)) {
			return false;
		}
	}
	return true;
}

function createMarker (posn, title, icon, clickFunc) {
    var marker = new GMarker(posn, {title: title, icon: icon, draggable:false });
	if (clickFunc) GEvent.addListener(marker, 'click', clickFunc);
    return marker;
}	

function getClosestMarker ( latlng, includeLexusContent ) {
	var mkr = null;
	var closestdist = 10000000;
	$.each(candidatePoi, function(i,marker){ 
		var dist = latlng.distanceFrom(marker.latlng);
		if (dist < closestdist) {
			if (!includeLexusContent && (marker.cat == "cc")) {
				//just ignore?
			}
			else {
				closestdist = dist;
				mkr = marker;
			}
		}
  	});
	return mkr;
}
//end directions ============================================================================


//helpers ============================================================================
/* Move the camera to the given location, staring straight down, and unhighlight all items in the left directions list
	@param {google.maps.LatLng} loc The location to fly the camera to */ 
function flyToLatLng (loc) {
	if(googleEarthInstance == null) { return; }
	var la = googleEarthInstance.createLookAt('');
	la.set(loc.lat(), loc.lng(),
     	10, // altitude
     	googleEarthInstance.ALTITUDE_RELATIVE_TO_GROUND,
     	0, // heading
     	60, // tilt
     	200 // range (inverse of zoom)
  	);
	googleEarthInstance.getView().setAbstractView(la);
}
//end helpers ============================================================================

//simulation =============================================================================
function addSimulation () {
	$("#resetButton").click(
        function() { 
			createSimulator();	
			resetViewState();	
			startSim(); 	
			return false;		 			
        }
	);  
	initSpeedSlider();
}

function resetViewState() {
    $("#poiScrollPane")[0].scrollTo(0)
	if (closestMarker) { closestMarker.marker.setImage(iconData[closestMarker.cat].iconNormalFN); }
	closestMarker = null;
	syncViewsWithSimulator();
}

function destroySim() {
	if (!simulator) return;
	stopSim();
	if (googleEarthInstance ) {
  		googleEarthInstance.getFeatures().removeChild(modelPlacemark);
		try {
			window.google.earth.removeEventListener(googleEarthInstance, 'frameend', simulator.tickListener);
		} catch (e) {}
	} else { 
		window.clearInterval (interval); 
		//document.getElementById( "earthReplacementVideo" ).Rewind();
	}
  	simulator = null;
}

function startSim (isClicked) {
	if (!simulator) return;
	if (isClicked) U.track("WT.pn=Main screen","WT.ti=Start Driving"); 
  	if (resetSimulatorBeforeStart) {
		createSimulator();	
		resetViewState();
		resetSimulatorBeforeStart = false;
	}
	centreOnJourney(true);	
		
	if (googleEarthInstance) {
		oldFlyToSpeed = googleEarthInstance.getOptions().getFlyToSpeed();
		googleEarthInstance.getOptions().setFlyToSpeed(googleEarthInstance.SPEED_TELEPORT);
  	} else {
		try {   document.getElementById( "earthReplacementVideo" ).playflv();
		}
		catch(err) {}
	}
	
	$("#startStopButton").attr("class", "stop").unbind('click').click(function(){stopSim();}); 

	simulator.start();
}

function pauseSim(){
	if (!simulator) return;	
	$("#startStopButton").attr("class", "start").unbind('click').click(function(){startSim();}); 
	
	if (googleEarthInstance) {
	} else {
		try {   document.getElementById( "earthReplacementVideo" ).pauseflv();
		}
		catch(err) { }
	}
	simulator.pause();
}

function stopSim () {
	if (!simulator) return;
	$("#startStopButton").attr("class", "start").unbind('click').click(function(){startSim();});
	if (googleEarthInstance) {
		googleEarthInstance.getOptions().setFlyToSpeed(oldFlyToSpeed);
	} else {
		try {   document.getElementById( "earthReplacementVideo" ).pauseflv();
		}
		catch(err) { }
	}
	simulator.stop();
}

function loadModel(loadedCallback) {
	var host = location.protocol + "//" + location.hostname
	host = host.replace("preview", "acceptance")
	host = host.replace("sitebuilder.", "")

	var locationKmzFile = host + mediaHome + config.configOptions.carModel;
	window.google.earth.fetchKml(
      	googleEarthInstance,
      	locationKmzFile,
	    function(kml) {
			if (kml != null)
                                                {
                                                     // alert('kml IS visible');
			     modelPlacemark = kml.getFeatures().getFirstChild();
			     modelPlacemark = kml.getFeatures().getChildNodes().item(1);		  
			     model = modelPlacemark.getGeometry();
		                     model.setAltitudeMode(googleEarthInstance.ALTITUDE_RELATIVE_TO_GROUND);			  
                                                 } else {
                                                     // KML not available, trigger Flash
                                                     // alert('kml NOT visible\nlocation.hostname: '+location.hostname+'\nhost: '+host+'\nlocationKmzFile: '+locationKmzFile);
                                                     config.configOptions.useGoogleEarth = false;
                                                     googleEarthInstance = null;
                                                     initGoogleEarth(null);
                                                 }

	                     if (loadedCallback) {
	                          loadedCallback()
	                     }
	    }
	);
}

function displayClosestPOI (loc,includeLexusContent) {
	var mkr = getClosestMarker(loc,includeLexusContent);
	if (!mkr) {
		closestMarker = null;
		return;
	}
	if (mkr != closestMarker) {
		if (closestMarker) closestMarker.marker.setImage(iconData[closestMarker.cat].iconNormalFN);
		closestMarker = mkr;
		closestMarker.marker.setImage(iconData[closestMarker.cat].iconHighlightFN);
		highlightPoi( closestMarker.id, true )
	}	
	if (!closestMarker.isVisited) {
		var dist = loc.distanceFrom(closestMarker.latlng);
		//check for dist changed from<10 as nodes being missed due to size of steps with increased speed
		if (dist<150) {
			if (config.configOptions.stopSimAtContent) {
				closestMarker.isVisited = true;
				showCarInfo(closestMarker.id);
			}
		}
	}
}

function myDrive (loc, heading) {
	if(googleEarthInstance == null) return;
	model.getLocation().setLatLngAlt(loc.lat(), loc.lng(), 1);
	model.getOrientation().setHeading(heading);
	myMoveToPointDriving(loc, heading);
}

function myMoveToPointDriving (loc, heading) {
	var oldLa = googleEarthInstance.getView().copyAsLookAt(googleEarthInstance.ALTITUDE_RELATIVE_TO_GROUND);
	var curHeading = oldLa.getHeading();
	var desiredHeading = heading;
  
	var curRange = oldLa.getRange();
	var desiredRange = Math.max(20.0, simulator.currentSpeed * 10);
  
	var la = googleEarthInstance.createLookAt('');
	la.set(loc.lat(), loc.lng(),
		0, // altitude
      	googleEarthInstance.ALTITUDE_RELATIVE_TO_GROUND,
      	curHeading + myGetTurnToDirection(curHeading, desiredHeading),
      	60, // tilt
      	curRange + (desiredRange - curRange) * 0.1 // range (inverse of zoom)
     );
	googleEarthInstance.getView().setAbstractView(la);
}

function myGetTurnToDirection (heading1, heading2) {
	if (Math.abs((heading1) - (heading2)) < 1) { return heading2 - heading1; }
	return (googleEarthHelpers.fixAngle(heading2 - heading1) < 0) ? -1 : 1;
}

function getSpeed(index)
{
    var speeds = [0.75,1,2,4,8,16,32,48,64];
    return speeds[index];
}

//init speed slider
function initSpeedSlider () {
    var speedIcons = $("#rightColumn div.slider-left").html().indexOf("speedSlower")

    if (speedIcons < 0) 
    {	$("#rightColumn div.slider-left").append('<img id="speedSlower" src="/Images/btn-minus_tcm584-901994.gif" width="11" height="10" alt=""/>');
    	$("#rightColumn div.slider-right").append('<img id="speedFaster" src="/Images/btn-plus_tcm584-901995.gif" width="11" height="10" alt=""/>');
    	$("#slider").slider({
    	    min:    simulatorMinimumSpeed,
	    max:    simulatorMaximumSpeed,
	    value:  simulatorDefaultSpeed,
                    step: simulatorStep,
	    change: function(event, ui) {
	        if (simulator) { simulator.options.speed = getSpeed(ui.value) }
	    }
	})
		$("#speedSlower, #speedFaster").click(function(event) {
	    event.preventDefault()
	    if (simulator) {
	        
	        //var newSpeed = simulator.options.speed + ( $(event.target).attr("id") === "speedFaster" ? +1 : -1 )
	        var newSpeed = $("#slider").slider("option", "value") + ( $(event.target).attr("id") === "speedFaster" ? +1 : -1 )
	        //alert(newSpeed);
	        
	        if (newSpeed < simulatorMinimumSpeed || newSpeed > simulatorMaximumSpeed) { return } //check speed is within the range
	        $("#slider").slider("option", "value", newSpeed)
	        simulator.options.speed = getSpeed(newSpeed);
	    }
	})
    }
    else {
        //alert("already added");
    }
}
//end simulation =============================================================================

// poi =======================================================================================

function showCentralFrame(frameSrc) {
    pauseSim(); // always pause simulation when central frame is opened
	addCoverScreen();
	iFrameNumber = iFrameNumber + 1;
		$("#container").prepend(
			'<div id="iFrameHolder" style="top:118px;">' + 
				'<iframe scrolling="no" name="central-frame'+ iFrameNumber +'" class="central-frame" id="central-frame'+ iFrameNumber +'" src="' + frameSrc + '" frameborder="0"></iframe>' +
			'</div>');
		$("#iFrameHolder").fadeIn();
	
}

function hideCentralFrame(onclose) {
    removeCoverScreen();

    //tt#158 don't remove iFrame until we're at least on the map! otherwise removes welcome screen!
    // when the welcome intro is first called the afterWelcomeInitialized is false but 
    // we pass in onclose so need to check for both
    if((afterWelcomeInitialized) || (onclose != undefined))
    {   $("#iFrameHolder").fadeOut(300, function() { 
            $("#iFrameHolder").remove();		
            maybeResumeSimulation() // resume simulation if it was paused
            if (onclose) { 
                onclose()
            }
        });
    }
}




function onCentralFrameClose () {
    hideCentralFrame()
	$("a").removeClass('selectedbtn');
}

function showCarInfo (id,trackingPrepend) {
		for (var i=0; i<config.carPOI.length; i++) {
			if (config.carPOI[i].id == id) {
				//MS:removed tracking - done at page level
				//if (trackingPrepend) U.track("WT.pn=Car features","WT.ti="+config.carPOI[i].tracking+trackingPrepend); 
				showCentralFrame(config.carPOI[i].contenturl);
				return;
			}
		}
	}

function showGallery (html) {	
    showCentralFrame( html )
}

function highlightPoi(poiId, scrollTo) {
    var poiIdNumber = poiId.split("_")[1];
    var currentPoi = $("#" + poiId);
    var currentPoiHeight  = currentPoi.outerHeight();
    var poiHeightRemaining = 0;
    
    //get remaining heights...
    currentPoi.nextAll().each( function() {
        poiHeightRemaining = poiHeightRemaining + $(this).outerHeight();	 
    })

    poiHeightRemaining += currentPoiHeight
	 
	$("#poiScrollPane .item").removeClass("highlight");
	if (poiId) {
	    $("#" + poiId).addClass("highlight");

	    if (scrollTo) {
	    
	        var poiScrollPaneHeight = $("#poiScrollPane").parent().height();
	        
	        if (poiHeightRemaining > poiScrollPaneHeight) {
                $("#poiScrollPane")[0].scrollTo("#" + poiId)
	        }
	        else { //calculate the scroll to element (try catch, if height less throws exception 
	            try {   $("#poiScrollPane")[0].scrollTo(( $("#poiScrollPane").outerHeight() - poiScrollPaneHeight )); }
	            catch (err){ }
	        }
        }
    }  
}

// end poi =======================================================================================


function SWFReplace() {  
	var myfont = { src: mediaHome+"/Images/Nobel_Light_SIFR_CE_tcm584-615859.swf"};     
	sIFR.activate(myfont);  
	//sIFR.replace(myfont, {selector: 'h3.xxx'});	
	//a.compare-cars
	//span.replace-me
	sIFR.replace(myfont, {selector: 'a.compare-cars', 
	//css: [
	//	'.sIFR-root {color: #FFFFFF}; a {color:#222222};'
	//],
	css: [ 	 '.sIFR-root { color: #FFFFFF; background-color:transparent; opacity=0;  }'
			,'a { color: #FFFFFF; text-align: center; text-decoration: none; opacity=0; }'
			,'a:link { color: #FFFFFF; opacity=0;}'  
			,'a:hover { color: #FFFFFF; opacity=0; }' //text-decoration: underline;
	],

	wmode: 'transparent' });	
} 

function findAppRoot() {
    var appRoot
	if (window.location.toString().length == (window.location.toString().lastIndexOf("/") + 1)) { 
	    appRoot = window.location 
	}
	else { 
	    appRoot = window.location.toString().substr(0, window.location.toString().lastIndexOf("/")) + "/" 
	};
	return appRoot
}

function initBeforeWelcome() {
	addShowHidePanels();
	initWidgets();	
	initGauges();	
	initFilterPoi();
	initOther();
}

function initAfterWelcome(callback) {
    
    // helpers
    function updateProgress (text) {
		$("#loading-bar p.copy", frames['central-frame'+ iFrameNumber].document).text(text);
    }
    function cascadeFadeIn (idx, arr, callback) {
        if(idx < arr.length) {
            var e = arr[idx]
            $(e[0]).fadeIn(skipWelcome?0:loaddelay, function() {
                if (!skipWelcome) {
                    updateProgress(e[1])
                }
                cascadeFadeIn(idx + 1, arr, callback)
            })
        }
        else {
            callback()
        }
    }
    
	removeCoverScreen();
    $('#headerDropDowns, #leftColumn, #rightColumn, #centerColumn').show()

	if (skipWelcome == false) {
    	updateProgress(config.labels.loading0);
    	$("#loading-bar p.copy", frames['central-frame'+ iFrameNumber].document).show();
		$("#loading-bar p.image", frames['central-frame'+ iFrameNumber].document).append('<img src="'+mediaHome+'/Images/loader02_tcm584-902166.gif" />');
	}
	
	// fade in elements one after another
	cascadeFadeIn(
	    0, 
	    [
	        ['#yourCar', config.labels.loading1],
	        ['#yourJourney', config.labels.loading2],
	        ['#stats', config.labels.loading3],
	        ['#GEHolder', config.labels.loading4],
	        ['#pointsOfInterests', config.labels.loading5],
	        ['#filterPoi', config.labels.loading6]
	     ],
	     function() { // after all emelements faded in
			$('#map1').show(loaddelay, function() {
				function _doInit () {
					initMaps();
					initGoogleEarth(function() {
						var drive_in = new SWFObject(mediaHome+'/Images/TopLeft_tcm584-901696.swf', "car",'130', '56', '8.0.0.0', '#E6E6E6');    
						drive_in.addParam   ("wmode",       "transparent");
						drive_in.write("drive_in"); 
						afterWelcomeInitialized = true
						U.track("WT.pn=Main screen","WT.ti=main")
						if (callback) {
						    callback()
						}
					});
				}
				$('#base-menu-container').fadeIn(300, function() {
					if (skipWelcome) {
						allowLinks = true;
					    _doInit();
					} else {
						hideCentralFrame(function() {
						    _doInit()
						});
					}
				});
			});	         
	     }
	)
}
 
function googleApisLoaded(results) {
    // everything is loaded by now. that is config, google apis.
    config = U.config()
    
    if (google.maps.BrowserIsCompatible()) { // Hurrah
		
		//TODO Hack to load styled CSS after maps is loaded
		$.getScript(javascriptHome + "forward-living/FL-extinfowindow.js", function(){
		    
			initBeforeWelcome()
			
	        var qParams = U.parseQueryStr( document.location.href )
			
			if ((qParams.hasOwnProperty('wp')&&($.isArray(qParams.wp)))) {
				journeyWaypoints = qParams.wp;
				if (qParams.hasOwnProperty('dis')) {
					showCentralFrame(config.configOptions.destinationUrl)
				} else {
					skipWelcome = true;
					$('#from').html( journeyWaypoints[0] );
            		$('#to')  .html( journeyWaypoints[journeyWaypoints.length - 1] );
					initAfterWelcome(loadDirections);
					//loadDirections()				
				}
				return;
			}
			
	        if (qParams.hasOwnProperty('sw')) { // sw = skip welcome
	            skipWelcome = true;
				initAfterWelcome() // go straight to after welcome part
	            return;
	        }
	        else { // show the welcome screen first
	            //MS:added qs value to override page meta
	            //showCentralFrame(config.configOptions.destinationUrl) // Note: welcome page is shown after config is loaded.
	            showCentralFrame(config.configOptions.destinationUrl + "?WT.pn=Welcome&WT.ti=main") // Note: welcome page is shown after config is loaded.
	        }
	});
    }
    else {
        // Oops! 
    }
}

function loadGoogleApis() {
    
    var config = U.config()
    
    var fns = []
    fns.push( function(callback) { google.load("maps",   "2", {"callback" : callback}) } )      // maps
    if (config.configOptions.useLocalSearch) {
        fns.push( function(callback) { google.load('search', '1', {"callback" : callback}) } )  // search?
    }
    if (config.configOptions.useGoogleEarth) {
        fns.push( function(callback) { google.load("earth",  "1", {"callback" : callback}) } )  // earth?
    }
    
    U.multiCall(fns, googleApisLoaded)
}

/**
callbackStr: String - callback function name
*/
function loadGoogleLoader(apiKey, callbackStr) {
    var script = document.createElement('script');
    script.src = 'http://www.google.com/jsapi?key=' + apiKey + '&callback=' + callbackStr;
    script.type = 'text/javascript';
    document.getElementsByTagName('head')[0].appendChild(script);    
}

$(document).ready(function() {
    if (document.URL.search(/#/) == -1) {
    appRoot = findAppRoot() // this is used in multiple places
    appRoot = ""
//    mediaHome = "http://" + window.location.host + "" + mediaHomeExtPath
	mediaHome = appRoot + mediaHomeExtPath;
	configHome = appRoot + configHomeExtPath;
	javascriptHome = appRoot + javascriptHomeExtPath;
	homePage = U.baseURI( window.location.href )
	journeyURL = homePage
	
	if ($.browser.msie && $.browser.version < 7) iconExt = ".gif";
	
                // NG - Updated so CT can swap images
	//lexusRight = mediaHome + "icons/lexus"+iconExt;
                //lexusLeft = mediaHome + "icons/lexusLeft"+iconExt;
	//lexusUp = mediaHome + "icons/caroverhead/0"+iconExt;
	lexusRight = mediaHome + ($.browser.msie && $.browser.version < 7) ? "/Images/lexus_tcm584-902144.gif" : "/Images/lexus_tcm584-902145.png";
                lexusLeft = mediaHome + ($.browser.msie && $.browser.version < 7) ? "/Images/lexusLeft_tcm584-902146.gif" : "/Images/lexusLeft_tcm584-902147.png";
	lexusUp = mediaHome + ($.browser.msie && $.browser.version < 7) ? "/Images/0_tcm584-901896.gif" : "0.png";

	// load config
	U.loadConfig(configHome,mediaHome, function(config) {
		var googleApiKey
		if (/acceptance/i.test(window.location.hostname)) {
			//alert('Setting googleApiKey\nAcceptance detected in ' + window.location.hostname + '(hostname, .host='+window.location.host+'\nSetting to [config.configOptions.googleApiKeyAcceptance]: ' + config.configOptions.googleApiKeyAcceptance)
			googleApiKey = config.configOptions.googleApiKeyAcceptance
		} else if (/preview/i.test(window.location.hostname)) {
			//alert('Setting googleApiKey\npreview detected in ' + window.location.hostname + '(hostname, .host='+window.location.host+'\nSetting to [config.configOptions.googleApiKeyStaging]: ' + config.configOptions.googleApiKeyStaging)
			googleApiKey = config.configOptions.googleApiKeyStaging
		} else {
			//alert('Setting googleApiKey\nNo test detected in ' + window.location.hostname + '(hostname, .host='+window.location.host+'\nSetting to [config.configOptions.googleApiKeyLive]: ' + config.configOptions.googleApiKeyLive)
			googleApiKey = config.configOptions.googleApiKeyLive
		}
	    loadGoogleLoader(googleApiKey, 'loadGoogleApis') 
		config.configOptions.appRoot = appRoot;
		config.configOptions.homePage = homePage;
		config.configOptions.mediaHome = mediaHome;
		config.configOptions.configHome = configHome;
		config.configOptions.javascriptHome = javascriptHome;
	})
}
	})  

/** release; avoid memory leaks */
$(window).unload( function () { 
    if (google && google.maps) {
        google.maps.Unload();
		destroySim();
    }
});

//export public members
return {
    appRoot            : function(){ return appRoot }, // used in geplugin-helpers.js
    findElementPosition: findElementPosition,
    onUpdateJourneyGo  : onUpdateJourneyGo,
    loadGoogleApis     : loadGoogleApis,
    onGaugeLoaded      : onGaugeLoaded,
    onCentralFrameClose: onCentralFrameClose,
    addCoverScreen     : addCoverScreen,
    removeCoverScreen  : removeCoverScreen,
    pauseSim           : pauseSim,  
    myDirections       : function() { return myDirections },
    journeyWaypoints   : function() { return journeyWaypoints },
    journeyDuration	   : function() { return journeyDuration},
    journeyLength	   : function() { return journeyLength}
}

})(jQuery, Utils)

