content: package Singletons;
  
  import Models.GearSpecRegister.GearSpecRegister;
  import Models.Settings.GearSpecSettings;
  import Models.Settings.ProjectSettings;
  import Utilities.OSValidator;
  import Utilities.Utils;
  import com.google.gson.Gson;
  import com.google.gson.GsonBuilder;
  import com.intellij.openapi.project.Project;
  import com.intellij.openapi.project.ProjectManager;
  import org.apache.commons.io.FileUtils;
  
  import javax.swing.*;
  import java.io.File;
  import java.io.IOException;
  
  /**
   * Created by matthewyork on 4/6/14.
   */
  public class SettingsManager {
      //Singleton instance for settings
      private static SettingsManager settingsManager;
      private Project[] targetProjects;
      private static String IGNORE_STRING = Utils.newLine()+Utils.newLine()+"#Android Gears"+Utils.newLine()+"Gears/";
      private static String IGNORE_COMMENT_STRING = "#Android Gears";
      private static String IGNORE_CONTENT_STRING = "Gears/";
  
      //Project Settings
      private ProjectSettings projectSettings = new ProjectSettings();
  
      private GearSpecSettings settings = new GearSpecSettings();
  
      protected SettingsManager() {
  
      }
  
      public static SettingsManager getInstance() {
          if (settingsManager == null) {
              settingsManager =  new SettingsManager();
          }
  
          return settingsManager;
      }
  
      ///////////////////////
      // Loading / Saving
      ///////////////////////
  
      public Boolean loadSettings(){
  
          //Get settings file
          File settingsFile = new File(Utils.getDefaultDirectory().getAbsolutePath()+Utils.pathSeparator()+".gearssettings");
  
          if (settingsFile.exists()){
              //Create new Gson instance for use
              Gson gson = new Gson();
  
              String settingsString = null;
              try {
                  settingsString = FileUtils.readFileToString(settingsFile);
              } catch (IOException e) {
                  e.printStackTrace();
                  return false;
              }
  
              //Load file into settings
              this.settings = new Gson().fromJson(settingsString, GearSpecSettings.class);
  
          }
          else {
              //Save a new default copy of the settings
              saveSettings();
          }
  
          return true;
      }
  
      public Boolean saveSettings(){
  
  
          //Get settings file
          File settingsFile = new File(Utils.getDefaultDirectory().getAbsolutePath()+Utils.pathSeparator()+".gearssettings");
  
          //Create new Gson instance for use
          Gson gson = new GsonBuilder().setPrettyPrinting().create();
  
          try {
              //Delete the settings, if they exist
              if (settingsFile.exists()){
                  FileUtils.forceDelete(settingsFile);
              }
  
              //Write settings to file
              FileUtils.write(settingsFile, gson.toJson(settings));
          } catch (IOException e) {
              e.printStackTrace();
              return false;
          }
  
          return true;
      }
  
      public Boolean loadProjectSettings(Project project){
          //Get settings file
          File settingsFile = new File(project.getBasePath()+"/.gearsproject");
  
          if (settingsFile.exists()){
              //Create new Gson instance for use
              Gson gson = new Gson();
  
              String settingsString = null;
              try {
                  settingsString = FileUtils.readFileToString(settingsFile);
              } catch (IOException e) {
                  e.printStackTrace();
                  return false;
              }
  
              //Load file into settings
              this.projectSettings = new Gson().fromJson(settingsString, ProjectSettings.class);
  
          }
  
          return true;
      }
  
      public Boolean saveProjectSettings(Project project){
          //Get settings file
          File settingsFile = new File(project.getBasePath()+"/.gearsproject");
  
          //Create new Gson instance for use
          Gson gson = new GsonBuilder().setPrettyPrinting().create();
  
          try {
              //Delete the settings, if they exist
              if (settingsFile.exists()){
                  FileUtils.forceDelete(settingsFile);
              }
  
              //Write settings to file
              FileUtils.write(settingsFile, gson.toJson(projectSettings));
          } catch (IOException e) {
              e.printStackTrace();
              return false;
          }
  
          return true;
      }
  
      ///////////////////////
      // Auto Ignore
      ///////////////////////
  
      public Boolean getAutoIgnore(){
          return settings.autoIgnore;
      }
  
      public Boolean setCreateIgnore(boolean createIgnore){
  
  
          /*
          if (autoIgnore == true){
              if (addIgnoreEntry()){
                  //showAddedIgnoreDialog(panel);
              }
              else {
                  showFailedToAddIgnoreDialog(panel);
              }
          }
          else {
              if (removeIgnoreEntry()){
                  showRemovedIgnoreDialog(panel);
              }
              else {
                  showFailedToRemoveIgnoreDialog(panel);
              }
          }
  
          return true;*/
  
          //Set setting
          if (createIgnore){
              if (addIgnoreEntry()){
                  settings.autoIgnore = createIgnore;
                  saveSettings();
                  return true;
              }
          }
          else {
              if (removeIgnoreEntry()){
                  settings.autoIgnore = createIgnore;
                  saveSettings();
                  return true;
              }
          }
  
          return false;
      }
  
      public Boolean ignoreExists(){
  
          ProjectManager pm = ProjectManager.getInstance();
          targetProjects = pm.getOpenProjects();
  
          if (targetProjects.length > 0){
              Project project = targetProjects[0];
  
              //Get ignore file
              File ignoreFile = new File(project.getBasePath()+ Utils.pathSeparator()+".gitignore");
  
              if (ignoreFile.exists()){
                  try {
                      //Read back ignore file
                      String ignoreFileString = FileUtils.readFileToString(ignoreFile);
  
                      //Return true if it exists
                      return  ignoreFileString.contains(IGNORE_STRING);
                  } catch (IOException e) {
                      e.printStackTrace();
                      return false;
                  }
              }
              else {
                  if (createIgnore(ignoreFile)){
                      return true;
                  }
              }
          }
  
          return false;
      }
  
      private Boolean addIgnoreEntry(){
          ProjectManager pm = ProjectManager.getInstance();
          targetProjects = pm.getOpenProjects();
  
          if (targetProjects.length > 0){
              Project project = targetProjects[0];
  
              //Get ignore file
              File gitignore = new File(project.getBasePath()+ Utils.pathSeparator()+".gitignore");
              File hgignoreFile = new File(project.getBasePath()+ Utils.pathSeparator()+".hgignore");
              File ignoreFile =null;
  
              //Find valid ignore file
              if (gitignore.exists()){
                  ignoreFile = gitignore;
              }
              else if (hgignoreFile.exists()){
                  ignoreFile = hgignoreFile;
              }
  
              if (ignoreFile.exists()){
                  try {
                      //Read back ignore file
                      String ignoreFileString = FileUtils.readFileToString(ignoreFile);
  
                      //Check if it exists already. If it does, we're good
                      if (!ignoreFileString.contains(IGNORE_COMMENT_STRING) && !ignoreFileString.contains(IGNORE_CONTENT_STRING)){
                          //Add entry
                          ignoreFileString = ignoreFileString+IGNORE_STRING;
  
                          //Write back changes to gitignore
                          FileUtils.forceDelete(ignoreFile);
                          FileUtils.write(ignoreFile, ignoreFileString);
                      }
  
                      return true;
                  } catch (IOException e) {
                      e.printStackTrace();
                      return false;
                  }
              }
              else {
                  //If no gitignore exists, create one!
                  if (createIgnore(gitignore)){
                      return true;
                  }
              }
          }
  
          return true;
      }
  
      private Boolean removeIgnoreEntry(){
          ProjectManager pm = ProjectManager.getInstance();
          targetProjects = pm.getOpenProjects();
  
          if (targetProjects.length > 0){
              Project project = targetProjects[0];
  
              //Get ignore file
              File gitignore = new File(project.getBasePath()+ Utils.pathSeparator()+".gitignore");
              File hgignoreFile = new File(project.getBasePath()+ Utils.pathSeparator()+".hgignore");
              File ignoreFile =null;
  
              //Find valid ignore file
              if (gitignore.exists()){
                  ignoreFile = gitignore;
              }
              else if (hgignoreFile.exists()){
                  ignoreFile = hgignoreFile;
              }
  
              if (ignoreFile != null){
                  try {
                      //Read back ignore file
                      String ignoreFileString = FileUtils.readFileToString(ignoreFile);
  
                      //remove entry
                      ignoreFileString = ignoreFileString.replace(IGNORE_COMMENT_STRING, "");
                      ignoreFileString = ignoreFileString.replace(IGNORE_CONTENT_STRING, "");
  
                      //Write back changes to gitignore
                      FileUtils.forceDelete(ignoreFile);
                      FileUtils.write(ignoreFile, ignoreFileString);
                  } catch (IOException e) {
                      e.printStackTrace();
                      return false;
                  }
              }
              else {
                  if (createIgnore(ignoreFile)){
                      return true;
                  }
              }
          }
  
          return true;
      }
  
      private Boolean createIgnore(File ignoreFile){
          try {
              //Delete the settings, if they exist
              if (ignoreFile.exists()){
                  FileUtils.forceDelete(ignoreFile);
              }
  
              //Write settings to file
              FileUtils.write(ignoreFile, IGNORE_STRING);
          } catch (IOException e) {
              e.printStackTrace();
              return false;
          }
  
          return true;
      }
  
      ///////////////////////
      // Auto Sync
      ///////////////////////
  
      public Boolean getAutoSync(){
          return this.settings.autosyncGears;
      }
  
      public Boolean setAutoSync(Boolean autoSync){
          this.settings.autosyncGears = autoSync;
  
          return saveSettings();
      }
  
      ///////////////////////
      // Modules
      ///////////////////////
  
      public String getMainModule(){
          if (projectSettings != null){
              if (projectSettings.mainModule != null){
                  return projectSettings.mainModule;
              }
          }
  
          return "";
      }
  
      public void setMainModule(String mainModule, Project project){
          if (mainModule != null){
              if (projectSettings != null){
                  projectSettings.mainModule = mainModule;
              }
              saveProjectSettings(project);
          }
      }
  
      ///////////////////////
      // Spec Repository Path
      ///////////////////////
  
      public String getSpecsPath(){
          if (this.settings.specsPath == null){
              this.settings.specsPath = Utils.getDefaultDirectory().getAbsolutePath();
              saveSettings();
          }
  
          return this.settings.specsPath;
      }
  
      public void setSpecsPath(String path){
          if (path != null){
              this.settings.specsPath = path;
              saveSettings();
          }
      }
  }
  
  