var mapviewer;
var geocoder;
var route_finder;
var route;
var markers = new Array();
var max_results = 10;
var max_zindex = 1000;
var message;
var geocode_status;
var results_panel;
var original_qs = '';
var original_qs1 = '';
var original_qs2 = '';
var loc = undefined;
var locations = new Array(undefined,undefined);
var location_results = new Array();
var start_pos = new MMLatLon(54.71882,-2.52538); // England.
var start_zoom_level = 6;
var start_map_type = 4;
var route_onload = 0;
var loc_icon = new MMIcon('//media.tiscali.co.uk/images/gfx/trv/maps/icon-circle.png' );
loc_icon.iconSize = new MMDimensions(32, 32);
loc_icon.iconAnchor = new MMPoint(16, 16);

function showAerial(bool) {
  if(bool) {
    mapviewer.addMapType(8);
    mapviewer.addMapType(32);
  } else {
    mapviewer.removeMapType(8);
    mapviewer.removeMapType(32);
  }
}

function onLoad()
{ 
  //Add the map
  if(MMIsSupportedBrowser()) {
    setUpVars();

    mapviewer = new MultimapViewer(document.getElementById('mapviewer'));

    //showAerial(false);

    mapviewer.setMapType(start_map_type);
    mapviewer.goToPosition(start_pos,start_zoom_level);
 
    // Pan and zoom widget.
    var pan_zoom_widget = new MMPanZoomWidget (new MMBox(10,10,undefined,undefined));
    mapviewer.addWidget(pan_zoom_widget);

    // Local info widget.
    var local_info_widget  = new MMLocalInfoWidget (undefined,undefined,new MMBox());
    //mapviewer.addWidget(local_info_widget);

    // Map type.
    var map_type_widget = new MMMapTypeWidget (undefined,new MMBox(),'tiscmaptype');
    //    map_type_widget = new MMMapTypeWidget ( undefined, new MMBox() );
    //    map_type_widget.setContainer ( container );
    var map_type_container = document.getElementById('maptype');
    if(map_type_container) {
      map_type_widget.setContainer(map_type_container);
    }
    mapviewer.addWidget(map_type_widget);
    

    // Overview widget.
    //var overview_widget = new MMOverviewWidget(undefined,new MMDimensions(156,156),undefined,undefined);
    //mapviewer.addWidget(overview_widget);

    mapviewer.setOption('checkcoverage',true);
    mapviewer.setOption('click','zoomin');
  }

  // Set up geocoder.
  geocoder = new MMGeocoder(processResults);
  geocode_status = document.getElementById('geocodestatus');
  message = document.getElementById('message');
  results_panel = document.getElementById('theresults');

  // Set up route finder.
  var funcRef = resultsLoaded;
  route_finder = new MMRouteRequester( funcRef );

  if(typeof(loc) != 'undefined') {
    setMainLocation(loc);
  } else if(locations[0] && locations[1]) {
    route_onload = 1;
    startRoute(true);
  }
  updateURL();

  // Events.
  var ev = new Array('changeZoom','endPan','changeMapType','startRouteRequest','endRouteRequest');
  var i;
  for(i = 0;i < ev.length;i++) {
    mapviewer.addEventHandler(ev[i],updateURL);
  }
 
}

function setUpVars() {
  var params = new Array();
  var data_string = document.location.hash;
  if(data_string.length > 0) {
    data_string = data_string.substring(1);
  }
  var pairs = data_string.split('&');
  var i;
  for(i = 0;i < pairs.length;i++) {
    var pair = String(pairs[i]).split('=');
    if(pair.length == 2) {
      var nm = pair[0];
      var val = pair[1];
      var fields = val.split('|');
      switch(nm) {
        case 'map':
          if(fields.length == 3) {
            var coords = String(fields[0]).split(',');
            if(coords.length == 2) {
              start_pos = new MMLatLon(coords[0], coords[1]);
            }
            start_zoom_level = fields[1];
            start_map_type = fields[2];
          }
          break;
        case 'loc':
          if(fields.length >= 3) {
            var pos = fields[0].split(':');
            if(pos.length == 3) {
              var cc = document.getElementById('country_code');
              if(cc) {
                cc.value = pos[0];
              }
              loc = new MMLocation();
              loc.coords = new MMLatLon(pos[1],pos[2]);
              loc.address = new MMAddress();
              loc.address.country_code = pos[0];
              loc.address.display_name = unescape(fields[2]);
              if(pos.length >= 2) {
                original_qs = unescape(fields[1]);
                var qs = document.getElementById('qs');
                if(qs) {
                  qs.value = original_qs;
                }
              }
            }
          }
          break;
        case 'route':
          var qstrings = new Array('','');
          var dnames = new Array('','');
          var count = 0;
          if(fields.length >= 2) {
            var qs_list = fields[1].split(':');
            if(qs_list.length == 2) {
              for(count = 0;count < 2;count++) {
                qstrings[count] = unescape(qs_list[count]);
                var ob = document.getElementById('qs'+(count+1));
                if(ob) {
                  ob.value = qstrings[count];
                }
              }
              original_qs1 = qstrings[0];
              original_qs2 = qstrings[1];
            }
            if(fields.length >= 3) {
              var dn_list = fields[2].split(':');
              if(dn_list.length == 2) {
                for(count = 0;count < 2;count++) {
                  dnames[count] = unescape(dn_list[count]);
                }
              }
            }
          }
          var points = fields[0].split(';');
          if(points.length == 2) {
            var temp_locations = new Array();
            var num_locs = 0;
            for(count = 0; count < 2; count++) {
              var p = points[count].split(':');
              if(p.length == 3) {
                var cc_ob = document.getElementById('country_code'+(count+1));
                if(cc_ob) { 
                  cc_ob.value = p[0];
                }
                temp_locations[count] = new MMLocation();
                temp_locations[count].coords = new MMLatLon(p[1],p[2]);
                temp_locations[count].address = new MMAddress();
                temp_locations[count].address.qs = qstrings[count];
                temp_locations[count].address.country_code = p[0];
                temp_locations[count].address.display_name = dnames[count];
                num_locs++;
              }
            }
            if(num_locs == 2) {
              locations = temp_locations;
            }
          }

          break;
      }
    }
  }
  return params;
}

function startSearch() {
  var fm = document.getElementById('mapform');
  original_qs = fm.qs.value;

  loc = undefined;
  locations = new Array(undefined,undefined);

    // create a new address object
    var address = new MMAddress();
    address.country_code = fm.country_code.value;
    address.qs = original_qs;
    
    // clear any existing items from previous geocoding requests
    cleanUp();

    // inform the user a geocode is occurring
    searchLoading(true);

    // perform the geocode
    geocoder.count = max_results;
    geocoder.geocode(address);

    return false;
}

function processResults() {
    // callback function registered with the geocoder to handle geocoding results
    // inform the user a geocode has finished
    searchLoading(false);
    // if an error occurred, inform the user
    if (geocoder.error_code && geocoder.error_code != 'MM_GEOCODE_MULTIPLE_MATCHES') {
        message.innerHTML = 'We are sorry - the following error occurred: <' + '/br><' + 'em>' + geocoder.error_code + '<' + '/em>';
        return false;
    }
    results = geocoder.result_set;
    var ol = document.createElement('ol');
     
    //loop through the result set
    var html = '';
    if(results.length == 1) {
      var marker = mapviewer.createMarker(results[0], { 'label' : results[0].address.display_name, 'icon': loc_icon });
      markers.push(marker);
    } else {
      html += '<ol>';
    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');

        anchor.href = '#';
        anchor.result_count = count;
        anchor.onclick = function () { moveToResult(this.result_count); return false; };
        anchor.appendChild(document.createTextNode(address.display_name));
        li.appendChild(anchor);
        ol.appendChild(li);
        html += '<li>&nbsp;<a href="#" onclick="moveToResult('+count+'); return false;">'+address.display_name+'</a></li>';

        //add a marker for each result
        var marker = mapviewer.createMarker(results[count], { 'label' : address.display_name, 'text' : (count+1) });
        //add an infobox for each result
        marker.setInfoBoxContent('<p>' + address.display_name + '<' + '/p>');
        markers.push(marker);
      }
      html += '</ol>';
    }

    showResults((results.length > 1),undefined,html);

    //if there were multiple matches, display all the results
    if (geocoder.error_code == 'MM_GEOCODE_MULTIPLE_MATCHES') {
    	var location = mapviewer.getAutoScaleLocation( markers );
    	mapviewer.goToPosition( location ); 
    	
    //otherwise show the only match at the optimal zoom factor
    } else {
        loc = results[0];
    	mapviewer.goToPosition( results[0] );
    }
}
             
function cleanUp() {
    loc = undefined;

    // Clean up the HTML containers
    if(message) {
      message.innerHTML = '';
    }
    results_panel.innerHTML = '';
    var route_steps = document.getElementById('routeSteps');
    if(route_steps) {
      route_steps.innerHTML = '';
    }

    //remove any markers
    mapviewer.removeAllOverlays();
    markers = new Array();
    showResults(false);
}

function searchLoading(bool) {
  var ob = document.getElementById('searchstatus');
  if(ob) {
    ob.style.visibility = bool ? 'visible' : 'hidden';
  }
}

function routeLoading(bool) {
  var ob = document.getElementById('routestatus');
  if(ob) {
    ob.style.visibility = bool ? 'visible' : 'hidden';
  }
}

function moveToResult (count) {
    //move the map specified location and open the info box
    loc = results[count];
    setMainLocation(loc);
    mapviewer.goToPosition(loc);
}

function showResults(bool,title,html) {
  var map = document.getElementById('mapviewer');
  var res = document.getElementById('resultspanel');
  var hdr = document.getElementById('resultshdr');
  if(bool) {
    if(typeof(html) == 'string') {
      results_panel.innerHTML = html
    }
    if(hdr) {
      hdr.innerHTML = title ? title : 'Alternative results';
    }
  }
  if(res) {
    res.style.display = bool ? 'block' : 'none';
  }
  if(map) {
    map.style.borderLeftWidth = bool ? '1px' : '0px';
	var map_width = 620;
	if(parseInt(map.style.width) >= 540){
		map_width = 784;
	}
    map.style.width = bool ? '419px' : map_width+'px';
  }
  
}

function startRoute(use_stored_locations) {
  var fm = document.getElementById('routeform');
  original_qs1 = fm.qs1.value;
  original_qs2 = fm.qs2.value;
  var qs1 = original_qs1;
  var qs2 = original_qs2;
  cleanUp();

  if(!use_stored_locations) {
    locations = new Array(undefined,undefined);
  }
  if(qs1 == '') {
    alert('Please specify a start address');
  } else if(qs2 == '') {
    alert('Please specify an end address');
  } else {

    // Inform user that we are retrieving results.
    routeLoading(true);

    addLocation(1,locations);
    addLocation(2,locations);
    route = new MMRoute(locations);

    var walking = document.getElementById('walking');
    if(walking && walking.checked) {
      route.mode = 'walking';
    } else {
      route.mode = 'driving';
    }

    // Initiate request.
    route_finder.request(route);
  }
  return false;
}

function addLocation(num, locations) {
    highlightInput('qs'+num);
    var qs = document.getElementById('qs' + num);
    var country_code = document.getElementById('country_code' + num);
    var address = new MMAddress();
    if(!locations[num-1]) {
    	if (qs && qs.value != '') {
        	address.qs = qs.value;
        	address.country_code = country_code.value;
        }
        locations[num-1] = new MMLocation(address);
    } 
}     

function resultsLoaded() {
    //updateURL();
    if (route.error_code) {
        if (route.error_code == 'MM_ROUTE_GEOCODING_ERRORS') {
            processGeocodingErrors (route.geocoding_errors);
        } else {
            //alert(route.error_code + ': ' + route.error_explanation);
            alert(route.error_explanation);
        }
    } else {
        if(route_onload) {
          mapviewer.goToPosition(start_pos,start_zoom_level);
          route_onload = 0;
        } else {
          mapviewer.goToPosition( mapviewer.getAutoScaleLocation( route.bounds ) );
        }
        displayStages(route);
        for( var i = 0, l = route.polyLine.length; i < l; ++i ) {
          mapviewer.addOverlay(route.polyLine[i]);
        }
    }
    routeLoading(false);
}

function displayStages(route) {
    var curr_step = 1;
    var stages = route.stages; 
    var container = document.getElementById('routeSteps');

    var i;
    var num_steps = 0;
    for(i = 0;i < stages.length;i++) {
      num_steps += stages[i].steps.length;
    }
    var html = '<h2>Your Directions</h2>';
    var summary = '<b>';
    var start_address = String(stages[0].start_address);
    if(start_address == 'undefined') {
      start_address = locations[0].address.display_name;
    }
    var end_address = String(stages[stages.length-1].end_address);
    if(end_address == 'undefined') {
      end_address = locations[1].address.display_name;
    }
    summary += (route.mode == 'walking') ? 'Walking' : 'Driving';
    summary += ' from:</b> ' + start_address;
    summary += '<br /><b>To:</b> ' + end_address;
    summary += '<br /><b>Total Distance:</b> ' + route.distance.miles + ' mile'+((route.distance.miles == '1') ? '' : 's');
    summary += '<br /><b>Estimated Total Time:</b> ';
    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'+((route.duration.minutes == 1) ? '' : 's')+' '; }
    summary += '<br /><b>Steps:</b> '+num_steps+'<br />';
    summary += '<br /><a href="#" onclick="reverseDirections()">Reverse these directions</a>';

    html += summary+'<br /><br />';

    var acc_distance = 0;    
    for (var count=0; count < stages.length; count++) {
      if(stages.length > 1) {    
        var stage_summary = '';
        stage_summary += '<strong>Stage ' + (count + 1) + '<' + '/strong>';
        stage_summary += '<br />Start: ' + stages[count].start_address;
        stage_summary += '<br />End: ' + stages[count].end_address;
        stage_summary += '<br />Stage Distance: ' + stages[count].distance.miles + ' mile(s)';
        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) '; }
        stage_summary += '<br />Summary: ' + stages[count].summary;
        html += stage_summary;
      }
        
        var steps = stages[count].steps;

        html += '<table cellpadding="0" cellspacing="0" class="routetbl">';
        html += '<tr><td><b>Step</b></td><td><b>Directions</b></td><td><b>Step distance</b></td><td><b>Distance so far</b></td></tr>';
        for (var stepCount=0; stepCount < steps.length; stepCount++) {
            var text = curr_step;
            var zindex = max_zindex - curr_step + 1;
            if (count == stages.length - 1 && stepCount  == steps.length - 1) {
                zindex = max_zindex; 
            }                
          
            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 + ' ';
            }
            
            var distance = steps[stepCount].distance.miles + ' miles';
            acc_distance += parseFloat(steps[stepCount].distance.miles);
            
            html += '<tr><td>'+(stepCount+1)+'</td><td>'+instruction+'</td><td>'+distance+'</td><td>'+String(acc_distance).replace(/(\.\d\d).*/g,'$1')+' miles</td></tr>\n';
         
            createStepMarker(steps[stepCount].start_point, instruction, text, zindex);
            
            ++curr_step;
        }
        html += '</table>';
    }            
    
    var copyright = '';
    if (route.copyright) {copyright += 'Copyright: ' + route.copyright; }
    if (route.disclaimer)  {copyright += '<br />Disclaimer:  <a href="' + route.disclaimer +'">' + route.disclaimer +'<' + '/a>'; }
    html += '<p>'+copyright+'</p>';

    container.innerHTML = html;
    container.style.display = 'block';
}

function processGeocodingErrors (errors) {
    var marker_group_name = 'g1';
    for (var i = 0; i < errors.length; i++) {
        if (errors[i].error_code == 'MM_GEOCODE_NO_MATCHES') {
            alert('No matching locations for Location ' + errors[i].input_id);
        } else if (errors[i].error_code == 'MM_GEOCODE_MULTIPLE_MATCHES') {
            location_results = errors[i].results;
            var html = '<ol>';
            for (var j = 0; j < errors[i].results.length; j++) {
                var display_name = errors[i].results[j].address.display_name;
                var point = errors[i].results[j].coords; 
                var coords = point.lat + ',' +point.lon;
                //var option = document.createElement('option');
                //option.value = point.lat + ',' +point.lon; 
                //option.appendChild(document.createTextNode(display_name));
                //select.appendChild(option);
                //select.selectedIndex=0;
                html += '<li><a href="#" onclick="setLocation('+errors[i].input_id+','+j+'); return false;">'+display_name+'</a></li>';

                //add a marker for each result
                var icon = MM_DEFAULT_ICON.copy();
                icon.groupName = marker_group_name;
                var marker = mapviewer.createMarker(errors[i].results[j], { 'label' : display_name, 'text' : (j+1), 'icon': icon });
                //add an infobox for each result
                marker.setInfoBoxContent('<p>' + display_name + '<' + '/p>');
                markers.push(marker);

            }
            html += '</ol>';
            highlightInput('qs'+errors[i].input_id,true);
            showResults(true,'Did you mean:',html);
            var location = mapviewer.getAutoScaleLocation( markers );
            mapviewer.goToPosition( location );
            //mapviewer.declutterGroup(marker_group_name, {}, MM_DECLUTTER_GRID ); 

            break;
        }
    }
}

function highlightInput(id,bool) {
  var ob = document.getElementById(id);
  if(ob) {
    ob.style.backgroundColor = bool ? '#f77' : '#fff';
  }
}

function setMainLocation(l) {
  mapviewer.removeAllOverlays();
  markers = new Array();

  var marker = mapviewer.createMarker(loc, { 'label' : l.address.display_name, 'icon': loc_icon, 'inert': true });
  //marker.setInfoBoxContent('<p>' + l.address.display_name + '<' + '/p>');
  //marker.openInfoBox();
  markers.push(marker);
  showResults(false);
}

function setLocation(num,index) {
  var qs = document.getElementById('qs'+num);
  //qs.value = location_results[index].address.display_name;

  locations[num-1] = location_results[index];

  showResults(false);
  startRoute(true);
}

function createStepMarker(location, instruction, text, zindex) {
    var marker = mapviewer.createMarker(location, {zIndex: zindex, 'text' : text});
    marker.setInfoBoxContent('<p>' + instruction + '<' + '/p>');
}

function enlargeMap(bool) {
  var ob = document.getElementById('enlargemap');
  if(ob) {
    ob.innerHTML = bool ? '<a href="#" onclick="enlargeMap(false); return false;"><img src="//media.tiscali.co.uk/images/gfx/trv/maps/icon-reduce.gif" width="16" height="16" alt="Reduce" />Reduce map</a>' : '<a href="#" onclick="enlargeMap(true); return false;"><img src="//media.tiscali.co.uk/images/gfx/trv/maps/icon-enlarge.gif" width="16" height="16" alt="Enlarge" />Enlarge map</a>';
    var col = document.getElementById('search_forms');
    if(col) {
      col.style.display = bool ? 'none' : 'block';
    }
    var map = document.getElementById('mapviewer');
    var border = document.getElementById('mapboxinner');
    var mapcol = document.getElementById('map_placement');
    if(mapcol && map && border) {
      mapcol.style.width = bool ? '786px' : '622px';
      map.style.width = bool ? '784px': '620px';
      border.style.width = bool ? '784px' : '620px';
 	  if(document.getElementById('resultspanel').style.display == "block"){
	      map.style.width = bool ? '584px' : '420px';
		  }
    }
    mapviewer.resize( new MMPoint( -1, 0 ) );
  }
  return false;
}

function updateURL() {
  var point = mapviewer.getCurrentPosition();
  var coords = ''+point;
  coords = coords.replace(/[^\d\.,\-]/g,'');
  var zoom = mapviewer.getZoomFactor();
  var map_type = mapviewer.getMapType();
  var base_url = String(document.location.href).replace(/#.*$/,'');
  var url = '#map='+coords+'|'+zoom+'|'+map_type;
  if(loc) {
    url += '&loc='+loc.address.country_code+':'+loc.coords.lat+':'+loc.coords.lon;
    url += '|'+escape(original_qs)+'|'+escape(loc.address.display_name);
  }

  if((typeof(locations[0]) != 'undefined') && (typeof(locations[1]) != 'undefined')) {
    url += '&route=';

    if(locations[0].address) {
      url += locations[0].address.country_code;
      if(route.stages) {
        var start_stage = route.stages[0];
        var sp = start_stage.steps[0].start_point;
        url += ':'+sp.lat+':'+sp.lon;
      }
    }
    if(locations[1].address) {
      url += ';';
      url += locations[1].address.country_code;
      if(route.stages) {
        var end_stage = route.stages[route.stages.length-1];
        var ep = end_stage.steps[end_stage.steps.length-1].start_point;
        url += ':'+ep.lat+':'+ep.lon;
      }
    }

    url += '|'+escape(original_qs1)+':'+escape(original_qs2);
    if(route.stages) {
      var sa = String(route.stages[0].start_address);
      var ea = String(route.stages[route.stages.length-1].end_address);
      if(sa == 'undefined') {
        if(locations[0].address && locations[0].address.display_name) {
          sa = locations[0].address.display_name;
        } else {
          sa = '';
        }
      }
      if(ea == 'undefined') {
        if(locations[1].address && locations[1].address.display_name) {
          ea = locations[1].address.display_name;
        } else {
          ea = '';
        }
      }
      url += '|'+escape(sa)+':'+escape(ea);
    }
  }

  document.location = url;

  var show = true;
  showAerial(show);

}

function reverseDirections() {
  var tmp = locations[0];
  locations[0] = locations[1];
  locations[1] = tmp;
  var fm = document.getElementById('routeform');
  if(fm) {
    //fm.qs1.value = locations[0].address.qs;
    //fm.qs2.value = locations[1].address.qs;
  }
  startRoute(true);
}

MMAttachEvent( window, 'load', onLoad );