@Override
  public void handleEvent(ActivityStartEvent event) {
    try {
      if (isTransitScenario) {
        if (transitDriverIds.contains(event.getPersonId())) return;
      }
      TravellerChain chain = chains.get(event.getPersonId());
      boolean beforeInPT = chain.isInPT();
      if (event.getActType().equals(PtConstants.TRANSIT_ACTIVITY_TYPE)) {
        chain.setInPT(true);

      } else {
        chain.setInPT(false);
        chain.traveling = false;
        Activity act = chain.addActivity();
        act.setCoord(network.getLinks().get(event.getLinkId()).getCoord());
        act.setFacility(event.getFacilityId());
        act.setStartTime(event.getTime());
        act.setType(event.getActType());
        // end the preceding journey
        Journey journey = chain.getJourneys().getLast();
        journey.setDest(act.getCoord());
        journey.setEndTime(event.getTime());
        journey.setToAct(act);
        if (beforeInPT) journey.getWalks().getLast().setEgressWalk(true);
      }
    } catch (Exception e) {
      System.err.println(e.getStackTrace());
      System.err.println(event.toString());
      ;
    }
  }
  @Override
  public void handleEvent(ActivityEndEvent event) {
    try {
      if (isTransitScenario) {
        if (transitDriverIds.contains(event.getPersonId())) return;
      }
      TravellerChain chain = chains.get(event.getPersonId());
      locations.put(event.getPersonId(), network.getLinks().get(event.getLinkId()).getCoord());
      if (chain == null) {
        chain = new TravellerChain();
        chains.put(event.getPersonId(), chain);
        Activity act = chain.addActivity();
        act.setCoord(network.getLinks().get(event.getLinkId()).getCoord());
        act.setEndTime(event.getTime());
        act.setFacility(event.getFacilityId());
        act.setStartTime(0.0);
        act.setType(event.getActType());

      } else if (!event.getActType().equals(PtConstants.TRANSIT_ACTIVITY_TYPE)) {
        Activity act = chain.getActs().getLast();
        act.setEndTime(event.getTime());
      }
    } catch (Exception e) {
      System.err.println(e.getStackTrace());
      System.err.println(event.toString());
    }
  }
 @Override
 public void handleEvent(VehicleArrivesAtFacilityEvent event) {
   try {
     ptVehicles.get(event.getVehicleId()).lastStop = event.getFacilityId();
   } catch (Exception e) {
     System.err.println(e.getStackTrace());
     System.err.println(event.toString());
   }
 }
 @Override
 public void handleEvent(PersonArrivalEvent event) {
   try {
     if (isTransitScenario) {
       if (transitDriverIds.contains(event.getPersonId())) return;
     }
     TravellerChain chain = chains.get(event.getPersonId());
     switch (event.getLegMode()) {
       case "walk":
       case "transit_walk":
         {
           Journey journey = chain.getJourneys().getLast();
           Walk walk = journey.getWalks().getLast();
           walk.setDest(network.getLinks().get(event.getLinkId()).getCoord());
           walk.setEndTime(event.getTime());
           walk.setDistance(walk.getDuration() * walkSpeed);
           break;
         }
       case TransportMode.car:
         {
           Journey journey = chain.getJourneys().getLast();
           journey.setDest(network.getLinks().get(event.getLinkId()).getCoord());
           journey.setEndTime(event.getTime());
           Trip trip = journey.getTrips().getLast();
           trip.setDistance(journey.getDistance());
           trip.setEndTime(event.getTime());
           chain.inCar = false;
           break;
         }
       case "pt":
         if (isTransitScenario) {
           Journey journey = chain.getJourneys().getLast();
           Trip trip = journey.getTrips().getLast();
           trip.setDest(network.getLinks().get(event.getLinkId()).getCoord());
           trip.setEndTime(event.getTime());
           journey.setPossibleTransfer(new Transfer());
           journey.getPossibleTransfer().setStartTime(event.getTime());
           journey.getPossibleTransfer().setFromTrip(trip);
         } else {
           Journey journey = chain.getJourneys().getLast();
           journey.setEndTime(event.getTime());
           journey.setDest(network.getLinks().get(event.getLinkId()).getCoord());
           journey.setEndTime(event.getTime());
         }
         break;
       default:
         Journey journey = chain.getJourneys().getLast();
         journey.setEndTime(event.getTime());
         journey.setDest(network.getLinks().get(event.getLinkId()).getCoord());
         journey.setEndTime(event.getTime());
         break;
     }
   } catch (Exception e) {
     System.err.println(e.getStackTrace());
     System.err.println(event.toString());
   }
 }
 @Override
 public void handleEvent(TeleportationArrivalEvent event) {
   try {
     if (transitDriverIds.contains(event.getPersonId())) return;
     TravellerChain chain = chains.get(event.getPersonId());
     if (chain.traveledVehicle) chain.traveledVehicle = false;
   } catch (Exception e) {
     System.err.println(e.getStackTrace());
     System.err.println(event.toString());
   }
 }
 @Override
 public void handleEvent(TransitDriverStartsEvent event) {
   try {
     ptVehicles.put(
         event.getVehicleId(), new PTVehicle(event.getTransitLineId(), event.getTransitRouteId()));
     transitDriverIds.add(event.getDriverId());
   } catch (Exception e) {
     System.err.println(e.getStackTrace());
     System.err.println(event.toString());
     ;
   }
 }
 @Override
 public void handleEvent(PersonStuckEvent event) {
   try {
     if (!transitDriverIds.contains(event.getPersonId())) {
       TravellerChain chain = chains.get(event.getPersonId());
       setStuck(getStuck() + 1);
       if (chain.getJourneys().size() > 0) chain.getJourneys().removeLast();
     }
   } catch (Exception e) {
     System.err.println(e.getStackTrace());
     System.err.println(event.toString());
   }
 }
  @Override
  public void handleEvent(LinkEnterEvent event) {
    try {
      if (ptVehicles.keySet().contains(event.getVehicleId())) {
        PTVehicle ptVehicle = ptVehicles.get(event.getVehicleId());
        ptVehicle.in = true;
        ptVehicle.setLinkEnterTime(event.getTime());
      } else {
        chains
            .get(driverIdFromVehicleId.get(event.getVehicleId()))
            .setLinkEnterTime(event.getTime());
      }

    } catch (Exception e) {
      System.err.println(e.getStackTrace());
      System.err.println(event.toString());
    }
  }
 @Override
 public void handleEvent(PersonEntersVehicleEvent event) {
   try {
     if (transitDriverIds.contains(event.getPersonId())) return;
     if (ptVehicles.keySet().contains(event.getVehicleId())) {
       TravellerChain chain = chains.get(event.getPersonId());
       Journey journey = chain.getJourneys().getLast();
       // first, handle the end of the wait
       journey.getWaits().getLast().setEndTime(event.getTime());
       // now, create a new trip
       ptVehicles.get(event.getVehicleId()).addPassenger(event.getPersonId());
       Trip trip = journey.addTrip();
       PTVehicle vehicle = ptVehicles.get(event.getVehicleId());
       trip.setLine(vehicle.transitLineId);
       trip.setMode(
           transitSchedule
               .getTransitLines()
               .get(vehicle.transitLineId)
               .getRoutes()
               .get(vehicle.transitRouteId)
               .getTransportMode());
       trip.setBoardingStop(vehicle.lastStop);
       trip.setOrig(journey.getWaits().getLast().getCoord());
       trip.setRoute(ptVehicles.get(event.getVehicleId()).transitRouteId);
       trip.setStartTime(event.getTime());
       // check for the end of a transfer
       if (journey.getPossibleTransfer() != null) {
         journey.getPossibleTransfer().setToTrip(trip);
         journey.getPossibleTransfer().setEndTime(event.getTime());
         journey.addTransfer(journey.getPossibleTransfer());
         journey.setPossibleTransfer(null);
       }
     } else {
       // add the person to the map that keeps track of who drives what
       // vehicle
       driverIdFromVehicleId.put(event.getVehicleId(), event.getPersonId());
     }
   } catch (Exception e) {
     System.err.println(e.getStackTrace());
     System.err.println(event.toString());
   }
 }
  @Override
  public void handleEvent(LinkLeaveEvent event) {
    try {
      if (ptVehicles.keySet().contains(event.getVehicleId())) {
        PTVehicle vehicle = ptVehicles.get(event.getVehicleId());
        if (vehicle.in) vehicle.in = false;
        vehicle.incDistance(network.getLinks().get(event.getLinkId()).getLength());

      } else {
        TravellerChain chain = chains.get(driverIdFromVehicleId.get(event.getVehicleId()));
        if (chain.inCar) {
          Journey journey = chain.getJourneys().getLast();
          journey.incrementCarDistance(network.getLinks().get(event.getLinkId()).getLength());
        }
      }
    } catch (Exception e) {
      System.err.println(e.getStackTrace());
      System.err.println(event.toString());
    }
  }
  @Override
  public void handleEvent(PersonLeavesVehicleEvent event) {
    if (transitDriverIds.contains(event.getPersonId())) return;
    try {
      if (ptVehicles.keySet().contains(event.getVehicleId())) {
        TravellerChain chain = chains.get(event.getPersonId());
        chain.traveledVehicle = true;
        PTVehicle vehicle = ptVehicles.get(event.getVehicleId());
        double stageDistance = vehicle.removePassenger(event.getPersonId());
        Trip trip = chain.getJourneys().getLast().getTrips().getLast();
        trip.setDistance(stageDistance);
        trip.setAlightingStop(vehicle.lastStop);
      } else {
        driverIdFromVehicleId.remove(event.getVehicleId());
      }

    } catch (Exception e) {
      System.err.println(e.getStackTrace());
      System.err.println(event.toString());
    }
  }
 @Override
 public void handleEvent(PersonDepartureEvent event) {
   try {
     if (transitDriverIds.contains(event.getPersonId())) return;
     TravellerChain chain = chains.get(event.getPersonId());
     Journey journey;
     Trip trip;
     switch (event.getLegMode()) {
       case TransportMode.walk:
         // fall through to the next
       case TransportMode.transit_walk:
         if (!chain.traveling) {
           chain.traveling = true;
           journey = chain.addJourney();
           journey.setOrig(network.getLinks().get(event.getLinkId()).getCoord());
           journey.setFromAct(chain.getActs().getLast());
           journey.setStartTime(event.getTime());
           Walk walk = journey.addWalk();
           walk.setAccessWalk(true);
           walk.setStartTime(event.getTime());
           walk.setOrig(journey.getOrig());
         } else {
           journey = chain.getJourneys().getLast();
           Walk walk = journey.addWalk();
           walk.setStartTime(event.getTime());
           walk.setOrig(network.getLinks().get(event.getLinkId()).getCoord());
           journey.getPossibleTransfer().getWalks().add(walk);
         }
         break;
       case TransportMode.car:
         chain.inCar = true;
         journey = chain.addJourney();
         journey.setCarJourney(true);
         journey.setOrig(network.getLinks().get(event.getLinkId()).getCoord());
         journey.setFromAct(chain.getActs().getLast());
         journey.setStartTime(event.getTime());
         trip = journey.addTrip();
         trip.setMode("car");
         trip.setStartTime(event.getTime());
         break;
       case TransportMode.pt:
         if (isTransitScenario) {
           // person waits till they enter the vehicle
           journey = chain.getJourneys().getLast();
           Wait wait = journey.addWait();
           if (journey.getWaits().size() == 1) wait.setAccessWait(true);
           wait.setStartTime(event.getTime());
           wait.setCoord(network.getLinks().get(event.getLinkId()).getCoord());
           if (!wait.isAccessWait()) {
             journey.getPossibleTransfer().getWaits().add(wait);
           }
         } else {
           journey = chain.addJourney();
           journey.setTeleportJourney(true);
           journey.setOrig(network.getLinks().get(event.getLinkId()).getCoord());
           journey.setFromAct(chain.getActs().getLast());
           journey.setStartTime(event.getTime());
           journey.setMainmode(event.getLegMode());
           trip = journey.addTrip();
           trip.setMode(event.getLegMode());
           trip.setStartTime(event.getTime());
         }
         break;
       default:
         journey = chain.addJourney();
         journey.setTeleportJourney(true);
         journey.setOrig(network.getLinks().get(event.getLinkId()).getCoord());
         journey.setFromAct(chain.getActs().getLast());
         journey.setStartTime(event.getTime());
         journey.setMainmode(event.getLegMode());
         trip = journey.addTrip();
         trip.setMode(event.getLegMode());
         trip.setStartTime(event.getTime());
         break;
     }
   } catch (Exception e) {
     System.err.println(e.getStackTrace());
     System.err.println(event.toString());
   }
 }