content: package common;
  
  import java.awt.Desktop;
  import java.io.File;
  import java.io.IOException;
  import java.net.URI;
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * 
   * FOX 1 Telemetry Decoder
   * @author chris.e.thompson g0kla/ac2cz
   *
   * Copyright (C) 2015 amsat.org
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   *
   * 
   * Based on a stackoverflow answer by MightyPork: http://stackoverflow.com/users/2180189/mightypork
   * 
   */
  public class DesktopApi {
  
      public static boolean browse(URI uri) {
          if (browseDESKTOP(uri)) return true;
  
          if (openSystemSpecific(uri.toString())) return true;
  
  
          return false;
      }
  
  
      public static boolean open(File file) {
  
          if (openSystemSpecific(file.getPath())) return true;
  
          if (openDESKTOP(file)) return true;
  
          return false;
      }
  
  
      public static boolean edit(File file) {
  
          // you can try something like
          // runCommand("gimp", "%s", file.getPath())
          // based on user preferences.
  
          if (openSystemSpecific(file.getPath())) return true;
  
          if (editDESKTOP(file)) return true;
  
          return false;
      }
  
  
      private static boolean openSystemSpecific(String what) {
  
          EnumOS os = getOs();
  
          if (os.isLinux()) {
              if (runCommand("kde-open", "%s", what)) return true;
              if (runCommand("gnome-open", "%s", what)) return true;
              if (runCommand("xdg-open", "%s", what)) return true;
          }
  
          if (os.isMac()) {
              if (runCommand("open", "%s", what)) return true;
          }
  
          if (os.isWindows()) {
              if (runCommand("explorer", "%s", what)) return true;
          }
  
          return false;
      }
  
  
      private static boolean browseDESKTOP(URI uri) {
  
          logOut("Trying to use Desktop.getDesktop().browse() with " + uri.toString());
          try {
              if (!Desktop.isDesktopSupported()) {
                  logErr("Platform is not supported.");
                  return false;
              }
  
              if (!Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
                  logErr("BROWSE is not supported.");
                  return false;
              }
  
              Desktop.getDesktop().browse(uri);
  
              return true;
          } catch (IOException e) {
          	// not an error, could not find program to execute
          	return false;
          } catch (Throwable t) {
              Log.errorDialog("Error using desktop browse.", t.getMessage() + "\nTrying: " + uri.toString());
              return false;
          }
      }
  
  
      private static boolean openDESKTOP(File file) {
  
          logOut("Trying to use Desktop.getDesktop().open() with " + file.toString());
          try {
              if (!Desktop.isDesktopSupported()) {
                  logErr("Platform is not supported.");
                  return false;
              }
  
              if (!Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
                  logErr("OPEN is not supported.");
                  return false;
              }
  
              Desktop.getDesktop().open(file);
  
              return true;
          } catch (Throwable t) {
              logErr("Error using desktop open.", t);
              return false;
          }
      }
  
  
      private static boolean editDESKTOP(File file) {
  
          logOut("Trying to use Desktop.getDesktop().edit() with " + file);
          try {
              if (!Desktop.isDesktopSupported()) {
                  logErr("Platform is not supported.");
                  return false;
              }
  
              if (!Desktop.getDesktop().isSupported(Desktop.Action.EDIT)) {
                  logErr("EDIT is not supported.");
                  return false;
              }
  
              Desktop.getDesktop().edit(file);
  
              return true;
          } catch (Throwable t) {
              logErr("Error using desktop edit.", t);
              return false;
          }
      }
  
  
      private static boolean runCommand(String command, String args, String file) {
  
          logOut("Trying to exec:\n   cmd = " + command + "\n   args = " + args + "\n   %s = " + file);
  
          String[] parts = prepareCommand(command, args, file);
  
          try {
              Process p = Runtime.getRuntime().exec(parts);
              if (p == null) return false;
  
              try {
                  int retval = p.exitValue();
                  if (retval == 0) {
                      logErr("Process ended immediately.");
                      return false;
                  } else {
                      logErr("Process crashed.");
                      return false;
                  }
              } catch (IllegalThreadStateException itse) {
                  Log.println("Process is running."); // we seem to get this when it works, so not an error?
                  return true;
              }
          } catch (IOException e) {
          	// This is not really an error.  We could not find the file and this was not a valid method to try
              //logErr("Error running command.", e);
              return false;
          }
      }
  
  
      private static String[] prepareCommand(String command, String args, String file) {
  
          List<String> parts = new ArrayList<String>();
          parts.add(command);
  
          if (args != null) {
              for (String s : args.split(" ")) {
                  s = String.format(s, file); // put in the filename thing
  
                  parts.add(s.trim());
              }
          }
  
          return parts.toArray(new String[parts.size()]);
      }
  
      private static void logErr(String msg, Throwable t) {
          System.err.println(msg);
          t.printStackTrace();
      }
  
      private static void logErr(String msg) {
          Log.errorDialog("ERROR", msg);
      }
  
      private static void logOut(String msg) {
          Log.println(msg);
      }
  
      public static enum EnumOS {
          linux, macos, solaris, unknown, windows;
  
          public boolean isLinux() {
  
              return this == linux || this == solaris;
          }
  
  
          public boolean isMac() {
  
              return this == macos;
          }
  
  
          public boolean isWindows() {
  
              return this == windows;
          }
      }
  
  
      public static EnumOS getOs() {
  
          String s = System.getProperty("os.name").toLowerCase();
  
          if (s.contains("win")) {
              return EnumOS.windows;
          }
  
          if (s.contains("mac")) {
              return EnumOS.macos;
          }
  
          if (s.contains("solaris")) {
              return EnumOS.solaris;
          }
  
          if (s.contains("sunos")) {
              return EnumOS.solaris;
          }
  
          if (s.contains("linux")) {
              return EnumOS.linux;
          }
  
          if (s.contains("unix")) {
              return EnumOS.linux;
          } else {
              return EnumOS.unknown;
          }
      }
  }