/**
 * FXML Controller class
 *
 * @author Mostafa
 */
public class LocalDeleteObjectInstanceServiceController implements Initializable {

  // Logger
  private static final Logger logger = LogManager.getLogger();

  @FXML private TextField ObjectInstanceDesignator;
  @FXML private Button OkButton;

  /** Initializes the controller class. */
  @Override
  public void initialize(URL url, ResourceBundle rb) {
    logger.entry();
    OkButton.disableProperty().bind(ObjectInstanceDesignator.textProperty().isEmpty());
    logger.exit();
  }

  @FXML
  private void Cancel_click(ActionEvent event) {
    logger.entry();
    ((Stage) OkButton.getScene().getWindow()).close();
    logger.exit();
  }

  @FXML
  private void Ok_click(ActionEvent event) {
    logger.entry();
    LogEntry log = new LogEntry("6.16", "Local Delete Object Instance service");
    try {
      ObjectInstanceHandle instanceHandle =
          rtiAmb
              .getObjectInstanceHandleFactory()
              .decode(
                  ByteBuffer.allocate(4)
                      .putInt(Integer.parseInt(ObjectInstanceDesignator.getText()))
                      .array(),
                  0);
      log.getSuppliedArguments()
          .add(
              new ClassValuePair(
                  "Object instance designator",
                  ObjectInstanceHandle.class,
                  instanceHandle.toString()));
      rtiAmb.localDeleteObjectInstance(instanceHandle);
      log.setDescription("Local Object instance deleted successfully");
      log.setLogType(LogEntryType.REQUEST);
    } catch (FederateNotExecutionMember
        | NotConnected
        | NumberFormatException
        | CouldNotDecode
        | RTIinternalError
        | OwnershipAcquisitionPending
        | FederateOwnsAttributes
        | ObjectInstanceNotKnown
        | SaveInProgress
        | RestoreInProgress ex) {
      log.setException(ex);
      log.setLogType(LogEntryType.ERROR);
      logger.log(Level.ERROR, ex.getMessage(), ex);
    } catch (Exception ex) {
      log.setException(ex);
      log.setLogType(LogEntryType.FATAL);
      logger.log(Level.FATAL, ex.getMessage(), ex);
    }
    logEntries.add(log);
    ((Stage) OkButton.getScene().getWindow()).close();
    logger.exit();
  }
}
/**
 * FXML Controller class
 *
 * @author Mostafa Ali <*****@*****.**>
 */
public class JoinFederationExecutionServiceController implements Initializable {

  // Logger
  private static final Logger logger = LogManager.getLogger();

  @FXML private TextField FederateName;
  @FXML private TextField FederateType;
  @FXML private TextField FederationExecutionName;
  @FXML private FilesList FomModuleDesignators;
  @FXML private Button OkButton;

  /** Initializes the controller class. */
  @Override
  public void initialize(URL url, ResourceBundle rb) {
    logger.entry();
    OkButton.disableProperty()
        .bind(
            Bindings.isEmpty(FederationExecutionName.textProperty())
                .or(Bindings.isEmpty(FederateType.textProperty())));
    logger.exit();
  }

  @FXML
  private void Cancel_click(ActionEvent event) {
    logger.entry();
    ((Stage) FederationExecutionName.getScene().getWindow()).close();
    logger.exit();
  }

  @FXML
  private void OK_click(ActionEvent event) {
    logger.entry();
    FederateHandle federateHandle;
    LogEntry log = new LogEntry("4.9", "Join Federation Execution service");
    try {
      if (!FederateName.getText().isEmpty()) {
        log.getSuppliedArguments()
            .add(new ClassValuePair("Federate Name", String.class, FederateName.getText()));
      }
      log.getSuppliedArguments()
          .add(new ClassValuePair("Federate Type", String.class, FederateType.getText()));
      log.getSuppliedArguments()
          .add(
              new ClassValuePair(
                  "Federation Execution Name", String.class, FederationExecutionName.getText()));
      List<URL> foms = new ArrayList<>();
      int i = 1;
      for (File file : FomModuleDesignators.getFiles()) {
        foms.add(file.toURI().toURL());
        log.getSuppliedArguments()
            .add(
                new ClassValuePair(
                    "FOM Module Deisgnator " + i++, URL.class, file.toURI().toURL().toString()));
      }
      if (FederateName.getText().isEmpty() && FomModuleDesignators.getFileNames().isEmpty()) {
        federateHandle =
            rtiAmb.joinFederationExecution(
                FederateType.getText(), FederationExecutionName.getText());
      } else if (FomModuleDesignators.getFileNames().isEmpty()) {
        federateHandle =
            rtiAmb.joinFederationExecution(
                FederateName.getText(), FederateType.getText(), FederationExecutionName.getText());
      } else if (FederateName.getText().isEmpty()) {
        federateHandle =
            rtiAmb.joinFederationExecution(
                FederateType.getText(),
                FederationExecutionName.getText(),
                foms.toArray(new URL[foms.size()]));
      } else {
        federateHandle =
            rtiAmb.joinFederationExecution(
                FederateName.getText(),
                FederateType.getText(),
                FederationExecutionName.getText(),
                foms.toArray(new URL[foms.size()]));
      }
      log.getReturnedArguments()
          .add(
              new ClassValuePair(
                  "Federate Handle", FederateHandle.class, federateHandle.toString()));
      log.setDescription("Federate joined federation execution successfully");
      log.setLogType(LogEntryType.REQUEST);
      logicalTimeFactory = rtiAmb.getTimeFactory();
      currentLogicalTime = logicalTimeFactory.makeInitial();

      // subscribe to HLAcurrentFDD to retrieve FDD
      ObjectClassHandle FederationHandle =
          rtiAmb.getObjectClassHandle("HLAobjectRoot.HLAmanager.HLAfederation");
      currentFDDHandle = rtiAmb.getAttributeHandle(FederationHandle, "HLAcurrentFDD");
      AttributeHandleSet set = rtiAmb.getAttributeHandleSetFactory().create();
      set.add(currentFDDHandle);
      rtiAmb.subscribeObjectClassAttributes(FederationHandle, set);
      rtiAmb.requestAttributeValueUpdate(FederationHandle, set, null);
      // In case of HLA_EVOKED we require this line to receive the FDD
      rtiAmb.evokeMultipleCallbacks(
          .05,
          1); // evoke one callback will not be enough because the reflect attribute is the second
              // one
    } catch (CouldNotCreateLogicalTimeFactory
        | CallNotAllowedFromWithinCallback
        | CouldNotOpenFDD
        | ErrorReadingFDD
        | InconsistentFDD
        | FederateNameAlreadyInUse
        | FederateAlreadyExecutionMember
        | FederationExecutionDoesNotExist
        | SaveInProgress
        | RestoreInProgress
        | NotConnected
        | RTIinternalError ex) {
      log.setException(ex);
      log.setLogType(LogEntryType.ERROR);
      logger.log(Level.ERROR, ex.getMessage(), ex);
    } catch (Exception ex) {
      log.setException(ex);
      log.setLogType(LogEntryType.FATAL);
      logger.log(Level.FATAL, ex.getMessage(), ex);
    }
    logEntries.add(log);
    ((Stage) FederationExecutionName.getScene().getWindow()).close();
    logger.exit();
  }
}