Event.java [src/nodes] Revision: default  Date:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package nodes;

import csip.api.server.ServiceException;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import nodes.factories.CropFactory;
import nodes.factories.OperationFactory;
import nodes.factories.ResidueFactory;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import parsers.ParseTypes;
import parsers.ParserException;
import parsers.WEPSParser;
import translators.Translator.FORMAT;
import static utils.Constants.*;

/**
 *
 * @author Brad
 */
public class Event implements Comparable {
  private LocalDate date;
  private Operation operation;
  private Crop crop;
  private Residue residue;
  private int residueAmount;
  private int rowDirection;
  private double targetYield;

  public Operation getOperation() {
    return operation;
  }

  public Crop getCrop() {
    return crop;
  }

  public Residue getResidue() {
    return residue;
  }

  public LocalDate getDate() {
    return date;
  }

  public void setDate(LocalDate date) {
    this.date = date;
  }

  public int getResidueAmount() {
    return residueAmount;
  }

  public void addResidue(Residue res) {
    residue = res;
  }

  public void removeCrop() {
    crop = null;
  }

  public void readJSONData(JSONObject jdatum, FORMAT type) throws JSONException {

    date = LocalDate.parse(jdatum.getString(DATE), DateTimeFormatter.ISO_DATE);

    operation = OperationFactory.createOperation(type);

    if (jdatum.has(RES_ADDED))
      residueAmount = jdatum.getInt(RES_ADDED);
    else
      residueAmount = -1;
    if (jdatum.has(ROW_DIRECTION))
      rowDirection = jdatum.getInt(ROW_DIRECTION);
    else
      rowDirection = 0; // If data comes for crlmod it won't have a row direction
    if (jdatum.has(YIELD))
      targetYield = jdatum.getDouble(YIELD);
    else
      targetYield = -1;

    if (jdatum.has(CROP))
      crop = CropFactory.createCrop(type);

    if (jdatum.has(RESIDUE))
      residue = ResidueFactory.createResidue(type);

    switch (type) {
      case WEPS:
        operation.addProperty("crop", crop);
        operation.addProperty("residue", residue);
        operation.rowDirection = rowDirection;
        operation.residueAmount = residueAmount;
        break;
    }
    operation.readJSONData(jdatum.getJSONObject(OPERATION));

    if (crop != null) {
      crop.readJSONData(jdatum.getJSONObject(CROP));
      crop.targetYield = targetYield;
    }

    if (residue != null) {
      residue.readJSONData(jdatum.getJSONObject(RESIDUE));
    }

  }

  public void readManData(WEPSParser parser) throws ParserException, IOException, ServiceException {
    ParseTypes type;
    WEPSAction action;

    while ((type = parser.readNext()) != ParseTypes.ENDOP) {
      if (type == ParseTypes.OPERATION) {
        operation = parser.getOperation();
      }
      if (type == ParseTypes.CROP) {
        crop = parser.getCrop();
      }
      if (type == ParseTypes.ACTION) {
        action = parser.getAction();
        operation.addProperty("action", action);
      }
    }
  }

  // Do not override equals because there is nothing to make an event unique aside from the memory address
  @Override
  public int compareTo(Object o) {
    //  Get simple compareTo() from LocalDate first...
    int result = this.getDate().compareTo((( Event ) o).getDate());

    //  If dates are equal, then prioritize by operation type.
    //  So far only a "kill crop" operation takes precedence over all others.
    //    Also, Note:  Both tests for equal are used here in case LocalDate ever
    //  rewrites its current compareTo() funciton, which has an undefined
    //  result (per their own JavaDoc) when the dates are equal.
    //  (Source code for LocalDate shows the return value to be "0" currently,
    //  but this could change since it is not documented as a valid result of that funciton.
    if ((0 == result) || this.getDate().equals((( Event ) o).getDate())) {

      result = 1;

//  This version of Event has no way to know if this is a kill_crop operation, does it??
//            if ( (((Event)o).operation.kill_crop ) && (this.operation.kill_crop) ) {
//                // If it is a kill crop make it "earlier"
//                result = -1;
//            }else{
//                //  Otherwise if it is not a "kill crop", or if this one is also a "kill crop", then make it "later".
//                result = 1;
//            }
    }

    return result;
  }
}