/*
 * Copyright 2015 JBoss Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.optaplanner.examples.coachshuttlegathering.solver;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.optaplanner.core.api.score.buildin.hardsoftlong.HardSoftLongScore;
import org.optaplanner.core.impl.score.director.easy.EasyScoreCalculator;
import org.optaplanner.examples.coachshuttlegathering.domain.Bus;
import org.optaplanner.examples.coachshuttlegathering.domain.BusStop;
import org.optaplanner.examples.coachshuttlegathering.domain.Coach;
import org.optaplanner.examples.coachshuttlegathering.domain.CoachShuttleGatheringSolution;
import org.optaplanner.examples.coachshuttlegathering.domain.Shuttle;
import org.optaplanner.examples.coachshuttlegathering.domain.StopOrHub;

public class CoachShuttleGatheringEasyScoreCalculator implements EasyScoreCalculator<CoachShuttleGatheringSolution> {

    public HardSoftLongScore calculateScore(CoachShuttleGatheringSolution solution) {
        long hardScore = 0L;
        long softScore = 0L;
        List<Bus> busList = solution.getBusList();
        Map<Bus, Integer> busToPassengerTotalMap = new LinkedHashMap<Bus, Integer>(busList.size());
        Map<Coach, Integer> coachToStopCountMap = new LinkedHashMap<Coach, Integer>(busList.size());
        for (BusStop stop : solution.getStopList()) {
            Bus bus = stop.getBus();
            if (bus != null) {
                // Constraint shuttleCapacity and coachCapacity
                Integer passengerTotal = busToPassengerTotalMap.get(bus);
                if (passengerTotal == null) {
                    passengerTotal = 0;
                }
                passengerTotal += stop.getPassengerQuantity();
                busToPassengerTotalMap.put(bus, passengerTotal);
                if (bus instanceof Shuttle) {
                    Shuttle shuttle = (Shuttle) bus;
                    StopOrHub destination = shuttle.getDestination();
                    if (destination instanceof BusStop) {
                        Bus destinationBus = ((BusStop) destination).getBus();
                        Integer destinationPassengerTotal = busToPassengerTotalMap.get(bus);
                        if (destinationPassengerTotal == null) {
                            destinationPassengerTotal = 0;
                        }
                        destinationPassengerTotal += stop.getPassengerQuantity();
                        busToPassengerTotalMap.put(bus, destinationPassengerTotal);
                    }
                }
                // Constraint coachStopLimit
                if (bus instanceof Coach) {
                    Coach coach = (Coach) bus;
                    Integer stopCount = coachToStopCountMap.get(coach);
                    stopCount = (stopCount == null) ? 1 : stopCount + 1;
                    coachToStopCountMap.put(coach, stopCount);
                }
            }
            // Constraint transportTime
            Integer transportTimeRemainder = stop.getTransportTimeRemainder();
            if (transportTimeRemainder != null && transportTimeRemainder < 0) {
                hardScore += transportTimeRemainder;
            }
            // Constraint distanceFromPrevious
            if (stop.getPreviousBusOrStop() != null) {
                softScore -= stop.getDistanceFromPreviousCost();
            }
            // Constraint distanceBusStopToBusDestination
            if (stop.getNextStop() == null && bus != null && bus.getDestination() != null) {
                softScore -= stop.getDistanceToDestinationCost(bus.getDestination());
            }
        }
        for (Bus bus : busList) {
            // Constraint shuttleCapacity and coachCapacity
            Integer passengerTotal = busToPassengerTotalMap.get(bus);
            if (passengerTotal != null && passengerTotal > bus.getCapacity()) {
                hardScore -= passengerTotal * 1000L;
            }
            if (bus instanceof Coach) {
                // Constraint coachStopLimit
                Coach coach = (Coach) bus;
                Integer stopCount = coachToStopCountMap.get(coach);
                if (stopCount != null && stopCount > coach.getStopLimit()) {
                    hardScore += (coach.getStopLimit() - stopCount) * 1000000L;
                }
                // Constraint distanceCoachDirectlyToDestination
                if (coach.getNextStop() == null) {
                    softScore -= coach.getDistanceToDestinationCost();
                }
            }
            if (bus instanceof Shuttle) {
                // Constraint shuttleDestinationIsCoachOrHub
                Shuttle shuttle = (Shuttle) bus;
                StopOrHub destination = shuttle.getDestination();
                if (destination instanceof BusStop) {
                    Bus destinationBus = ((BusStop) destination).getBus();
                    if (destinationBus instanceof Shuttle) {
                        hardScore -= 1000000000L;
                    }
                }
                // Constraint shuttleSetupCost
                if (shuttle.getNextStop() != null) {
                    softScore -= shuttle.getSetupCost();
                }
            }
        }
        // TODO
        return HardSoftLongScore.valueOf(hardScore, softScore);
    }

}

@@ -2652,32 +2652,125 @@
 tion).getBus();%0A
+                        if (destinationBus != null && destinationBus instanceof Coach) %7B%0A    
                 
@@ -2832,38 +2832,53 @@
 gerTotalMap.get(
-b
+destinationB
 us);%0A
+    
                 
@@ -2918,32 +2918,36 @@
 otal == null) %7B%0A
+    
                 
@@ -3005,34 +3005,42 @@
                 
-%7D%0A
+    %7D%0A    
                 
@@ -3121,32 +3121,36 @@
                 
+    
 busToPassengerTo
@@ -3156,25 +3156,36 @@
 otalMap.put(
-b
+destinationB
 us, destinat
@@ -3196,32 +3196,58 @@
 assengerTotal);%0A
+                        %7D%0A
                 
@@ -4624,18 +4624,39 @@
 rdScore 
--=
++= (bus.getCapacity() -
  passeng
@@ -4662,16 +4662,17 @@
 gerTotal
+)
  * 1000L
@@ -5978,24 +5978,8 @@
   %7D%0A
-        // TODO%0A
     

fix CoachShuttleGatheringEasyScoreCalculator