/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on ----
!  AUTHOR(S): KOGA, Junichiro
!  File : ProcessFrame.java
!  
!  Contact address :  Phase System Consortium
!                     E-mail: phase_system@nims.go.jp URL https://azuma.nims.go.jp
!
!
!   Since 2002, this program set had been intensively developed as a part of the following 
!  national projects supported by the Ministry of Education, Culture, Sports, Science and
!  Technology (MEXT) of Japan; "Frontier Simulation Software for Industrial Science
!  (FSIS)" from 2002 to 2005, "Revolutionary Simulation Software (RSS21)" from 2006 to
!  2008. "Research and Development of Innovative Simulation Software (RISS)" from 2008
!  to 2013. These projects is lead by the Center for Research on Innovative Simulation 
!  Software (CISS), the Institute of Industrial Science (IIS), the University of Tokyo.
!   Since 2013, this program set has been further developed centering on PHASE System
!  Consortium. 
!   The activity of development of this program set has been supervised by Takahisa Ohno.
!
!=======================================================================
 */
package ciss.phase_viewer.process;

import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

import ciss.phase_viewer.common.ExternalProgramExecuter;
import ciss.phase_viewer.mainpanel.ChaseGUI;
import ciss.phase_viewer.mainpanel.InternalFrameChase;

public class ProcessFrame extends InternalFrameChase {
    private final int TA_MAX_SIZE = 20000;

    private ChaseGUI parent;

    private Container cont;
    // JLabel labelcom;
    private JTextField tfcom;
    private JTextArea ta;
    private JScrollPane scrta;
    private JButton btnexe;
    private JButton btnclose;
    private String comstr;
    private String outstr;
    private StringBuffer outbuf = new StringBuffer(21000);

    /**
     * 簡易シェル用GUIを作成する. この「簡易シェル」は, テキストフィールドに打ち込まれた文字列をOSのシェルに 渡し,
     * 標準出力を表示するだけのシンプルなもの. より高級なシェル操作を行うようにするためには大きな変更を 施す必要がある.
     */
    public ProcessFrame(ChaseGUI frame) {
        // super(frame, "Process", true);
        super("shell", true, true, true);
        setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

        parent = frame;

        cont = getContentPane();
        // cont.setLayout(new FlowLayout(FlowLayout.CENTER));
        cont.setLayout(new BoxLayout(cont, BoxLayout.Y_AXIS));

        // add textfield for input command
        tfcom = new JTextField(20);
        tfcom.setBorder(new TitledBorder("Command"));
        tfcom.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == e.VK_ENTER) {
                    exeaction();
                }
            }
        });
        cont.add(tfcom);

        // add text area for showing output
        ta = new JTextArea(25, 30);
        // ta = new AexxJTextArea(10000,false);
        // String debstr = "";
        // for( int i = 0; i < 20000; i++ ){
        // debstr += "a";
        // if( i % 100 == 99 ){
        // debstr += "\n";
        // }
        // }
        // ta.append(debstr);
        ta.setEditable(false);
        scrta = new JScrollPane(ta);
        scrta.setBorder(new TitledBorder("Output"));
        cont.add(scrta);

        // ok and cancel button
        JPanel panelok = new JPanel(new GridLayout(1, 2));
        btnexe = new JButton("Execute");
        btnclose = new JButton("Close");

        // execute pressed
        btnexe.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                exeaction();
            }
        });
        btnexe.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == e.VK_ENTER) {
                    exeaction();
                }
            }
        });
        panelok.add(btnexe);

        // close pressed
        btnclose.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                dispose();
            }
        });
        panelok.add(btnclose);
        cont.add(panelok);

        setBackground(Color.gray.brighter());
        setResizable(true);
        setLocation(200, 300);
        setSize(400, 500);
        setVisible(false);
    }

    /**
     * この画面を可視化する.
     */
    public void displayProc() {
        comstr = "";
        outstr = "";
        tfcom.setText(comstr);
        ta.setText(outstr);
        setVisible(true);
    }

    // exe. action
    private void exeaction() {
        Process p;
        comstr = tfcom.getText();
        try {
            System.out.println("executing: " + comstr);
            BufferedReader[] bin = ExternalProgramExecuter.executeGetBR(comstr);
            outstr = getStdout(bin[0]);
            // outstr += getStdout(bin[1]);
            showoutput();
        } catch (Exception exception) {
            errorout("Failed to execute command: " + comstr);
            exception.printStackTrace();
        }
        tfcom.setText("");
    }

    private String getStdout(BufferedReader br) {
        String string = new String();
        String outString = new String();

        try {
            while ((string = br.readLine()) != null) {
                outString = outString + string
                        + System.getProperty("line.separator");
            }
        } catch (Exception exception) {
            System.out.println("failed to create string from stdout");
            exception.printStackTrace();
            return "";
        }

        return outString;
    }

    // display output
    private void showoutput() {
        ta.setEditable(true);
        if (outstr.length() == 0) {
            outstr = "No output.";
            ta.setForeground(Color.green.darker().darker());
        } else {
            outstr += "\n\t-End of the Result-\n";
        }

        Integer ii = new Integer(outstr.length());
        // System.out.println("outstr length="+ii.toString());

        ta.setText(outstr);
        Font font = new Font("Serif", Font.PLAIN, 15);
        ta.setFont(font);
        ta.setEditable(false);
        ta.setForeground(Color.black);
    }

    // error output
    private void errorout(String str) {
        ta.setEditable(true);
        // ta.setForeground(fcolor);
        ta.setText(str);
        Font font = new Font("Serif", Font.PLAIN, 15);
        ta.setFont(font);
        ta.setEditable(false);
    }

}
