var BusPlotter = Class.create({
  /**
  *sets up the bus plotter javascript
  *@params map - the google maps object we are using
  */
  initialize: function(map){
    this.units = new Hash();
    this.checkInTime = 0;
    this.routesArray = new Array;
    this.selectedBus = null;
    this.map = map;
    this.getBuses();
  },
  
  //used when a route is selected, makes sure buses not no unit are not shown
  //@param routeId - the route number being shown, if 'ALL' is passed, all busses will be shown
  setRouteSelected: function(routeId){
    if(this.selectedBus != null){
      this.selectedBus.setIsSelected(false);
      this.selectedBus = null;
    }
    if(routeId != "ALL"){
      if(this.routesArray.indexOf(routeId) == -1)
        this.routesArray.push(routeId);
      this.showAndHideBuses();
    }else{
      this.routesArray.clear();
      this.showAndHideBuses();
    }
  },
  
  showAndHideBuses: function(){
    var units = this.units;
    var selectedBus = this.selectedBus;
    var routesArray = this.routesArray;
    var map = this.map;
    this.units.each(function(pair){
      if(routesArray.indexOf(pair.value.getRouteId()) == -1 && routesArray.length > 0){
        pair.value.hide();
      }else{
        pair.value.show();
      }
    });
  },
  
  setRoutePlotter: function(routePlotter){
    this.routePlotter = routePlotter;
  },
  
  getRoutePlotter: function(){
    return this.routePlotter
  },
  
  //removes a route from the routesArray
  removeSelectedRoute: function(routeId){
    this.routesArray.splice(this.routesArray.indexOf(routeId), 1);
    if(this.routesArray.length == 0){
      this.showAndHideBuses();
    }
  },
  
  /**
  * selects a bus, or deselects it if already selected
  * @param busIcon - a BusIcon object
  */
  selectBus: function(busIcon){
    if(busIcon == this.selectedBus){
      this.selectedBus = null;
    }else{
      if(this.selectedBus != null){
        this.selectedBus.onClick();
      }
      this.selectedBus = busIcon;
    }
    this.showAndHideBuses();
  },
  
  getSelectedBus: function(){
    return this.selectedBus;
  },
  
  //returns live bus icon url
  getLiveBus: function(){
    return this.liveBus;
  },
  
  //returns dead bus icon url
  getDeadBus: function(){
    return this.deadBus;
  },
  
  //returns map
  getMap: function(){
    return this.map;
  },
  
  //sends an ajax request which retreaves all the buses and 
  getBuses: function(){
    var thisContainer = this;
    new Ajax.Request("./bus_plotter", {method: 'get', evalScripts: false, onComplete: function(response){
      var busResponse = eval("(" + response.transport.responseText + ")");
      try{
        thisContainer.updateUnits(busResponse);
      }catch(err){
        console.log(err);
        //$('connection_lost').show();
        this.getBuses()
      }
    }});
  },
  
  //same as hash.set for api, sets this.units
  setUnit: function(key, value){
    this.units.set(key, value);
  },
  
  getUnit: function(key){
    unit = this.units.get(key);
    return unit;
  },
  
  unsetUnit: function(key){
    this.units.unset(key);
  },
  
  /**
  * First sets all units to dead, than updates coordinates of buses and sets buses to alive if updated.
  * After it purges all buses that have not been updated from the map.  
  */
  updateUnits: function(busResponse){
    this.setUnitsToDead();
    var thisContainer = this;
    var busResponse = $H(busResponse);
    var checkInTime = parseInt(busResponse.get('checkInTime'));
    if(checkInTime > this.checkInTime){ 
        this.checkInTime = checkInTime;
        unitList = $A(busResponse.get('unitList'));
        unitList.each(function(unit){
          var busIcon = thisContainer.getUnit(unit.unit_id)
          if(busIcon == null){
            busIcon = new BusIcon(unit, thisContainer.getMap(), thisContainer);
            thisContainer.setUnit(unit.unit_id, busIcon);
          }else{
            busIcon.update(unit);
          }
      });
      thisContainer.purgeDeadUnits();
    }
    setTimeout("busPlotter.getBuses()", 1000 * REFRESH_RATE); //busPlotter must be global because js is the suck.
  },
  
  setUnitsToDead: function(){
    this.units.each(function(pair){
      pair.value.setStatus(false);
    });
  },
  
  purgeDeadUnits: function(){
    var thisContainer = this;
    this.units.each(function(pair){
      if(!pair.value.getStatus()){
        pair.value.destroy();
        thisContainer.unsetUnit(pair.key);
      }
    });
  }
  
});