/*
 * ActionValue.java
 *
 *
 * Jim Frankenberger
 * USDA-ARS, West Lafayette IN
 * jrf@purdue.edu
 *
 * Created on August 27, 2004, 2:14 PM
 */
package ex1;

import java.util.*;

/**
 * This class holds all a process variables for a particular process within an
 * operation. There is one instance of this class created for each action tag
 * found in the detail operation xml files. The WepsDBFile class maintains a
 * list of these for each operation.
 *
 * @author jrf
 */
public class ActionValue {

   boolean operationOverwrite = false;

   private final HashMap<ParamDef, ParameterVal> children;   // the parameters for this action
   private OpAction opA;   // pointer to meta inforamtion about the action

   private InputLimits.TableStatus status; // stores the current table status.

   /**
    * Creates a new instance of Class
    */
   public ActionValue() {
      children = new HashMap<>();
      status = InputLimits.TableStatus.OKAY;
   }

   /**
    *
    * Initialize this from another instance.
    *
    * @param source object to copy values from
    */
   public ActionValue(ActionValue source) {
      children = new HashMap<>();
      opA = source.opA;

      Collection<ParameterVal> c = source.getAllParms();

      for (ParameterVal ap : c) {
         ParameterVal nap = new ParameterVal(ap.getInfo(), ap.getRawVal());
         children.put(ap.getInfo(), nap);
      }

      status = source.status;
   }

   /**
    *
    * This is called when an new process is added by the user. Values are
    * typically 0.0, 0 or the first entry in a choice list for this parameter.
    */
   public void fillWithDefaultParms() {
      int cnt = opA.getNumChildParms();
      for (int i = 0; i < cnt; i++) {
         ParamDef p = opA.getColumn(i);
         String val = p.getPseudoVal();
         ParameterVal nap = new ParameterVal(p, val);
         children.put(p, nap);
      }
   }

   /**
    * Attaches the meta-information about this process (all instances of this
    * process type will share the same info)
    *
    * @param a Action/process meta data object
    */
   public void setAction(OpAction a) {
      opA = a;
   }

   /**
    *
    * Add a new parameter to the list.
    *
    * @param p parameter meta-information
    * @param val value of the parameter
    */
   public void addParm(ParamDef p, String val) {
      ParameterVal ap = new ParameterVal(p, val);
      ParameterVal old = children.put(p, ap);
      if (old != null) {
         operationOverwrite = true;
      }
   }

   /**
    * Return the full name of the process, like 'P21 - Break Crust'
    *
    * @return Full name of the action
    */
   public String getName() {
      return opA.getFullName();
   }

   /**
    * Check if this process matches the requested action
    *
    * @param id numeric id part of action/processs
    * @param ty character part of action/process G,P,O
    * @return
    */
   public int actionCounts(int id, char ty) {
      if ((opA.id == id) && (opA.code == ty)) {
         return 1;
      } else {
         return 0;
      }
   }

   /**
    * Check if this action is the same as the requested one.
    *
    * @param a action to compare to
    * @return true if this action is the same type
    */
   public boolean sameOpAction(OpAction a) {
      return a == opA;
   }

   /**
    * Return the parameter value for a particlar column. The column number is
    * based on the actions as they were loaded from the config files. The order
    * of parameters within each detail xml can vary.
    *
    * @param col column to get parameter value from
    * @return Object containing parameter data
    */
   public ParameterVal getVal(int col) {
      ParamDef p = opA.getColumn(col);

      if (p != null) {
         ParameterVal pv = children.get(p);

         return pv;
      } else {
         return null;
      }
   }

   /**
    *
    * @param def
    * @return
    */
   public ParameterVal getVal(ParamDef def) {
      return children.get(def);
   }

   /**
    * Return the meta-information about the parameter for this column.
    *
    * @param col Column to get meta-information for
    * @return ParamDef structure holding info
    */
   public ParamDef getColumn(int col) {
      return opA.getColumn(col);
   }

   /**
    * Return all the parameters for this process as a list of ParameterVal
    * structs.
    *
    * @return a collection of ParameterVals
    */
   public Collection<ParameterVal> getAllParms() {
      return children.values();
   }

   /**
    * Returns the children ordered by columns.
    *
    * @param c
    * @return
    */
   public Collection<ParameterVal> getAllOrderedParms() {
      Collection<ParameterVal> c = new ArrayList<ParameterVal>(children.size());
      for (int i = 0; i < children.size(); i++) {
         ParamDef p = opA.getColumn(i);
         if (p != null) {
            ParameterVal pv = children.get(p);
            c.add(pv);
         }
      }

      return c;
   }

   /**
    * Return the meta-information about this process.
    *
    * @return meta information about this action
    */
   public OpAction getAction() {
      return opA;
   }

   /**
    * The P or G or O part of the action name.
    *
    * @return the character part of the action name (P,G,O)
    */
   public String getCode() {
      return String.valueOf(opA.code);
   }

   /**
    * The numeric part of the action name as a string.
    *
    * @return the numeric part of the action name as a string.
    */
   public String getID() {
      return String.valueOf(opA.id);
   }

   /**
    * The numeric part of the action name as an integer.
    *
    * @return the numeric part of the action name as an integer/
    */
   public int getIdInt() {
      return opA.id;
   }

   /*
	 * Get the group this process requires to proceed it. Used for checking the
	 * process order.
	 * 
	 * @return Get group this process belongs to
    */
   public String getGroupCode(int index) {
      if (index >= opA.getGroups()) {
         return null;
      } else {
         return String.valueOf(opA.getGroupCode(index));
      }
   }

   /*
	 * Get the number of possible groups that can precede this process. Used for checking the 
	 * process order.
	 *
    */
   public int getGroups() {
      return opA.getGroups();
   }

   /**
    * Get the group (numeric part) this process requires to proceed it. Used for
    * checking process order
    *
    * @param index
    * @return the integer part of the group this process belongs to
    */
   public int getGroupId(int index) {
      return opA.getGroupId(index);
   }

   /**
    * Check if this process matches the requested code (P,G,O).
    *
    * @param val the code to check for
    * @return true if code matches
    */
   public boolean isCode(char val) {
      return opA.code == val;
   }

   public void setStatus(InputLimits.TableStatus input) {
      status = input;
   }

   public InputLimits.TableStatus getStatus() {
      return status;
   }
}
