var BusIcon = Class.create({
  /**
  *constructor for BusIcon. Will create a bus icon and plot it on map with hover over text
  *@param unit - the results of a unit from the bus_plotter query
  *@param map - the google maps map
  *@param busPlotter - the bus plotter which creates the bus icon
  */
  initialize: function(unit, map, busPlotter){
    this.map = map;
    this.busPlotter = busPlotter;
    this.routePlotter = this.busPlotter.getRoutePlotter();
    this.isSelected = false;
    this.alive = true;
    this.liveBus = "./img/bus.png"
    this.deadBus = "./img/bus2.png"
    this.unit_id = unit.unit_id;
    this.bus_id = unit.bus_id;
    this.gps = $H(unit.gps);
    this.route_id = unit.routeId
    this.setLocation()
    this.live = this.gps.get('live');
    this.destination = unit.destination;

    this.setIcon();
    this.setMarker();
    this.setInfo();
    this.map.addOverlay(this.marker);
  },
  
  /*returns whether a bus is alive or not, note alive determines whether the route got updated or not from the server. It
   *is not the same as this.live which determines if the coordinates are live or scheduled coordinates. Non living bus icons
   * will be purged 
   */
  getStatus: function(){
    return this.alive;
  },
  
  /*sets whether a bus is alive or not*/
  setStatus: function(bool){
    this.alive = bool;
  },
  
  /**
  * updates the bus icon after getting data from hastus.
  * @param unit - the unit row returned from the servermathingy 
  * TODO, possibly change this to setUnit() and than call the same method from the constructor to reduce redundent data
  */
  update: function(unit){
    this.alive = true;
    this.route_id = unit.routeId
    this.gps = $H(unit.gps);
    this.live = this.gps.get('live');
    this.setLocation();
    this.destination = unit.destination;
    
    this.updateIcon();
    this.updateInfo();
    this.updateMarker();
  },
  
  /* updates the position of the marker */
  updateMarker: function(){
    this.marker.setLatLng(this.busLocation);
    this.marker.setImage(this.busIcon.image);
  },
  
  /* updates whether to show the live bus or the dead bus */
  updateIcon: function(){
    if(this.live == "true"){
      this.busIcon.image = this.liveBus;
    }else{
      this.busIcon.image = this.deadBus;
    }
  },
  
  /* updates the info box */
  updateInfo: function(){
    var text = "Bus: " + this.bus_id + "<br />" + "Route: " + this.route_id + "<br />" + "To: " + this.destination; 
    if(this.live == "true"){
      text = text + "<br />Updated At: " + this.check_in_time;
    }
    this.infoBox.updateText(text);
  },
  
  /* returns the unit id*/
  getUnitId: function(){
    return this.unit_id;
  },
  
  /* returns the route id*/
  getRouteId: function(){
    return this.route_id;
  },
  
  
  /* creates new GIcon for bus and than sets image according to this.updateIcon() */
  setIcon: function(){
    this.busIcon = new GIcon();
    this.updateIcon(); // sets the icon to live or dead
    this.busIcon.infoWindowAnchor = new GPoint(10, 0);
  	this.busIcon.iconSize = new GSize(25, 31);
  	this.busIcon.iconAnchor = new GLatLng(15.5, 12.5);
  },
  
  //creates a new Gmarker and sets it to the current busLocation using the current busIcon.
  setMarker: function(){
    this.marker = new GMarker(this.busLocation, {'icon': this.busIcon});
    
  },
  
  /* sets the appropriate location from the gps coordinates, also sets the check_in_time 
   * TODO, move the check_in_time to a more appropriate function or rename method to setGpsValues and set everything from the gps including live and lat and lng.
  */
  setLocation: function(){
    this.latitude = parseFloat(this.gps.get('lat'));
    this.longitude = -parseFloat(this.gps.get('lng')); //we use the negative longitude
    var check_in_time = new Date(parseInt(this.gps.get('checkInTime')));
    this.check_in_time = check_in_time.toTimeString();
    this.check_in_time = this.check_in_time.replace("GMT-0500 (EST)", "");
    this.busLocation = new GLatLng(this.latitude, this.longitude); //we are using negative longitude since dieselnet is retarted
  },
  
  /* creates an InfoWindow and binds it with the bus marker, callse updateInfo to set the text.*/
  setInfo: function(){
    this.infoBox = new InfoOverlay("");
    this.updateInfo();
    GEvent.bind(this.marker, "mouseover", this, this.onMouseOver);
  	GEvent.bind(this.marker, "mouseout", this, this.onMouseOut);
  	GEvent.bind(this.marker, "click", this, this.onClick);
  	GEvent.bind(this.marker, "infowindowclose", this, this.infoClosed);
  },
  
  /* this function should be binded to the infowindowclose event and will trigger onClick if selected in case user closes info box with [x] link */
  infoClosed: function(){
    if(this.isSelected){
      this.onClick()
    }
  },
  /* this function should be binded to the mouseover event. Will display info window unless already displayed and will also display polylines for bus icon unless already displayed */
  onMouseOver: function(){
    if(!this.isSelected && this.busPlotter.getSelectedBus() == null){
     this.marker.openInfoWindow(this.infoBox.getDiv(), {'noCloseOnClick': true});
    }
    if(ROUTE_POLYLINES[this.route_id] != null && !ROUTE_POLYLINES[this.route_id][1])
      ROUTE_POLYLINES[this.route_id][0].show();
  },
  
  /* this function should be binded to the mouseout event, should undo everything onMouseOver function does */
  onMouseOut: function(){
    if(!this.isSelected){
     this.marker.closeInfoWindow();
    }
    if(ROUTE_POLYLINES[this.route_id] != null && !ROUTE_POLYLINES[this.route_id][1])
      ROUTE_POLYLINES[this.route_id][0].hide();
  },
  
  /* this function should be binded to the click event. Will center map on bus, remove buses not on same route and display info window. should undo same events when clicked again*/
  onClick: function(toggleInfo){  
    if(this.isSelected){
      //toggle Routes all should reset everything for us.
      this.routePlotter.toggleRoute("ALL");
    }else{
      this.routePlotter.toggleRoute("ALL")
      //if(toggleInfo){ 
        this.marker.openInfoWindow(this.infoBox.getDiv(), {'noCloseOnClick': true});
      //}
      this.isSelected = true;
      if(!this.routePlotter.is_set(this.route_id)){
        this.routePlotter.toggleRoute(this.route_id);
      }
      this.busPlotter.selectBus(this);
    }
    this.map.panTo(this.busLocation);
  },
  
  /* sets the bus to selected */
  setIsSelected: function(bool){
    this.isSelected = bool;
  },
  
  /* hides this bus icon by hiding the marker */
  hide: function(){
    this.marker.hide();
  },
  
  /* shows this bus icon by showing the marker */
  show: function(){
    this.marker.show();
  },
  
  /* returns teh bus marker */
  getMarker: function(){
    return this.marker;
  },
  
  /* removes the marker from the map permanantly*/
  destroy: function(){
    this.map.removeOverlay(this.marker);
    if(ROUTE_POLYLINES[this.route_id] != null && !ROUTE_POLYLINES[this.route_id][1] )
      ROUTE_POLYLINES[this.route_id][0].hide();
  }
});