/**************************************************************
 * 
 * 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);
    }
};

