var XEMapRoute = Class.create();

XEMapRoute.addMapDataHandler = function(mapData, options) {
  options = options ? options : {};
  $A(mapData.Elements).each(function(i) {i.toString = XELocation.toString; });

  var dirs = new GDirections();
  var polyline = [];
  var polyStore = [];
  
  var me = this;
  var remainder = null;
  var lastload = null;
  
  var load = function(data) {
    if(data.size() < 25) {
      lastload = data;
      remainder = null;
    } else {
      var parted = data.partition(function(x, index) { return index < 24;} ); //partition of size 24
      lastload = parted[0]; //first half
      remainder = parted[1];
      remainder.unshift(lastload.last());
      
    }
    if(lastload.size() > 1) {
      dirs.loadFromWaypoints(lastload, {getPolyline: true});
    }
  }
  
  GEvent.addListener(dirs, "load", function() {
    var polyline = dirs.getPolyline();
    me.map.addOverlay(polyline);
    polyStore.push(polyline);
    if(options.onload) options.onload(polyline);
    if(remainder) {
      load(remainder);
    }
  });
  
  GEvent.addListener(dirs, "error", function(er) {
    if(!options['polyline']) {
      if(window['console']) console.log("Error %o", dirs.getStatus());
      lastload.pop();
		  load(lastload);
    } else {
      var polyline = XELine.addMapDataHandler.call(me, mapData);
      if(options.onload) options.onload(polyline);
      polyStore.push(polyline);
    }
  });
  
  load(mapData.Elements);
  
  return polyStore;
}

var XELine = Class.create();
XELine.addMapDataHandler = function(mapData, options) {
  options = Object.extend({color: "#3333cc", geodesic:false, weight: 4, opacity: 0.5}, options);
  
  var linePoints = mapData.Elements.map(function(i) {
    if(i.Lat && i.Lng) {
      return new GLatLng(parseFloat(i.Lat), parseFloat(i.Lng));
    } else {
      return new GLatLng(parseFloat(i.MapData.Lat), parseFloat(i.MapData.Lng));
    }
  });
  var polyline = new GPolyline(linePoints,options.color, options.weight, options.opacity, {"geodesic":options.geodesic});
  this.map.addOverlay(polyline);
  return polyline;
}

XEMapRoute.removeMapDataHandler = function(mapData, marker) {
  throw "XEMapRoute.removeMapDataHandler is not yet implemented.";
  var lines = marker.flatten();
  var me = this;
  lines.each(function(i) {
    me.map.removeOverlay(i);
  });
  return true;
}

XEMapRoute.centreOnMarker = XELine.centreOnMarker = function(mapData, polyline) {
  var bounds = null;
  var flat = polyline.flatten().findAll(Prototype.K);
  var bounds = new GLatLngBounds;
  
  flat.each(function(line) {
    var lineBound = line.getBounds();
    bounds.extend(lineBound.getSouthWest());
    bounds.extend(lineBound.getNorthEast());
  });
  
  this.map.setCenter(bounds.getCenter(), this.map.getBoundsZoomLevel(bounds));
}

XEMapRoute.copyPolyline = function(polyline) {
  return polyline;
}

