package usda.weru.weps.serverControl;

import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import javax.help.CSH;
import javax.swing.JTextField;
import usda.weru.util.WepsMessage;
import usda.weru.util.WepsMessageLog;
import usda.weru.weps.RunProgram;

/**
 *
 * @author mhaas
 */
public abstract class RunProgramBase implements Runnable {

    protected boolean stopFlag = false;
    protected RunDialog runDialog = null;
    
    
    public boolean getStopFlag () {
        return(stopFlag);
    }

   @Override
    public void run() {
        
    }


    /**
     * Thread to receive weps.exe stdout or stderr.
     * Directs all output into a file.
     * Parses stdout and updates RunDialog
     * @author wjr
     */
    public static class PipeIn extends Thread {

        private final WepsMessageLog c_log;
        InputStream from;
        PrintWriter to;
        RunDialog rd;

        public PipeIn(InputStream from, PrintWriter to, RunDialog rd, int idx) {
            this.from = from;
            this.to = to;
            this.rd = rd;

            c_log = new WepsMessageLog();
        }

        public WepsMessageLog getLog() {
            return c_log;
        }

        @Override
        public void run() {

            String inpstr, trimstr, message = null;
            BufferedReader bid = new BufferedReader(new InputStreamReader(from), 10);

            try {
                while ((inpstr = bid.readLine()) != null) {
                    to.println(inpstr);
                    trimstr = inpstr.trim();

                    //Special run time catches
                    //if (rp != null) {
                    if (rd != null) {
                        //trim the input string so that the leading white spaces are removed-neha
                        if (trimstr.startsWith("Year")) {
                            rd.JTF_status.setText(inpstr);
                            StringTokenizer st = new StringTokenizer(inpstr);
                            st.nextToken();
                            rd.JPB_weps.setValue(Integer.parseInt(st.nextToken()));
                        }
                    }
                    //Catch Errors and warnings
                    if (trimstr.startsWith("Requested Station Not Found.")) {
                        //Cligen was not happy, unable to find desired station.
                        c_log.logMessage(WepsMessage.errorMessage(
                                "Selected cligen station does not exist in the cligen database being used."));
                    } else if (trimstr.startsWith("Error")) {
                        message = trimstr.replaceFirst("Error:", "");
                        message = message.replaceFirst("Error :", "");
                        c_log.logMessage(WepsMessage.errorMessage(message.trim()));
                    } else if (trimstr.startsWith("Warning")) {
                        message = trimstr.replaceFirst("Warning:", "");
                        message = message.replaceFirst("Warning :", "");
                        c_log.logMessage(WepsMessage.warningMessage(message.trim()));
                    }

                }
                to.flush();
            } catch (IOException e) {
                //System.err.println("PipeIn: " + e);
            }
        }
    }
        
    /**
     * Wrapper for window that tracks exe progress. Replaces RunWindow class
     * @author wjr
     */
    public class RunDialog extends usda.weru.weps.gui.RunDialog_n {

        private static final long serialVersionUID = 1L;

        RunProgram runProgram;
        boolean runFlag = true;
        JTextField[] JTF_arr = {JTF_win, JTF_cli, JTF_weps};

        public RunDialog(Component parent, String title, RunProgram runProgram) {
            super();
            addHelp();
            this.runProgram = runProgram;
            setTitle("WEPS Run: " + title);
            setLocation(100, 100);

            setVisible(true);
            setResizable(true);
            JL_runName.setText(title);
            JL_runName.setToolTipText(title);

            pack();

            addWindowListener(new WindowAdapter() {

                @Override
                public void windowClosed(WindowEvent e) {
                    stopFlag = true;
                }
            });

        }
        
        public void setRunFlag (boolean val) {
            runFlag = val;
        }
        
        public JTextField getJTF (int idx) {
            return (JTF_arr[idx]);
        }

        /**
         * help stuff
         */
        private void addHelp() {
            CSH.setHelpIDString(JLabel4, "runWindGen_html");
            CSH.setHelpIDString(JTF_win, "runWindGen_html");

            CSH.setHelpIDString(JLabel2, "runCliGen_html");
            CSH.setHelpIDString(JTF_cli, "runCliGen_html");

            CSH.setHelpIDString(JLabel3, "runWepsModel_html");
            CSH.setHelpIDString(JTF_weps, "runWepsModel_html");

            CSH.setHelpIDString(JTF_status, "runStatusBar_html");
            CSH.setHelpIDString(JPB_weps, "runProgressBar_html");
            CSH.setHelpIDString(JB_can, "runCancelButton_html");

            CSH.setHelpIDString(this, "runDialog_html");
        }

        /**
         * Sets max number of years for JProgressBar
         *
         * @param tot
         */
        public void setTotalYears(String totstr) {
            try {
                JPB_weps.setMaximum(Integer.parseInt(totstr));
            } catch (java.lang.NumberFormatException e) {
                //System.err.println("RP: can't parse total years string " + e);
            }
        }

        /**
         * Sets current year from weps.exe
         *
         * @param cur year number
         */
        public void setCurrentYear(int cur) {
            JPB_weps.setValue(cur);
        }

        /**
         * Kills current weps.exe run
         *
         * @param event
         */
        @Override
        public void JBCan_actionPerformed(java.awt.event.ActionEvent event) {
            stopFlag = true;
            this.dispose();
        }
    }


    //
    // MEH
    // This is copied from the PipeIn class (above), from its run method.
    // This class creates the stdout and stderr files when the external science models are executed.
    // It filters the output and simultaneously copies Error and Warning messages to the log.
    // These messages are filtered from the log file after execution and written to the warnings.txt file.
    //
    // When the external modules are executed remotely on a server, this filtering does not take place, we only
    // get returned the entire stdout and stderr files.  This copied method is then used to extract these messages
    // from the files after the run so that the rest of the program execution can continue seamlessly
    // and the remote execution will remain transparent to the rest of the Weps GUI code.
    //
    
    public WepsMessageLog scanExecOutFiles (InputStream from) {
        String inpstr, trimstr, message = null;
        BufferedReader bid = new BufferedReader(new InputStreamReader(from), 10);
        WepsMessageLog c_log;
        c_log = new WepsMessageLog();

        try {
            while ((inpstr = bid.readLine()) != null) {

                trimstr = inpstr.trim();
                //Catch Errors and warnings
                if (trimstr.startsWith("Requested Station Not Found.")) {
                    //Cligen was not happy, unable to find desired station.
                    c_log.logMessage(WepsMessage.errorMessage(
                            "Selected cligen station does not exist in the cligen database being used."));
                } else if (trimstr.startsWith("Error")) {
                    message = trimstr.replaceFirst("Error:", "");
                    message = message.replaceFirst("Error :", "");
                    c_log.logMessage(WepsMessage.errorMessage(message.trim()));
                } else if (trimstr.startsWith("Warning")) {
                    message = trimstr.replaceFirst("Warning:", "");
                    message = message.replaceFirst("Warning :", "");
                    c_log.logMessage(WepsMessage.warningMessage(message.trim()));
                }

            }
            bid.close();
        } catch (IOException e) {
            //System.err.println("PipeIn: " + e);
        }
        return (c_log);
    }
}

        
        

