package droplauncher.mvc.model;

import adakite.utils.AdakiteUtils;
import droplauncher.mvc.view.View;
import droplauncher.bwheadless.BWHeadless;
import droplauncher.bwheadless.ReadyStatus;
import droplauncher.ini.IniFile;
import droplauncher.mvc.view.LaunchButtonText;
import droplauncher.starcraft.Race;
import droplauncher.starcraft.Starcraft;
import droplauncher.util.Constants;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.filechooser.FileNameExtensionFilter;

public class Model {

  private static final Logger LOGGER = Logger.getLogger(Model.class.getName());
  private static final boolean CLASS_DEBUG = (Constants.DEBUG && true);

  public static final File DROP_LAUNCHER_INI = new File("droplauncher.ini");

  private View view;

  private BWHeadless bwheadless;
  private IniFile ini;

  public Model() {
    this.bwheadless = new BWHeadless();
    this.ini = new IniFile();

    this.bwheadless.setIniFile(this.ini);
    try {
      this.ini.open(DROP_LAUNCHER_INI);
      this.bwheadless.readSettingsFile(this.ini);
    } catch (Exception ex) {
      LOGGER.log(Constants.DEFAULT_LOG_LEVEL, null, ex);
    }
  }

  public void setView(View view) {
    this.view = view;
  }

  public BWHeadless getBWHeadless() {
    return this.bwheadless;
  }

  /**
   * Reads a dropped or selected file which is meant for the
   * bwheadless.exe process and sets the appropiate settings.
   *
   * @param file specified file to process
   */
  private void processFile(File file) {
    String ext = AdakiteUtils.getFileExtension(file);
    if (ext != null) {
      if (ext.equalsIgnoreCase("dll")) {
        if (file.getName().equalsIgnoreCase("BWAPI.dll")) {
          this.bwheadless.setBwapiDll(file.getAbsolutePath());
        } else {
          this.bwheadless.setBotRace(BWHeadless.DEFAULT_BOT_RACE);
          this.bwheadless.setBotDll(file.getAbsolutePath());
        }
      } else if (ext.equalsIgnoreCase("exe")) {
        this.bwheadless.setBotRace(BWHeadless.DEFAULT_BOT_RACE);
        this.bwheadless.setBotClient(file.getAbsolutePath());
      } else if (ext.equalsIgnoreCase("jar")) {
        this.bwheadless.setBotRace(BWHeadless.DEFAULT_BOT_RACE);
        this.bwheadless.setBotClient(file.getAbsolutePath());
      } else {
        /* If file extension is not recognized, ignore file. */
      }
    } else {
      /* If no file extension is detected, ignore file. */
    }
  }

  /* ************************************************************ */
  /* Events from View */
  /* ************************************************************ */

  public void boxDropFilesMouseClicked(MouseEvent evt) {
    JFileChooser fc = new JFileChooser();
    fc.setAcceptAllFileFilterUsed(false);
    fc.setMultiSelectionEnabled(true);
    fc.setFileFilter(new FileNameExtensionFilter("All supported files (*.dll, *.exe)", "dll", "exe"));
    if (this.view.showFileChooser(fc) == JFileChooser.APPROVE_OPTION) {
      File[] fileList = fc.getSelectedFiles();
      if (fileList != null && fileList.length > 0) {
        for (File file : fileList) {
          processFile(file);
        }
      }
      this.view.update();
    }
  }

  public void btnLaunchActionPerformed(ActionEvent evt) {
    ReadyStatus status = this.bwheadless.getReadyStatus();
    if (status != ReadyStatus.READY) {
      this.view.showMessageBox(JOptionPane.ERROR_MESSAGE, "Not ready: " + status.toString());
      return;
    }
    if (this.bwheadless.isRunning()) {
      this.bwheadless.stop();
    } else {
      this.bwheadless.start();
    }
    this.view.update();
  }

  public void btnStarcraftExeActionPerformed(ActionEvent evt) {
    //TODO: Only accept StarCraft.exe file selection.
    //TODO: Guess StarCraft directory or read from registry.
    JFileChooser fc = new JFileChooser(new File("C:\\StarCraft"));
    fc.setAcceptAllFileFilterUsed(false);
    fc.setFileFilter(new FileNameExtensionFilter("*.exe", "exe"));
    if (this.view.showFileChooser(fc) == JFileChooser.APPROVE_OPTION) {
      File file = fc.getSelectedFile();
      if (file != null) {
        this.bwheadless.setStarcraftExe(file.getAbsolutePath());
        this.view.getLabelStarcraftExeText().setText(this.bwheadless.getStarcraftExe());
      }
    }
  }

  public void filesDropped(File[] files) {
    /* Parse all objects dropped into a complete list of files dropped since
       dropping a directory does NOT include all subdirectories and
       files by default. */
    ArrayList<File> fileList = new ArrayList<>();
    for (File file : files) {
      if (file.isDirectory()) {
        try {
          Path[] tmpList = AdakiteUtils.getDirectoryContents(file.toPath(), true);
          for (Path tmpPath : tmpList) {
            fileList.add(tmpPath.toFile());
          }
        } catch (IOException ex) {
          if (CLASS_DEBUG) {
            LOGGER.log(Constants.DEFAULT_LOG_LEVEL, null, ex);
          }
        }
      } else if (file.isFile()) {
        fileList.add(file);
      } else {
        if (CLASS_DEBUG) {
          LOGGER.log(Constants.DEFAULT_LOG_LEVEL, "Unknown file dropped: " + file.getAbsolutePath());
        }
      }
    }

    /* Process all files. */
    for (File file : fileList) {
      processFile(file);
    }

    this.view.update();
  }

  public void rbRaceProtossActionPerformed(ActionEvent evt) {
    this.bwheadless.setBotRace(Race.PROTOSS);
  }

  public void rbRaceRandomActionPerformed(ActionEvent evt) {
    this.bwheadless.setBotRace(Race.RANDOM);
  }

  public void rbRaceTerranActionPerformed(ActionEvent evt) {
    this.bwheadless.setBotRace(Race.TERRAN);
  }

  public void rbRaceZergActionPerformed(ActionEvent evt) {
    this.bwheadless.setBotRace(Race.ZERG);
  }

  public void txtBotNameKeyReleased(KeyEvent evt) {
    JTextField txt = this.view.getTextFieldBotName();
    int caret = txt.getCaretPosition();
    String botName = txt.getText();
    String botNameFixed = Starcraft.cleanProfileName(botName);
    if (AdakiteUtils.isNullOrEmpty(botNameFixed)) {
      botNameFixed = BWHeadless.DEFAULT_BOT_NAME;
      caret = botNameFixed.length();
    }
    if (!botName.equalsIgnoreCase(botNameFixed)) {
      if (caret < 0) {
        caret = 0;
      } else if (caret >= botNameFixed.length()) {
        caret = botNameFixed.length();
      } else {
        caret--;
      }
      txt.setText(botNameFixed);
      txt.setCaretPosition(caret);
    }
    this.bwheadless.setBotName(botNameFixed);
  }

}

@@ -1096,16 +1096,20 @@
 File ini
+File
 ;%0A%0A  pub
@@ -1174,16 +1174,20 @@
 this.ini
+File
  = new I
@@ -1232,24 +1232,28 @@
 ile(this.ini
+File
 );%0A    try %7B
@@ -1267,16 +1267,20 @@
 this.ini
+File
 .open(DR
@@ -1344,16 +1344,20 @@
 this.ini
+File
 );%0A    %7D

Rename "ini" to "iniFile"