/*
 * Main.java
 */

package edu.umbc.combio.erilllab.jfitom.gui;

import java.io.BufferedReader;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import org.jdesktop.application.Application;
import org.jdesktop.application.SingleFrameApplication;

/**
 * The main class of the application.
 */
public class Main extends SingleFrameApplication {

    private final static Logger LOGGER = Logger.getLogger(MainView.class.getName());
    static private FileHandler logFileHandler;
    private static LogManager lm = LogManager.getLogManager();

    private static String[] clArguments = null;
    private static String optionsFilePath = null;
    private static String genomeFilePath = null;
    private static String sitesFilePath = null;

    // We load all the options with default values. So, if any value is missing in the provided or
    // default options file it will be automatically carry the factory settings.
    private static int scoreMethod = Integer.parseInt(Options.DEFAULT_SCORE_METHOD);
    private static int listSizeMethod = Integer.parseInt(Options.DEFAULT_RESULT_SIZE_METHOD);
    private static int listSize = Integer.parseInt(Options.DEFAULT_RESULT_SIZE_METHOD_VALUE);
    private static int thresholdMethod = Integer.parseInt(Options.DEFAULT_THRESHOLD_SCORE_METHOD);
    private static double threshold = Double.parseDouble(Options.DEFAULT_THRESHOLD_SCORE_VALUE);
    private static boolean areSitesPalindromic = Options.DEFAULT_IS_PALINDROME.equals("Y") ? true : false;
    private static int maxHysteresisLimit = Integer.parseInt(Options.DEFAULT_MAX_HYSTERESIS_LIMIT);
    private static int maxIntergenicDistance = Integer.parseInt(Options.DEFAULT_MAX_INTERGENIC_DISTANCE);
    private static int maxOperatorDistanceIn = Integer.parseInt(Options.DEFAULT_MAX_OPERATOR_DISTANCE_IN);
    private static int maxOperatorDistanceOut = Integer.parseInt(Options.DEFAULT_MAX_OPERATOR_DISTANCE_OUT);
    private static String outputFilePath = Options.DEFAULT_OUTPUT_FILE;

    static BufferedReader optionsFileReader;

    MainView mainView = null;

    /**
     * At startup create and show the main frame of the application.
     */
    @Override protected void startup() {
        mainView = new MainView(this, optionsFilePath, genomeFilePath, sitesFilePath);
        Class c = MainView.class;
        String fileURL = c.getProtectionDomain().getCodeSource().getLocation().getFile();
//        System.out.println("Jarpath: " + c.getProtectionDomain().getCodeSource().getLocation().getFile());

         fileURL = fileURL.replaceAll("%20", " ");
         System.out.println(fileURL);
         if(System.getProperty("os.name").startsWith("Windows")){
            System.out.println("JFitom is running on a Windows...");
            fileURL = fileURL.replaceFirst("/", "");
            System.out.println(fileURL);
            fileURL = fileURL.replaceAll("/", "\\\\");
            System.out.println(fileURL);
         }

         mainView.setJarPath(System.getProperty("user.dir"));
//         mainView.setJarPath(fileURL);
         

//        try {
//            //        fileURL.replaceAll("/", "\\");
//                    fileURL.replaceAll("%20", " ");
//            System.out.println(URLEncoder.encode(fileURL, "utf-8"));
//        } catch (UnsupportedEncodingException ex) {
//            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
//        }

        show(mainView);
    }

    /**
     * This method is to initialize the specified window by injecting resources.
     * Windows shown in our application come fully initialized from the GUI
     * builder, so this additional configuration is not needed.
     */
    @Override protected void configureWindow(java.awt.Window root) {
    }

    /**
     * A convenient static getter for the application instance.
     * @return the instance of Main
     */
    public static Main getApplication() {
        return Application.getInstance(Main.class);
    }

    /**
     * Main method launching the application.
     */
    public static void main(String[] args) {

        /**
         * The user may specify the options file, genome file and sites file in the command line.
         * The command format is as follows,
         *
         * jfitom -o <option-file.opt> -g <genome-file-path> -s <sites-file-path>
         *
         * The user is free to put the file names in any order. If the options file
         * is not specified JFITOM tries to read the options from the default location
         * i.e. <JFITOM Home>\config\jfitom.opt. If there is no options file in
         * the default location JFITOM runs with factory settings. If any one of the
         * genome or sites file is not specified JFITOM allows the user to give
         * the input using the GUI.
         * 
         */

        if(args.length == 0){
            // No command line argument
            launch(Main.class, args);
        }

        // If the user enters any command for help or version, JFITOM generate suggestions and exits.
        if(args.length == 1){
            if("h".equals(args[0]) || "-h".equals(args[0]) || "help".equals(args[0]) || "-help".equals(args[0]) || "?".equals(args[0])){
                System.out.println("Thanks for using JFitom.\nSample command: jfitom -o <option-file.opt> -g <genome-file-path> -s <sites-file-path>.");
                System.exit(1);
            }

            if("v".equals(args[0]) || "-v".equals(args[0]) || "version".equals(args[0]) || "-version".equals(args[0])){
                System.out.println("You are running JFitom Alpha");
                System.exit(1);
            }
        }

        // If there is atleast one argument we consider it is in CLI mode
        if(args.length > 0) {
            if(args.length != 2 && args.length != 4 && args.length != 6){
                // The aruments are in wrong format.
    //            System.out.println("args.length: " + args.length);
                // Invalid command line arguments
                System.out.println("No command line arguments or arguments in wrong format.\nExample: jfitom -o <option-file.opt> -g <genome-file-path> -s <sites-file-path>\nJFitom is now running with default options file.");
                // TODO: We need to decide the behavior of JFITOM at this point.
                clArguments = null;
                System.exit(1);
            } else {
                // The command line arguments are in valid format
//              System.out.println("args.length: " + args.length);
                    for(int i = 0; i < args.length; i = i + 2){
                        if("-o".equals(args[i])){
                            optionsFilePath = args[i+1];
                        } else if("-g".equals(args[i])){
                            genomeFilePath = args[i+1];
                        } else if("-s".equals(args[i])){
                            sitesFilePath = args[i+1];
                        } else {
                            System.out.println("No command line arguments or arguments in wrong format.\nExample: jfitom -o <option-file.opt> -g <genome-file-path> -s <sites-file-path>\nJFitom is now running with default options file.");
                            System.exit(1);
                            // TODO: We need to decide the behavior of JFITOM at this point.
                        }
                }

                // If atleast the genome file path and the site file path are specified in the command
                // line argument we assume that the user wants to execute the program from command line.
                // So, no GUI will be displaced.
                if(genomeFilePath != null && sitesFilePath != null){

//                    loadOptionsFromFile(optionsFilePath);

                    JFitomWrapper commandLineWrapper = new JFitomWrapper();
                    commandLineWrapper.loadOptionsFromFile(optionsFilePath);
                    commandLineWrapper.setMainView(null);
                    commandLineWrapper.computeResult(genomeFilePath, sitesFilePath);
                    System.out.println("JFITOM is closing now...\n Good bye, Bidai.");

                    // We exit after completing the operation
                    System.exit(1);
                } else {
                    System.out.println("No command line arguments or arguments in wrong format.\nExample: jfitom -o <option-file.opt> -g <genome-file-path> -s <sites-file-path>\nJFitom is now running with default options file.");
                    System.exit(1);
                }
            }
        }
        
        
    }

//    /**
//        This method is only for the command line operations.
//     */
//    public static void loadOptionsFromFile(String optionsFile){
//        try {
//            if(optionsFile != null){
//                System.out.println("Reading options file...");
//                optionsFileReader = new BufferedReader(new FileReader(optionsFile));
//            } else {
//                // If no options file specified we look up in the default location
//                System.out.println("Reading options file from the default location...");
//                optionsFileReader = new BufferedReader(new FileReader(".\\config\\options.conf"));
//            }
//
//
//            // Reading line by line
//            String currentLine = null;
//            try {
//                log(Level.INFO, "Started reading options file.");
//                while ((currentLine = optionsFileReader.readLine()) != null) {
//                    if(!currentLine.startsWith("#")){
//                        // Now we check which property, this line corresponds to
//                        String[] optionValuePair = currentLine.split("=");
//                        String option = optionValuePair[0].trim();
//                        String value = optionValuePair[1].trim();
//
//                        if(Options.OPTION_IS_PALINDROME.equals(option)){
//                            if("Y".equals(value)){
//                                areSitesPalindromic = true;
//                            } else {
//                                areSitesPalindromic = false;
//                            }
//                        }
//
//                        if(Options.OPTION_OUTPUT_FILE.equals(option)){
//                            outputFilePath = value;
//                        }
//
//                        if(Options.OPTION_SCORE_METHOD.equals(option)){
//                            scoreMethod = Integer.parseInt(value);
//                        }
//
//                        if(Options.OPTION_MAX_HYSTERESIS_LIMIT.equals(option)){
//                            maxHysteresisLimit = Integer.parseInt(value);
//                        }
//
//                        if(Options.OPTION_MAX_INTERGENIC_DISTANCE.equals(option)){
//                            maxIntergenicDistance = Integer.parseInt(value);
//                        }
//
//                        if(Options.OPTION_MAX_OPERATOR_DISTANCE_OUT.equals(option)){
//                            maxOperatorDistanceOut = Integer.parseInt(value);
//                        }
//
//                        if(Options.OPTION_MAX_OPERATOR_DISTANCE_IN.equals(option)){
//                            maxOperatorDistanceIn = Integer.parseInt(value);
//                        }
//
//                        if(Options.OPTION_RESULT_SIZE_METHOD.equals(option)){
//                            listSizeMethod = Integer.parseInt(value);
//                        }
//
//                        if(Options.OPTION_RESULT_SIZE_METHOD_VALUE.equals(option)){
//                            listSize = Integer.parseInt(value);
//                        }
//
//                        if(Options.OPTION_THRESHOLD_SCORE_METHOD.equals(option)){
//                            thresholdMethod = Integer.parseInt(value);
//                        }
//
//                        if(Options.OPTION_THRESHOLD_SCORE_VALUE.equals(option)){
//                            threshold = Double.parseDouble(value);
//                        }
//
//                        /**
//                            We skip this because the options are already saved.
//                         */
////                        if(Options.OPTION_SAVE_OPTIONS.equals(option)){
////                            if("Y".equals(value)){
////                                saveOptionsCheckBox.setSelected(true);
////                            } else {
////                                saveOptionsCheckBox.setSelected(false);
////                            }
////                        }
//
////                        if(Options.OPTION_GENERATE_LOGS.equals(option)){
////                            if("Y".equals(value)){
////                                generateLogsCheckBox.setSelected(true);
////                            } else {
////                                generateLogsCheckBox.setSelected(false);
////                            }
////                        }
//
////                        if(Options.OPTION_VIEW_RESULT.equals(option)){
////                            if("Y".equals(value)){
////                                viewResultsCheckBox.setSelected(true);
////                            } else {
////                                viewResultsCheckBox.setSelected(false);
////                            }
////                        }
//
////                        setStatusBarText("Options are set according to the options file.");
//
//                        System.out.println("Reading options file complete.");
//                    } // If not a commented line
//
//                }// while
//            } catch (IOException ex) {
//                log(Level.SEVERE, "I/O exception in reading options file.");
//                System.out.println("I/O Exception during reading the options file.\nTerminating...");
//                System.exit(1);
////                setStatusBarText("I/O exception in reading options file.");
//                // If we cannot read the optionsFile, we use the default values
////                initializeUIControlsWithDefaultValues();
////                Logger.getLogger(MainView.class.getName()).log(Level.SEVERE, null, ex);
//            }
//
//        } catch (FileNotFoundException ex) {
//            log(Level.SEVERE, "No options file found.");
//            System.out.println("Options file not found.\nTerminating...");
//            System.exit(1);
////            setStatusBarText("No options file found.");
//            // If we do not find the optionsFile, we use the default values
////            initializeUIControlsWithDefaultValues();
////            Logger.getLogger(MainView.class.getName()).log(Level.SEVERE, null, ex);
//        }
//    }

    private static void log(Level level, String logMessage){
            LOGGER.log(level, logMessage);
    }
}
