/*
 * (c) Copyright: Artenum SARL, 101-103 Boulevard Mac Donald, 
 *                75019, Paris, France 2005.
 *                http://www.artenum.com
 *
 * License:
 *
 *  This program is free software; you can redistribute it 
 *  and/or modify it under the terms of the Q Public License; 
 *  either version 1 of the License.
 * 
 *  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 Q Public License for more details.
 * 
 *  You should have received a copy of the Q Public License 
 *  License along with this program;
 *  if not, write to:
 *    Artenum SARL, 101-103 Boulevard Mac Donald,
 *    75019, PARIS, FRANCE, e-mail: contact@artenum.com
 */

package com.artenum.jyconsole;

import com.artenum.jyconsole.action.DefaultKeyBinding;
import com.artenum.jyconsole.ui.PopupMenu;
import com.artenum.jyconsole.util.PropertyLoader;

import org.python.util.InteractiveInterpreter;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Rectangle;

import java.io.File;
import java.io.IOException;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;

/**
 * <pre>
 * <b>Project ref           :</b> JyConsole project
 * <b>Copyright and license :</b> See relevant sections
 * <b>Status                :</b> under development
 * <b>Creation              :</b> 04/03/2005
 * <b>Modification          :</b>
 *
 * <b>Description  :</b> Main application that take care of the components initialisation.
 *
 * </pre>
 * <table cellpadding="3" cellspacing="0" border="1" width="100%">
 * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor"><td><b>Version number</b></td><td><b>Author (name, e-mail)</b></td><td><b>Corrections/Modifications</b></td></tr>
 * <tr><td>0.1</td><td>Sebastien Jourdain, jourdain@artenum.com</td><td>Creation</td></tr>
 * </table>
 *
 * @author        Sebastien Jourdain
 * @version       0.1
 */
public class JyConsole extends JPanel {
    public final static String STYLE_DEFAULT = "style.default";
    public final static String STYLE_ERROR = "style.error";

    //
    private TextComponent archive;
    private JScrollPane scroll;
    private TextComponent command;
    private JPanel prompt;
    private JLabel promptLabel;
    private InteractiveInterpreter interpreter;
    private LogWriter out;
    private LogWriter err;
    private HistoryManager historyManager;
    private ScrollingView panel;
    private int i = 10;
    private PopupMenu popupMenu;
    private CommandLine cmd;
    private File currentScriptDir;
    private PreferenceManager prefManager;

    public JyConsole() {
        super(new BorderLayout());
        cmd = new CommandLine();
        prefManager = new PreferenceManager();

        // Default style
        Style defaultStyle = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);

        archive = new TextComponent();
        archive.setEditable(false);
        archive.setFocusable(true);
        Style regular = archive.getStyledDocument().addStyle(STYLE_DEFAULT, defaultStyle);
        Style error = archive.getStyledDocument().addStyle(STYLE_ERROR, regular);
        StyleConstants.setItalic(error, true);
        StyleConstants.setForeground(error, Color.RED);

        command = new TextComponent();
        command.setFocusable(true);
        regular = command.getStyledDocument().addStyle(STYLE_DEFAULT, defaultStyle);
        error = command.getStyledDocument().addStyle(STYLE_ERROR, regular);
        StyleConstants.setItalic(error, true);
        StyleConstants.setForeground(error, Color.RED);

        prompt = new JPanel();
        prompt.setBackground(Color.WHITE);
        prompt.setLayout(new BoxLayout(prompt, BoxLayout.Y_AXIS));
        promptLabel = new JLabel(">>> ");
        prompt.add(promptLabel);
        prompt.add(Box.createVerticalGlue());
        prompt.setBackground(Color.WHITE);
        prompt.setFocusable(false);

        JPanel promptLine = new JPanel();
        promptLine.setLayout(new BoxLayout(promptLine, BoxLayout.LINE_AXIS));
        promptLine.add(prompt);
        promptLine.add(command);
        promptLine.setFocusable(false);

        panel = new ScrollingView(new BorderLayout());
        panel.add(archive, BorderLayout.NORTH);
        panel.add(promptLine, BorderLayout.CENTER);

        panel.setFocusable(false);
        panel.setOpaque(true);

        scroll = new JScrollPane(panel);
        add(scroll, BorderLayout.CENTER);

        //
        //panel.add(new FillComponent(scroll.getViewport(), new Component[] { archive, promptLine }), BorderLayout.SOUTH);
        out = new LogWriter(archive, JyConsole.STYLE_DEFAULT);
        err = new LogWriter(archive, JyConsole.STYLE_ERROR);
        interpreter = new InteractiveInterpreter();
        interpreter.setOut(out);
        interpreter.setErr(err);
        historyManager = new HistoryManager(this);
        //
        //command.addFocusListener(completion);
        popupMenu = new PopupMenu(this);
        addMouseListener(popupMenu);
        prompt.addMouseListener(popupMenu);
        archive.addMouseListener(popupMenu);
        command.addMouseListener(popupMenu);
        scroll.addMouseListener(popupMenu);

        try {
            // Print info
            out.write("Welcome on JyConsole by Artenum (www.artenum.com) !");
        } catch (IOException e) {}

        // register pref
        prefManager.addBgColorComponent(archive);
        prefManager.addBgColorComponent(command);
        prefManager.addBgColorComponent(prompt);
        prefManager.addBgColorComponent(scroll);
        prefManager.addTxtDocument(archive.getStyledDocument());
        prefManager.addTxtDocument(command.getStyledDocument());
        prefManager.setPrompt(promptLabel);

        // Set system preferences
        if (System.getProperty("jyconsole.script.dir") != null) {
            setScriptDirectory(new File(System.getProperty("jyconsole.script.dir")));
        }
    }

    public void updateScrollPosition() {
        scroll.getViewport().scrollRectToVisible(new Rectangle(0, panel.getHeight() + scroll.getHeight() + 100, 50, 50));
    }

    public static void main(String[] args) {
        try {
            PropertyLoader.loadProperties("./config.properties");
        } catch (Exception e) {
            e.printStackTrace();
        }

        JyConsole console = new JyConsole();
        DefaultKeyBinding.applyDefaultMapping(console);
        JFrame f = new JFrame("JyConsole");
        f.getContentPane().add(console, BorderLayout.CENTER);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(600, 400);
        f.setVisible(true);
    }

    public InteractiveInterpreter getInterpreter() {
        return interpreter;
    }

    public TextPrinter getInputComponent() {
        return command;
    }

    public TextPrinter getOutputComponent() {
        return archive;
    }

    public HistoryManager getHistoryManager() {
        return historyManager;
    }

    public void setFocusForInput() {
        command.requestFocus();
        command.setCaretPosition(command.getText().length());
    }

    public void setSimulationFlag(boolean simulation) {
        err.setSimulationFlag(simulation);
    }

    public int getPromptWidth() {
        return prompt.getWidth();
    }

    public CommandLine getCommandLine() {
        cmd.updateData(command.getCaretPosition(), command.getText());
        return cmd;
    }

    public void updateCommandLine(String cmdLine) {
        command.setText(cmdLine);
    }

    public File getScriptDirectory() {
        return currentScriptDir;
    }

    public void setScriptDirectory(File currentScriptDir) {
        this.currentScriptDir = currentScriptDir;
    }

    public PreferenceManager getPreferenceManager() {
        return prefManager;
    }
}
