/*
 * TODO in javascript Map class:
 *
 *   Show vehicles at any time in the history
 *
 *   "Play map": Is this just a matter of the previous call and timeouts?
 *
 *   Pan and Zoom
 *
 *   Show a given route or all routes.
 *
 *   Show a given vehicle on the route or all vehicles
 *
 *   Toggle display of stops?
 *
 *   Show the estimated times we gave?
 *
 *   Should we interpolate vehicle positions when we don't have location data for
 *   longer periods? That way they can see exactly when the vehicle got to the stop.
 */

function Vehicle(id, lat, lon, dir, speed, driver, status, staleness) 
{
    this.id = id;
    this.lat = lat;
    this.lon = lon;
    this.dir = dir;
    this.speed = speed;
    this.driver = driver;
    this.status = status;
    this.staleness = staleness;
    this.img = null;
    this.linkMap = null;
    this.visible = true;

    var speedInfo = ((this.speed <= 0) ? 'Stopped' : 'Speed: ' + this.speed + 'mph');
    this.title = 'Vehicle #' + this.id + '; ' + speedInfo;
}

Vehicle.prototype.updateImage = function()
{
    if (this.img) {
       if (this.staleness == 'hide') {
           this.img.src = '/images/spacer.gif';
       } 
       else if ((this.dir > 0) && (this.speed > 0)) {
           this.img.src = '/images/vehicleArrow_' + this.staleness +
     		  '_' + (Math.round(this.dir/22.5) % 16) + '_small.gif';
       }
       else {
           this.img.src = '/images/vehicleCircle_' + this.staleness + '_small.gif';
       }

       var speedInfo = ((this.speed <= 0) ? 'Stopped' : 'Speed: ' + this.speed + 'mph');
       this.title = 'Vehicle #' + this.id + '; ' + speedInfo;
       this.img.alt = this.img.title = this.title;
       this.linkMap = document.getElementById('area' + this.id);
       this.linkMap.title = this.title;
    }
}

Vehicle.prototype.statsAlert = function()
{
    var b1 = (this.staleness == 'hide' ? '' : '<b>');
    var b2 = (this.staleness == 'hide' ? '' : '</b>');

    return(b1 + this.img.title + "\n" +
                this.img.src + "\n" +
                this.img.style.top + "," + this.img.style.left + " . " + this.img.style.visibility + b2 + "<BR>");
}



function Map(mapID, imagePath, width, height, minx, miny, maxx, maxy) 
{
    this.mapElement = document.getElementById(mapID);
    this.width = width;
    this.height = height;
    this.minx = minx;
    this.miny = miny;
    this.maxx = maxx;
    this.maxy = maxy;
    this.vehicles = new Array();
    this.selectedVehicle = -1;
    this.vehicleIconOffset = 14.5;
    this.comeBackLaterSpan = document.getElementById('comeBackLater');
	this.imagePath = imagePath;
}


Map.prototype.checkVanVisibilityAndUpdateNotice = function()
{
  var anyVisibleVans = false;
  var n = this.vehicles.length;
  for (var i=0; i<n; i++) {
    if (typeof(this.vehicles[i]) == 'object') {
      if ((this.vehicles[i].visible) && (this.vehicles[i].staleness != 'hide')) {
        anyVisibleVans = true;
      }
    }
  }
  if (this.comeBackLaterSpan && (typeof(this.comeBackLaterSpan) == 'object')) {
    this.comeBackLaterSpan.style.display = (anyVisibleVans ? 'none' : '');
  }
}


Map.prototype.addVehicle = function(id, v) 
{
    var vX = (this.width * (v.lon - this.minx)/(this.maxx - this.minx)) - this.vehicleIconOffset;
    var vY = (this.height * (this.maxy - v.lat)/(this.maxy - this.miny)) - this.vehicleIconOffset;

    vImg = document.createElement('IMG');
    vImg.className = 'vehicle_img';
    vImg.id = 'vehicle_img_' + v.id;
    vImg.style.top = vY;
    vImg.style.left = vX;
    vImg.setAttribute("usemap", "#map"+v.id, 0);

    if (v.staleness == 'hide') {
       vImg.src = this.imagePath + '/spacer.gif';
    }
    else if ((v.dir > 0) && (v.speed > 0)) {
       vImg.src = this.imagePath + '/vehicleArrow_' + v.staleness +
                  '_' + (Math.round(v.dir/22.5) % 16) + '_small.gif';
    }
    else {
       vImg.src = this.imagePath + '/vehicleCircle_' + v.staleness + '_small.gif';
    }

    vImg.style.zIndex = 99;
    vImg.style.top = Math.round(vY);
    vImg.style.left = Math.round(vX);

    var speedInfo = ((v.speed <= 0) ? 'Stopped' : 'Speed: ' + v.speed + 'mph');
    v.title = 'Vehicle #' + v.id + '; ' + speedInfo;
    vImg.alt = vImg.title = v.title; 
    
    v.visible = ((vY >= 0) && (vY < this.height) && (vX >= 0) && (vX < this.width));
    vImg.style.visibility = (v.visible  ? 'visible' : 'hidden');

    if (this.mapElement != null)
    {
        this.mapElement.appendChild(vImg);
    }

    var map = document.createElement('map');
    map.setAttribute('name', 'map'+v.id);
    var speedInfo = ((v.speed <= 0) ? 'Stopped' : 'Speed: ' + v.speed + 'mph');
    map.innerHTML = "<area id='area" + id + "' shape='circle' coords='" + this.vehicleIconOffset + "," + this.vehicleIconOffset + "," + this.vehicleIconOffset + "' href='javascript: void(0);' " +
                  "onClick='selectVehicle("+id+");' title='" + v.title + "'>";
            			
    if (this.mapElement != null) 
    {
        this.mapElement.appendChild(map);
    }
    
    v.img = vImg;
    v.linkMap = map;
    this.vehicles[id] = v;
}


Map.prototype.setVehicleStaleness = function(id, s)
{
    this.vehicles[id].staleness = s;
    this.vehicles[id].updateImage();
}


Map.prototype.getXfromLon = function(lon)
{
    return (this.width * (lon - this.minx)/(this.maxx - this.minx)) - this.vehicleIconOffset;
}


Map.prototype.getYfromLat = function(lon)
{
    return (this.height * (this.maxy - lat)/(this.maxy - this.miny)) - this.vehicleIconOffset;
}

Map.prototype.getLonfromX = function(x)
{
    return((((this.maxx - this.minx) * (x + this.vehicleIconOffset)) / this.width) + this.minx);
}

Map.prototype.getLatfromY = function(pixY)
{
    return(this.maxy - (((this.maxy - this.miny) * (pixY + this.vehicleIconOffset)) / this.height));
}


Map.prototype.setVehicleLatLon = function(id, lat, lon)
{
    this.vehicles[id].lat = lat;
    this.vehicles[id].lon = lon;

    newX = (this.width * (lon - this.minx)/(this.maxx - this.minx)) - this.vehicleIconOffset;
    newY = (this.height * (this.maxy - lat)/(this.maxy - this.miny)) - this.vehicleIconOffset;

	//alert("lon = " + lon + ",  width = " + this.width + " minx = " + this.minx + ", maxx = " + this.maxx + ", new x = " + newX + ", newY = " + newY);
    this.vehicles[id].img.style.top = Math.round(newY) + "px";
    this.vehicles[id].img.style.left = Math.round(newX) + "px";
    this.vehicles[id].img.style.zIndex = 99;

    this.vehicles[id].img.style.pixelLeft = newX;
    this.vehicles[id].img.style.pixelTop = newY;

    this.vehicles[id].visible = ((newY >= 0) && (newY < this.height) && (newX >= 0) && (newX < this.width));
    this.vehicles[id].img.style.visibility = (this.vehicles[id].visible ? 'visible' : 'hidden');
}

Map.prototype.setVehicleDirection = function(id, dir, speed) 
{
    this.vehicles[id].dir = dir;
    this.vehicles[id].speed = speed;
    this.vehicles[id].updateImage();
}

Map.prototype.setVehicleStatus = function(id, status)
{
    this.vehicles[id].status = status;
    this.vehicles[id].updateImage();
}

Map.prototype.statsAlert = function()
{
    var m = "";
    var n = this.vehicles.length;
    for (var i=0; i<n; i++) {
        if (typeof(this.vehicles[i]) == 'object') {
            m += this.vehicles[i].statsAlert();
        }
    }
    return (m);
}

Map.prototype.selectVehicle = function(id)
{
	this.selectedVehicle = id;
	return true;
}


