/* copyright 2006-2008 FitLink.com */

var map;
var pts;
var lays;
var arp;
var move;
window.onunload=map_unload;

function map_init() {
  if (map) return false;
  pts = [];
  lays = [];
  move = false;
  map_set_distance(0.0);
  map = new GMap2($("map"));
  map.addControl(new GSmallMapControl());
  map.addControl(new GMapTypeControl());
  window.onunload=map_unload;
  return true;
}

function map_unload() {
  map=null; pts=null; lays=null; move=null;
  if (arp) arp = unpop(arp);
  handleUnload();
  GUnload();
  window.onunload=null;
}

function map_enable_point() {
  show('map_buttons');
  GEvent.clearListeners(map, 'click');
  GEvent.addListener(map, 'click', function(overlay, point) {
    if (point) {
      map_clear();
      map_add_point(point,null);
    }
  });
}

function map_enable_route() {
  show('map_buttons');
  GEvent.clearListeners(map, 'click');
  GEvent.addListener(map, 'click', function(overlay, point) {
    if (point) {
      if (pts.length>0) map_remove_overlay();
      map_add_route_point(point, true);
      map_add_overlay(new GMarker(point));
    }
  });
}

function map_disable() {
  GEvent.clearListeners(map, 'click');
  hide('map_buttons');
}

function map_parse(d) {
  var t = [];
  if (d) for (i=0; i<d.length; i++) {
    t.push(new GLatLng(Number(d[i][0]),Number(d[i][1])));
  }
  map_center(t);
  return t;
}

function map_set_points(d) {
  var a = unserialize(d);
  var t = map_parse(a);
  for (i=0; i<t.length; i++) {
    map_add_point(t[i],a[i].length > 2 ? a[i][2] : null);
  }
}

function map_add_point(point, info) {
  var marker = new GMarker(point);
  map_add_overlay(marker);
  if (info && info!='') GEvent.addListener(marker, 'click', function() {
    marker.openInfoWindowHtml(info);
  });
  pts.push(point);
}

function map_set_route(d, mark) {
  var t = map_parse(unserialize(d));
  for (i=0; i<t.length; i++) {
    map_add_route_point(t[i]);
  }
  if (t.length>0 && mark) map_add_overlay(new GMarker(t[t.length-1]));
}

function map_add_route_point(point, center) {
  if (pts.length>0) {
    var line = [];
    var oldPoint = pts[pts.length-1];
    line.push(oldPoint);
    line.push(point);
    map_add_overlay(new GPolyline(line,'#ff0000', 6));
    map_set_distance( total + map_calc_distance(oldPoint, point) );
  }
  if (center) map.setCenter(point);
  pts.push(point);
}

function map_center(points) {
  if (!points) points = pts; if (points.length==0) return;
  var nt = 180; var xt = -180; var ng = 180; var xg = -180; var z = 14;
  for (var i=0; i<points.length; i++) {
    var p = points[i];
    if (p.lat()<nt) nt = p.lat();
    if (p.lat()>xt) xt = p.lat();
    if (p.lng()<ng) ng = p.lng();
    if (p.lng()>xg) xg = p.lng();
  }
  if (points.length > 1) {
    var r = Math.max( 0.1, map.getSize().height / map.getSize().width );
    var s = Math.max( Math.abs( xt - nt ) / r, Math.abs( xg - ng )  );
    z = Math.min( 17, Math.max( 0, 17 - Math.round( Math.log( s / 0.003 ) / Math.LN2 ) ) );
  }
  map.setCenter(new GLatLng((xt + nt)/2,(xg + ng)/2),z);
}

function map_default_center() {
  map.setCenter(new GLatLng(38.5,-97),4);
}

function map_move(t,g,a,z) {
  if (!z) switch (a) { case 1: a=6; break; case 2: a=8; break; case 3: a=11; break; case 4: a=14; break; case 5: a=15; break; case 6: case 7: a=16; break; default: a=17; break; }
  if (map) map.setCenter(new GLatLng(t,g),Math.max(Math.min(z?z:a,17),4));
}

function map_add_overlay(o) {
  lays.push(o);
  map.addOverlay(o);
}

function map_remove_overlay() {
  if (lays.length>0) map.removeOverlay(lays.pop());
}

function map_calc_distance(p1, p2) {
  if (p1 && p2) {
    var x = 69.1 * (p2.lat() - p1.lat());
    var y = 69.1 * (p2.lng() - p1.lng()) * Math.cos(p1.lat() / 57.3);
    return Math.sqrt( (x * x) + (y * y) );
  }
  return 0;
}

function map_get_points() {
  var first = true;
  var str = '';
  for (i=0; i<pts.length; i++) {
    if (!first) str = str + '|';
    first = false;
    str = str + pts[i].lat() + ',' + pts[i].lng();
  }
  return str;
}

function map_undo() {
  if (pts.length>0) {
    var p = pts.pop();
    if (pts.length>0) {
      var l = pts[pts.length-1];
      map.setCenter(l);
      map_set_distance( total - map_calc_distance(l,p) );
    }
  }
  map_remove_overlay();
  map_remove_overlay();
  if (pts.length>0) map_add_overlay(new GMarker(pts[pts.length-1]));
}

function map_clear() {
  pts = [];
  lays = [];
  map_set_distance(0.0);
  map.clearOverlays();
}

function map_set_distance(dis) {
  total = dis;
  d = $('route_distance');
  if (d) {
    var s = String(Math.round(total * 100.0));
    while (s.length < 3) s = '0' + s;
    s = s.substr(0,s.length-2) + '.' + s.substr(s.length-2);
    d.innerHTML = s;
  }
}

function map_resolve_location() {
  var loc = get_value('map_location');
  if (loc && loc!='') {
    set_html('go_text','Loading...');
    new GClientGeocoder().getLatLng(loc,map_handle_location);
  } else {
    set_html('go_text','Please enter a location');
  }
}

function map_handle_location(p) {
  if (p) map_center(new Array(p));
  set_html('go_text',p ? '' : 'We could not find the location');
}

function map_resolve_address_if_exists() {
  if (has_value('street1') || has_value('street2') || has_value('city') || has_value('state') || has_value('postalcode') || (has_option('country') && get_option('country')!='United States')) {
    map_resolve_address(false,true);
    return false;
  }
  return true;
}

function map_resolve_address(e,su) {
  move = !su; var c = get_value('city'); var s = get_value('state'); var p = get_value('postalcode'); var co = get_option('country');
  if (is_empty(co)) {
    page_warning("Please select a country");
    return;
  } else if (co=='United States' && is_empty(c) && is_empty(s) && is_empty(p)) {
    page_warning("Please specify a city, state or postal code");
    return;
  }
  loading();
  if (map_is_resolvable()) {
    var addr = array_concat(new Array(get_value('street1'),c,s,p,co),', ');
    new GClientGeocoder().getLocations(addr,e ? map_handle_exact_address : map_handle_address);
  } else {
    ajax_call('/parts/geocode?country=' + escape(co),e ? map_handle_exact_geocode : map_handle_geocode);
  }
}

function map_handle_exact_geocode(d) {
  map_handle_geocode(d,true);
}

function map_handle_geocode(d,e) {
  done_loading();
  var a = d ? unserialize(d) : null;
  if (a) map_set_address(null,null,null,null,a[0],a[1],null,a[2]);
  else map_unknown(e,true);
}

function map_handle_exact_address(r) {
  map_handle_address(r,true);
}

function map_handle_address(r,e) {
  var code = r ? r.Status.code : null;
  var ps = r ? r.Placemark : new Array();
  done_loading();
  if (code==G_GEO_UNKNOWN_ADDRESS || code==G_GEO_UNAVAILABLE_ADDRESS) {
    map_unknown(e,true);
  } else if (code!=G_GEO_SUCCESS) {
    page_warning("An unexpected error occurred while resolving your address. Please try again later");
  } else if (ps.length>1) {
    arp = new YAHOO.widget.Panel('address_resolve',{width:'600px',height:'525px',modal:true,close:true,fixedcenter:true,draggable:false,zIndex:10});
    arp.setHeader('Select Address');
    var s = '<p>We located several possible matches.  Please select the correct address:</p><ul>';
    for (var i=0; i<ps.length; i++) {
      var a = map_parse_address(ps[i]);
      s += "<li><a href='#' onclick=\"arp.hide(); arp.destroy(); map_set_address('" + array_implode(a,"','",true) + "'); return false;\">" + map_strip(ps[i].address) + "</a></li>";
    }
    s += '</ul>';
    arp.setBody(s);
    arp.render(document.body);
    arp.center();
    arp.show();
  } else if (ps.length>0) {
    var a = map_parse_address(ps[0]);
    if (a[6]==0) map_unknown(e,true);
    else if (!e || a[6]==8) map_set_address(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);
    else {
      map_unknown(e,false);
      map_move(a[4],a[5],a[6]);
    }
  }
}

function map_unknown(e,c) {
  var s = "We cannot resolve the " + (e ? "exact " : "") + "address";
  if (e) {
    map_show_control(c);
    s += ".  Please try again or plot the exact location on the map";
  }
  page_warning(s);
}

function map_parse_address(pl) {
  var a = pl.AddressDetails;
  var c = a ? a.Country : null;
  var aa = c ? c.AdministrativeArea : null;
  var sa = aa ? aa.SubAdministrativeArea : null;
  var l = sa && sa.Locality ? sa.Locality : (aa && aa.Locality ? aa.Locality : (c && c.Locality ? c.Locality : (a ? a.Locality : null)));
  var t = l && l.Thoroughfare ? l.Thoroughfare : (c && c.Thoroughfare ? c.Thoroughfare : (a ? a.Thoroughfare : null));
  var z = l && l.PostalCode ? l.PostalCode : (aa ? aa.PostalCode : null);
  var p = pl.Point;
  var lt = p ? p.coordinates[1] : '0';
  var lg = p ? p.coordinates[0] : '0';
  var ac = a ? a.Accuracy : '0';
  var ar = new Array(t ? t.ThoroughfareName : '',l ? l.LocalityName : '',aa ? map_strip(aa.AdministrativeAreaName) : '',z ? z.PostalCodeNumber : '',lt,lg,ac);
  return new Array(t ? t.ThoroughfareName : '',l ? l.LocalityName : '',aa ? map_strip(aa.AdministrativeAreaName) : '',z ? z.PostalCodeNumber : '',lt,lg,ac);
}

function map_set_address(o,c,s,p,t,g,a,z) {
  if (o) set_value('street1',o);
  if (c) set_value('city',c);
  if (s) set_value('state',s);
  if (p) set_value('postalcode',p);
  set_value('latitude',t);
  set_value('longitude',g);
  set_value('accuracy',a);
  if (move) map_move(t,g,a,z);
  else map_submit();
}

function map_clear_address() {
  set_value('street1','');
  set_value('street2','');
  set_value('city','');
  set_value('state','');
  set_value('postalcode','');
  set_option('country','United States');
  set_value('latitude','');
  set_value('longitude','');
  set_value('accuracy','');
}

function map_is_resolvable() {
  var cs = ['United States','Australia','Austria','Belgium','Brazil','Canada','Czech Republic','Denmark','Ecuador','El Salvador',
            'Finland','France','Germany','Hong Kong','Hungary','India','Ireland','Italy','Japan','Liechtenstein','Luxembourg','Mexico',
            'Netherlands','New Zealand','Nicaragua','Norway','Poland','Portugal','San Marino','Singapore','Slovakia','Spain','Sweden',
            'Switzerland','Turkey','United Kingdom','Uruguay'];
  return array_contains(cs,get_option('country'));
}

function map_show_control(c) {
  show('map_control');
  if (map_init() && c) map_default_center();
  map_enable_point();
}

function map_hide_control() {
  map_disable();
  map_clear();
  hide('map_control');
}

function map_save() {
  if (pts && pts.length>0) {
    set_value('latitude',pts[0].lat());
    set_value('longitude',pts[0].lng());
    set_value('accuracy',10);
    map_submit();
  } else {
    map_resolve_address(true,true);
  }
}

function map_submit() {
  if (window.floater) {
    window.floater.validate = function () { return true; };
    window.floater.submit();
  } else document.main_form.submit();
}

function map_strip(s) {
  if (get_option('country')=='United States') {
    var re = s.length == 4 ? /.\..\./ : /,\s.\..\.\s/;
    if (re.test(s)) return s.replace(/\./g,'');
  }
  return s;
}
