public float getCost(Floor floor, Direction destinationDirection) {
    // TODO: In morning simulation, cars get stuck on the top floor
    Assignment a = new Assignment(floor, destinationDirection);

    if (assignments.getCurrentAssignment() == null) {
      // don't care about direction
      float time = car.getTravelTime(floor);
      return time;
    }

    // Don't send another elevator to do the work if this elevator is already
    // doing it.
    if (assignments.contains(a)) return 0.0F;

    // factors:
    // 1. how much will it slow down the elevator in processing existing
    //    tasks?
    // 2. how long will it take for elevator to arrive *******
    // 3. how does this affect the distribution of elevators in the system?
    //    (probably would eventually be in Building)
    float cost = 0.0F;

    // For now, only #2 above is implemented.
    float currentHeight = car.getHeight();
    for (Iterator allDestinations =
            assignments.iteratorIncluding(
                car.getFloorRequestPanel().getServicedFloors(), getNearestBase(), a);
        allDestinations.hasNext(); ) {
      Assignment nextAssignment = (Assignment) allDestinations.next();
      Floor nextDestination = nextAssignment.getDestination();
      float nextHeight = nextDestination.getHeight();

      // stop condition when destination would be reached.
      // LATER: continue to evaluate total trip cost vs. partial trip cost
      //      if (a.equals(nextAssignment))
      //      {
      //        cost += car.getTravelTime(nextDestination.getHeight() - currentHeight);
      //        return cost;
      //      }

      // accumulator for number of stops
      cost += floor.getCarEntranceForCar(car).getDoor().getMinimumCycleTime();

      // accumulator for total distance
      cost += car.getTravelTime(nextHeight - currentHeight);

      currentHeight = nextHeight;

      if (nextAssignment.equals(a)) break;
    }

    // all destinations have been accumulated, and we did not add this stop.
    // So now the stop must be added specifically from the last stop.
    cost += car.getTravelTime(floor.getHeight() - currentHeight);
    return cost;
  }
 public void setNextDestination() {
   Floor location = car.getLocation();
   Assignment newAssignment = assignments.getCurrentAssignment();
   if (location != null && !location.getCallPanel().isDown() && !location.getCallPanel().isUp()) {
     while (newAssignment != null && newAssignment.getDestination() == location) {
       assignments.removeAssignment(newAssignment);
       newAssignment = assignments.getCurrentAssignment();
     }
   }
   if (newAssignment != null) car.setDestination(newAssignment.getDestination());
 }
 public boolean arrive(HashSet<Assignment> RequestAssignments) {
   // TODO Auto-generated method stub
   Floor location = car.getLocation();
   List serviceFloors = car.getFloorRequestPanel().getServicedFloors();
   Floor topFloor = (Floor) serviceFloors.get(serviceFloors.size() - 1);
   Floor bottomFloor = (Floor) serviceFloors.get(0);
   // remove from up/down list
   Assignment currentAssignment = assignments.getCurrentAssignment();
   if (RequestAssignments.contains(currentAssignment))
     RequestAssignments.remove(currentAssignment);
   assignments.removeAssignment(currentAssignment);
   // If the next assignment is on the same floor but going the other way
   // the doors would close and re-open.
   // To prevent this, we can remove that assignment and indicate that
   // we're at the "extreme" position, ready to go the other direction.
   Assignment newAssignment = assignments.getCurrentAssignment();
   while (newAssignment != null && newAssignment.getDestination() == location) {
     assignments.removeAssignment(newAssignment);
     if (RequestAssignments.contains(newAssignment)) RequestAssignments.remove(newAssignment);
     if (currentAssignment.getDirection() == Direction.UP) topFloor = location;
     else bottomFloor = location;
     newAssignment = assignments.getCurrentAssignment();
   }
   /*if (newAssignment!=null){
   	Floor floor=newAssignment.getDestination();
   	if (!serviceFloors.contains(floor)){
   		if (newAssignment.getDirection().isUp()){
   			if (!floor.getCallPanel().isUp())
   				assignments.removeAssignment(newAssignment);
   		}else{
   			if (!floor.getCallPanel().isDown())
   				assignments.removeAssignment(newAssignment);
   		}
   	}
   }*/
   boolean wasUp = currentAssignment.getDirection().isUp();
   boolean atExtreme = (wasUp && location == topFloor) || (!wasUp && location == bottomFloor);
   boolean isUp = atExtreme ? !wasUp : wasUp;
   return isUp;
 }
  /** The nearest base is the nearest floor we could reasonably stop at. */
  public Assignment getNearestBase() {
    Assignment current = assignments.getCurrentAssignment();
    Direction currAssignmentDirection = (current == null) ? Direction.NONE : current.getDirection();

    // The first case is the car is docked
    Floor carLocation = car.getLocation();
    if (carLocation != null) {
      final CarEntrance entrance = carLocation.getCarEntranceForCar(car);
      Direction dockedDirection =
          entrance.isUp()
              ? Direction.UP
              : entrance.isDown() ? Direction.DOWN : currAssignmentDirection;
      return new Assignment(carLocation, dockedDirection);
    }

    // The second case is the car is idle
    Floor f = car.getFloorAt();
    if (f != null) return new Assignment(f, currAssignmentDirection);

    // Finally, the third case is the car is travelling
    float currentHeight = car.getHeight();
    Direction carDirection =
        (current.getDestination().getHeight() < currentHeight) ? Direction.DOWN : Direction.UP;

    List floors = car.getFloorRequestPanel().getServicedFloors();
    for (Iterator i = createFloorContexts(floors, carDirection); i.hasNext(); ) {
      FloorContext context = (FloorContext) i.next();
      if (context.contains(currentHeight)) {
        float distance = Math.abs(context.getNext().getHeight() - currentHeight);
        boolean canCarStop = distance >= stoppingDistance;
        if (canCarStop || context.getNext() == getDestination())
          return new Assignment(context.getNext(), carDirection);
        return new Assignment(context.getSuccessor(), carDirection);
      }
    }
    throw new IllegalStateException("The car is somehow not between two floors.");
  }
 Floor getDestination() {
   Assignment current = assignments.getCurrentAssignment();
   if (current == null) return null;
   return current.getDestination();
 }