package simulator;

import java.util.ArrayList;
import java.util.HashMap;

public class Constituent {

    public enum Status {IDLE, SELECTION, OPERATING}

    private ArrayList<Action> actionList = null;
    private ArrayList<Action> capabilityList = null; // 일단 보존
    private HashMap<String, Integer> capabilityMap = null; // 각 CS의 Action 당 사용되는 cost <Action_name, cost>

    private String name;
    private int usedCost;
    private int totalBudget;
    private int accumulatedBenefit;
    private Status status;

    public Constituent(String name){
        this.name = name;
        this.actionList = new ArrayList<Action>();
        this.capabilityList = new ArrayList<Action>();
        this.capabilityMap = new HashMap<String, Integer>();
        this.usedCost = 0;
        this.totalBudget = 100;
        this.accumulatedBenefit = 0;
        this.status = Status.IDLE;
    }

    /**
     * step method
     * CS chooses an action according to probability distribution.
     * Before selecting, the CS checks the acknowledgement from SoS manager.
     * @return chosen Action instance
     */
    public Action step(){
        if(this.getRemainBudget() == 0){
            return null; // voidAction, nothing happen
        }else{ // We have money
            /*
             * 1. If the status of CS is IDLE (currently no job), then select a job (immediate action)
             * 2. If the status of CS is SELECTION, then
             */
            if(this.status == Status.IDLE){ // Select an action
                /* How to choose an action
                 * 1. Get a list of available actions
                 * 2. Calculate the utilities to do actions
                 * 3. Choose the best action to get the most utility
                 */
                ArrayList<Action> availableActions = new ArrayList<Action>();
                for(Action a : this.actionList){
                    if(a.getStatus() == Action.Status.RAISED)
                        availableActions.add(a);
                }

                int bestIndex = -1;
                if(availableActions.size() > 1){
                    bestIndex = 0;
                    for(int i=1; i<availableActions.size(); i++){
                        if(this.getUtility(availableActions.get(bestIndex))
                                < this.getUtility(availableActions.get(i))){
                            bestIndex = i;
                        }
                    }

                }else if(availableActions.size() == 0){

                }else{
                    bestIndex = 0;
                }
            }
            ArrayList<Action> tempList = new ArrayList<Action>(this.actionList.size());
            tempList.addAll(this.actionList);
            for(Action a : this.actionList){
                if(this.getCost(a) > this.getRemainBudget()){
                    tempList.remove(a);
                }
            }
            if(tempList.size() > 0)
                return selectAction(tempList);
            else{ // We don't have enough money to execute an action.
                return null;
            }
        }
    }

    private Action selectAction(ArrayList<Action> actions){
        // TODO: 2016-08-02 Select action based on probability distribution of utility
        Action retAction = actions.get(0);
        for(Action a : actions){
            if(getUtility(a) > getUtility(retAction)){
                retAction = a;
            }
        }
        return retAction;
    }

    public int getRemainBudget(){
        return this.totalBudget - this.usedCost;
    }

    public void updateCostBenefit(int cost, int benefit){
        this.usedCost += cost;
        this.accumulatedBenefit += benefit;
    }

    private int getUtility(Action a){
        return a.getBenefit() - this.getCost(a);
    }

    public String toString(){
        return this.name;
    }

    public int getAccumulatedBenefit(){
        return this.accumulatedBenefit;
    }

    public void addCapability(Action a, int cost){
        this.capabilityList.add(a);
        this.capabilityMap.put(a.getName(), cost);
    }

    public ArrayList<Action> getCapability(){
        return this.capabilityList;
    }

    public ArrayList<Action> getActionList(){
        return this.actionList;
    }

    public int getCost(Action a){
        Integer _cost = this.capabilityMap.get(a.getName());
        if(_cost != null)
            return _cost;
        else
            return 0;
    }

    public void updateActionList(ArrayList<Action> _list){
        ArrayList<Action> newList = new ArrayList<Action>(this.actionList.size());
        for(Action target : _list){
            newList.add(target);
        }
        this.actionList = newList;
    }

    public Status getStatus(){
        return this.status;
    }

}

@@ -153,57 +153,8 @@
 G%7D%0A%0A
-    private ArrayList%3CAction%3E actionList = null;%0A
     
@@ -211,16 +211,16 @@
 / %EC%9D%BC%EB%8B%A8 %EB%B3%B4%EC%A1%B4%0A
+
     priv
@@ -530,59 +530,8 @@
 me;%0A
-        this.actionList = new ArrayList%3CAction%3E();%0A
     
@@ -1758,38 +1758,42 @@
 Action a : this.
-action
+capability
 List)%7B%0A         
@@ -2334,32 +2334,117 @@
                %7D
+%0A                    String selectedName = availableActions.get(bestIndex).getName();
 %0A%0A              
@@ -2579,466 +2579,211 @@
    %7D
-%0A            ArrayList%3CAction%3E tempList = new ArrayList%3CAction%3E(this.actionList.size());%0A            tempList.addAll(this.actionList);%0A            for(Action a : this.actionList)%7B%0A                if(this.getCost(a) %3E this.getRemainBudget())%7B%0A                    tempList.remove(a);%0A                %7D%0A            %7D%0A            if(tempList.size() %3E 0)%0A                return selectAction(tempList);%0A            else%7B // We don't have enough money to execute an
+else if(this.status == Status.SELECTION)%7B // Selecting%0A                /* Selecting the action at the immediate action step%0A                 * If we select the action, then this CS will try to choose the
  act
@@ -2803,28 +2803,19 @@
         
-return null;
+ */
 %0A       
@@ -2826,24 +2826,46 @@
  %7D%0A        %7D
+%0A%0A        return null;
 %0A    %7D%0A%0A    
@@ -3938,93 +3938,8 @@
  %7D%0A%0A
-    public ArrayList%3CAction%3E getActionList()%7B%0A        return this.actionList;%0A    %7D%0A%0A
     
@@ -4241,30 +4241,34 @@
 ction%3E(this.
-action
+capability
 List.size())
@@ -4361,22 +4361,26 @@
    this.
-action
+capability
 List = n

Edit from actionList to capabilityList