/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.text.Document;
import javax.swing.event.DocumentListener;
import javax.swing.event.DocumentEvent;

import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import drafts.com.sun.star.script.framework.runtime.XScriptContext;
import bsh.Interpreter;

public class OOBeanShellDebugger implements OOScriptDebugger, ActionListener, DocumentListener {

    private JFrame frame;
    private JTextArea ta;
    private GlyphGutter gg;
    private XScriptContext context;
    private int currentPosition = -1;
    private int linecount;
    private Interpreter sessionInterpreter;
    private Thread execThread = null;
    private String filename = null;

    /* Entry point for script execution */
    public void go(XScriptContext context, String filename) {
        if (filename != null && filename != "") {
            try {
                FileInputStream fis = new FileInputStream(filename);
                this.filename = filename;
                go(context, fis);
            }
            catch (IOException ioe) {
                JOptionPane.showMessageDialog(frame,
                    "Error loading file: " + ioe.getMessage(),
                    "Error", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    /* Entry point for script execution */
    public void go(XScriptContext context, InputStream in) {
        this.context = context;
        initUI();

        if (in != null) {
            try {
                loadFile(in);
            }
            catch (IOException ioe) {
                JOptionPane.showMessageDialog(frame,
                    "Error loading stream: " + ioe.getMessage(),
                    "Error", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    public void loadFile(InputStream in) throws IOException {

        /* Remove ourselves as a DocumentListener while loading the file
           so we don't get a storm of DocumentEvents during loading */
        ta.getDocument().removeDocumentListener(this);

        byte[] contents = new byte[1024];
        int len = 0, pos = 0;

        while ((len = in.read(contents, 0, 1024)) != -1) {
            ta.insert(new String(contents, 0, len), pos);
            pos += len;
        }

        try {
            in.close();
        }
        catch (IOException ignore) {
        }

        /* Update the GlyphGutter and add back the DocumentListener */
        gg.update();
        ta.getDocument().addDocumentListener(this);
    }

    private void initUI() {
        frame = new JFrame("BeanShell Debug Window");
        ta = new JTextArea();
        ta.setRows(15);
        ta.setColumns(40);
        ta.setLineWrap(false);
        linecount = ta.getLineCount();

        gg = new GlyphGutter(this);

        final JScrollPane sp = new JScrollPane();
        sp.setViewportView(ta);
        sp.setRowHeaderView(gg);

        ta.getDocument().addDocumentListener(this);
        String[] labels = {"Run", "Clear", "Save", "Close"};
        JPanel p = new JPanel();
        p.setLayout(new FlowLayout());

        for (int i = 0; i < labels.length; i++) {
            JButton b = new JButton(labels[i]);
            b.addActionListener(this);
            p.add(b);

            if (labels[i].equals("Save") && filename == null) {
                b.setEnabled(false);
            }
        }

        frame.getContentPane().add(sp, "Center");
        frame.getContentPane().add(p, "South");
        frame.pack();
        frame.show();
    }

    /* Implementation of DocumentListener interface */
    public void insertUpdate(DocumentEvent e) {
        doChanged(e);
    }

    public void removeUpdate(DocumentEvent e) {
        doChanged(e);
    }

    public void changedUpdate(DocumentEvent e) {
        doChanged(e);
    }

    /* If the number of lines in the JTextArea has changed then update the
       GlyphGutter */
    public void doChanged(DocumentEvent e) {
        if (linecount != ta.getLineCount()) {
            gg.update();
            linecount = ta.getLineCount();
        }
    }

    private void startExecution() {
        execThread = new Thread() {
            public void run() {
                Interpreter interpreter = new Interpreter();
                interpreter.getNameSpace().clear();

                // reset position and repaint gutter so no red arrow appears
                currentPosition = -1;
                gg.repaint();

                try {
                    interpreter.set("context", context);
                    interpreter.eval(ta.getText());
                }
                catch (bsh.EvalError err) {
                    currentPosition = err.getErrorLineNumber() - 1;
                    try {
                        // scroll to line of the error
                        int line = ta.getLineStartOffset(currentPosition);
                        Rectangle rect = ta.modelToView(line);
                        ta.scrollRectToVisible(rect);
                    }
                    catch (Exception e) {
                        // couldn't scroll to line, do nothing
                    }
                    gg.repaint();

                    JOptionPane.showMessageDialog(frame, "Error at line " +
                        String.valueOf(err.getErrorLineNumber()) +
                        "\n\n: " + err.getErrorText(),
                        "Error", JOptionPane.ERROR_MESSAGE);
                }
                catch (Exception e) {
                    JOptionPane.showMessageDialog(frame,
                        "Error: " + e.getMessage(),
                        "Error", JOptionPane.ERROR_MESSAGE);
                }
            }
        };
        execThread.start();
    }

    private void promptForSaveName() {
        JFileChooser chooser = new JFileChooser();
        chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
            public boolean accept(File f) {
                if (f.isDirectory() || f.getName().endsWith(".bsh")) {
                    return true;
                }
                return false;
            }

            public String getDescription() {
                return ("BeanShell files: *.bsh");
            }
        });

        int ret = chooser.showSaveDialog(frame);

        if (ret == JFileChooser.APPROVE_OPTION) {
            filename = chooser.getSelectedFile().getAbsolutePath();
            if (!filename.endsWith(".bsh")) {
                filename += ".bsh";
            }
        }

    }

    private void saveTextArea() {
        if (filename == null) {
            promptForSaveName();
        }

        FileOutputStream fos = null;
        if (filename != null) {
            try {
                File f = new File(filename);
                fos = new FileOutputStream(f);
                String s = ta.getText();
                fos.write(s.getBytes(), 0, s.length());
            }
            catch (IOException ioe) {
                JOptionPane.showMessageDialog(frame,
                    "Error saving file: " + ioe.getMessage(),
                    "Error", JOptionPane.ERROR_MESSAGE);
            }
            finally {
                if (fos != null) {
                    try {
                        fos.close();
                    }
                    catch (IOException ignore) {
                    }
                }
            }
        }
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Run")) {
            startExecution();
        }
        else if (e.getActionCommand().equals("Close")) {
            frame.dispose();
        }
        else if (e.getActionCommand().equals("Save")) {
            saveTextArea();
        }
        else if (e.getActionCommand().equals("Clear")) {
            ta.setText("");
        }
    }

    public JTextArea getTextArea() {
        return ta;
    }

    public int getCurrentPosition() {
        return currentPosition;
    }
}

class GlyphGutter extends JComponent {

    private OOBeanShellDebugger debugger;
    private final String DUMMY_STRING = "99";

    GlyphGutter(OOBeanShellDebugger debugger) {
        this.debugger = debugger;
        update();
    }

    public void update() {
        JTextArea textArea = debugger.getTextArea();
        Font font = textArea.getFont();
        setFont(font);

        FontMetrics metrics = getFontMetrics(font);
        int h = metrics.getHeight();
        int lineCount = textArea.getLineCount() + 1;

        String dummy = Integer.toString(lineCount);
        if (dummy.length() < 2) {
            dummy = DUMMY_STRING;
        }

        Dimension d = new Dimension();
        d.width = metrics.stringWidth(dummy) + 16;
        d.height = lineCount * h + 100;
        setPreferredSize(d);
        setSize(d);
    }

    public void paintComponent(Graphics g) {
        JTextArea textArea = debugger.getTextArea();

        Font font = textArea.getFont();
        g.setFont(font);

        FontMetrics metrics = getFontMetrics(font);
        Rectangle clip = g.getClipBounds();

        g.setColor(getBackground());
        g.fillRect(clip.x, clip.y, clip.width, clip.height);

        int ascent = metrics.getMaxAscent();
        int h = metrics.getHeight();
        int lineCount = textArea.getLineCount() + 1;

        int startLine = clip.y / h;
        int endLine = (clip.y + clip.height) / h + 1;
        int width = getWidth();
        if (endLine > lineCount) {
            endLine = lineCount;
        }

        for (int i = startLine; i < endLine; i++) {
            String text;
            text = Integer.toString(i + 1) + " ";
            int w = metrics.stringWidth(text);
            int y = i * h;
            g.setColor(Color.blue);
            g.drawString(text, 0, y + ascent);
            int x = width - ascent;

            // if currentPosition is not -1 then a red arrow will be drawn
            if (i == debugger.getCurrentPosition()) {
                drawArrow(g, ascent, x, y);
            }
        }
    }

    private void drawArrow(Graphics g, int ascent, int x, int y) {
        Polygon arrow = new Polygon();
        int dx = x;
        y += ascent - 10;
        int dy = y;
        arrow.addPoint(dx, dy + 3);
        arrow.addPoint(dx + 5, dy + 3);
        for (x = dx + 5; x <= dx + 10; x++, y++) {
            arrow.addPoint(x, y);
        }
        for (x = dx + 9; x >= dx + 5; x--, y++) {
            arrow.addPoint(x, y);
        }
        arrow.addPoint(dx + 5, dy + 7);
        arrow.addPoint(dx, dy + 7);

        g.setColor(Color.red);
        g.fillPolygon(arrow);
        g.setColor(Color.black);
        g.drawPolygon(arrow);
    }
};
