package org.lodder.subtools.multisubdownloader.actions;

import java.util.List;

import org.lodder.subtools.multisubdownloader.Messages;
import org.lodder.subtools.multisubdownloader.exceptions.SearchSetupException;
import org.lodder.subtools.multisubdownloader.gui.dialog.Cancelable;
import org.lodder.subtools.multisubdownloader.listeners.IndexingProgressListener;
import org.lodder.subtools.multisubdownloader.listeners.SearchProgressListener;
import org.lodder.subtools.multisubdownloader.listeners.StatusListener;
import org.lodder.subtools.multisubdownloader.settings.model.Settings;
import org.lodder.subtools.multisubdownloader.subtitleproviders.SubtitleProvider;
import org.lodder.subtools.multisubdownloader.subtitleproviders.SubtitleProviderStore;
import org.lodder.subtools.multisubdownloader.workers.SearchHandler;
import org.lodder.subtools.multisubdownloader.workers.SearchManager;
import org.lodder.subtools.sublibrary.logging.Logger;
import org.lodder.subtools.sublibrary.model.Release;

public abstract class SearchAction implements Runnable, Cancelable, SearchHandler {

  protected Settings settings;
  protected SubtitleProviderStore subtitleProviderStore;
  protected SearchManager searchManager;
  protected List<Release> releases;
  protected IndexingProgressListener indexingProgressListener;
  protected SearchProgressListener searchProgressListener;
  protected StatusListener statusListener;

  public void setSettings(Settings settings) {
    this.settings = settings;
  }

  public void setProviderStore(SubtitleProviderStore store) {
    this.subtitleProviderStore = store;
  }

  public void setStatusListener(StatusListener listener) {
    this.statusListener = listener;
  }

  public void setSearchProgressListener(SearchProgressListener listener) {
    this.searchProgressListener = listener;
  }

  public void setIndexingProgressListener(IndexingProgressListener listener) {
    this.indexingProgressListener = listener;
  }

  @Override
  public void run() {
    Logger.instance.trace(this.getClass().getSimpleName(), "run", "SearchAction is being executed");
    try {
      this.search();
    } catch (ActionException e) {
      Logger.instance.error(e.getMessage());
      if (this.statusListener != null) {
        this.statusListener.onError(e);
      }
    }
  }

  private void search() throws ActionException {
    this.setStatusListener(this.indexingProgressListener);

    validate();

    String languageCode = this.getLanguageCode();

    setStatusMessage(Messages.getString("SearchAction.StatusIndexing"));

    this.releases = createReleases();

    if (Thread.currentThread().isInterrupted()) return;

    if (this.releases.size() <= 0) {
      this.cancel(true);
      return;
    }

    this.indexingProgressListener.completed();

    this.setStatusListener(this.searchProgressListener);

    /* Create a new SearchManager. */
    this.searchManager = new SearchManager(this.settings);

    /* Tell the manager which language we want */
    this.searchManager.setLanguage(languageCode);

    /* Tell the manager which providers to use */
    for (SubtitleProvider subtitleProvider : this.subtitleProviderStore.getAllProviders()) {
      if (!settings.isSerieSource(subtitleProvider.getName())) {
        continue;
      }

      this.searchManager.addProvider(subtitleProvider);
    }

    /* Tell the manager which releases to search. */
    for (Release release : this.releases) {
      this.searchManager.addRelease(release);
    }

    /* Listen for when the manager tells us Subtitles are found */
    this.searchManager.onFound(this);

    /* Tell the manager where to push progressUpdates */
    this.searchManager.setProgressListener(this.searchProgressListener);

    setStatusMessage(Messages.getString("SearchAction.StatusSearching"));

    /* Tell the manager to start searching */
    this.searchManager.start();
  }

  protected abstract List<Release> createReleases() throws ActionException;

  protected void setStatusMessage(String message) {
    this.statusListener.onStatus(message);
  }

  @Override
  public boolean cancel(boolean mayInterruptIfRunning) {
    if (searchManager != null) this.searchManager.cancel(mayInterruptIfRunning);
    Thread.currentThread().interrupt();
    this.indexingProgressListener.completed();
    this.searchProgressListener.completed();
    return true;
  }

  protected abstract String getLanguageCode();

  protected String getLanguageCode(String language) {
    if (language.equals("Nederlands")) {
      return "nl";
    } else if (language.equals("Engels")) {
      return "en";
    }
    return null;
  }

  protected void validate() throws SearchSetupException {
    if (this.settings == null) {
      throw new SearchSetupException("Settings must be set.");
    }
    if (this.subtitleProviderStore == null) {
      throw new SearchSetupException("SubtitleProviderStore must be set.");
    }
    if (this.searchProgressListener == null) {
      throw new SearchSetupException("SearchProgressListener must be set.");
    }
    if (this.indexingProgressListener == null) {
      throw new SearchSetupException("IndexingProgressListener must be set.");
    }
  }

}

@@ -932,75 +932,78 @@
 ary.
-logging.Logger;%0Aimport org.lodder.subtools.sublibrary.model.Release
+model.Release;%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory
 ;%0A%0Ap
@@ -1415,16 +1415,103 @@
 istener;
+%0A  %0A  private static final Logger LOGGER = LoggerFactory.getLogger(SearchAction.class);
 %0A%0A  publ
@@ -2090,69 +2090,20 @@
    L
-ogger.instance.trace(this.getClass().getSimpleName(), %22run%22, 
+OGGER.trace(
 %22Sea
@@ -2209,28 +2209,19 @@
    L
-ogger.instance.error
+OGGER.trace
 (e.g
@@ -2231,16 +2231,19 @@
 essage()
+, e
 );%0A     

Convert SearchAction from old logger to new LOGGER slf4j