package org.triplea.client.ui.javafx;

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.function.Function;

import javafx.application.Platform;

/**
 * A utility class for executing synchronous Tasks using the JavaFX-UI.
 * @param <T> The Object type which is being returned by this task. May be null.
 */
public final class LoadingTask<T> {

  private final Function<LoadingTask<T>, T> function;
  private final TripleA triplea;

  public LoadingTask(final TripleA triplea, final Function<LoadingTask<T>, T> function) {
    this.triplea = checkNotNull(triplea);
    this.function = checkNotNull(function);
  }

  /**
   * The public method which should be used to start the task
   *
   * @return An object of type T which is generated by the task, may be null.
   */
  public T run() {
    if (Platform.isFxApplicationThread()) {
      throw new IllegalStateException("This method must not be called on the FX Application Thread!");
    }
    try {
      Platform.runLater(() -> triplea.displayLoadingScreen(true));
      return function.apply(this);
    } finally {
      Platform.runLater(() -> {
        triplea.displayLoadingScreen(false);
        triplea.setLoadingMessage("");
      });
    }
  }

  public void setLoadingMesage(final String message) {
    Platform.runLater(() -> triplea.setLoadingMessage(message));
  }
}
