/**
 * This is part of the Java Prettify.
 * 
 * It is distributed under MIT license. See the file 'readme.txt' for
 * information on usage and redistribution of this file, and for a
 * DISCLAIMER OF ALL WARRANTIES.
 * 
 * @author Chan Wai Shing <cws1989@gmail.com>
 */
package prettify;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTextPane;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.BoxView;
import javax.swing.text.ComponentView;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Element;
import javax.swing.text.Highlighter;
import javax.swing.text.IconView;
import javax.swing.text.JTextComponent;
import javax.swing.text.LabelView;
import javax.swing.text.ParagraphView;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;

/**
 * The text pane for displaying the script text.
 * @author Chan Wai Shing <cws1989@gmail.com>
 */
public class SyntaxHighlighterPane extends JTextPane {

    /**
     * Indicate whether it is in debug mode or not.
     */
    protected final static boolean debug;

    static {
        String debugMode = System.getProperty("PrettifyDebugMode");
        debug = debugMode == null || !debugMode.equals("true") ? false : true;
    }
    private static final long serialVersionUID = 1L;
    /**
     * The line number offset. E.g. set offset to 9 will make the first line number to appear at line 1 + 9 = 10
     */
    private int lineNumberOffset;
    /**
     * The background color of the highlighted line. Default is black.
     */
    private Color highlightedBackground;
    /**
     * Indicator that indicate to turn on the mouse-over highlight effect or not. See {@link #setHighlightOnMouseOver(boolean)}.
     */
    private boolean highlightWhenMouseOver;
    /**
     * The list of line numbers that indicate which lines are needed to be highlighted.
     */
    protected final List<Integer> highlightedLineList;
    /**
     * The highlighter painter used to do the highlight line effect.
     */
    protected Highlighter.HighlightPainter highlightPainter;
    /**
     * The theme.
     */
    protected Theme theme;
    /**
     * The style list. see {@link #setStyle(java.util.List)}.
     */
    protected List<Object> styleList;
    /**
     * Record the mouse cursor is currently pointing at which line of the document. -1 means not any line.
     * It is used internally.
     */
    protected int mouseOnLine;

    public SyntaxHighlighterPane() {
        super();

        setEditable(false);
        //<editor-fold defaultstate="collapsed" desc="editor kit">
        setEditorKit(new StyledEditorKit() {

            private static final long serialVersionUID = 1L;

            @Override
            public ViewFactory getViewFactory() {
                return new ViewFactory() {

                    @Override
                    public View create(Element elem) {
                        String kind = elem.getName();
                        if (kind != null) {
                            if (kind.equals(AbstractDocument.ContentElementName)) {
                                return new LabelView(elem) {

                                    @Override
                                    public int getBreakWeight(int axis, float pos, float len) {
                                        return 0;
                                    }
                                };
                            } else if (kind.equals(AbstractDocument.ParagraphElementName)) {
                                return new ParagraphView(elem) {

                                    @Override
                                    public int getBreakWeight(int axis, float pos, float len) {
                                        return 0;
                                    }
                                };
                            } else if (kind.equals(AbstractDocument.SectionElementName)) {
                                return new BoxView(elem, View.Y_AXIS);
                            } else if (kind.equals(StyleConstants.ComponentElementName)) {
                                return new ComponentView(elem) {

                                    @Override
                                    public int getBreakWeight(int axis, float pos, float len) {
                                        return 0;
                                    }
                                };
                            } else if (kind.equals(StyleConstants.IconElementName)) {
                                return new IconView(elem);
                            }
                        }
                        return new LabelView(elem) {

                            @Override
                            public int getBreakWeight(int axis, float pos, float len) {
                                return 0;
                            }
                        };
                    }
                };
            }
        });
        //</editor-fold>

        lineNumberOffset = 0;

        //<editor-fold defaultstate="collapsed" desc="highlighter painter">
        highlightedBackground = Color.black;
        highlightWhenMouseOver = true;
        highlightedLineList = new ArrayList<Integer>();

        highlightPainter = new Highlighter.HighlightPainter() {

            @Override
            public void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c) {
                if (c.getParent() == null) {
                    return;
                }

                // get the Y-axis value of the visible area of the text component
                int startY = Math.abs(c.getY());
                int endY = startY + c.getParent().getHeight();

                FontMetrics textPaneFontMetrics = g.getFontMetrics(getFont());
                int textPaneFontHeight = textPaneFontMetrics.getHeight();

                int largerestLineNumber = c.getDocument().getDefaultRootElement().getElementCount();

                g.setColor(highlightedBackground);

                // draw the highlight background to the highlighted line
                synchronized (highlightedLineList) {
                    for (Integer lineNumber : highlightedLineList) {
                        if (lineNumber > largerestLineNumber + lineNumberOffset) {
                            // skip those line number that out of range
                            continue;
                        }
                        // get the Y-axis value of this highlighted line
                        int _y = Math.max(0, textPaneFontHeight * (lineNumber - lineNumberOffset - 1));
                        if (_y > endY || _y + textPaneFontHeight < startY) {
                            // this line is out of visible area, skip it
                            continue;
                        }
                        // draw the highlighted background
                        g.fillRect(0, _y, c.getWidth(), textPaneFontHeight);
                    }
                }

                // draw the mouse-over-highlight effect
                if (mouseOnLine != -1) {
                    if (mouseOnLine <= largerestLineNumber + lineNumberOffset) {
                        int _y = Math.max(0, textPaneFontHeight * (mouseOnLine - lineNumberOffset - 1));
                        if (_y < endY && _y + textPaneFontHeight > startY) {
                            // the line is within the range of visible area
                            g.fillRect(0, _y, c.getWidth(), textPaneFontHeight);
                        }
                    }
                }
            }
        };
        try {
            getHighlighter().addHighlight(0, 0, highlightPainter);
        } catch (BadLocationException ex) {
            if (debug) {
                Logger.getLogger(SyntaxHighlighterPane.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        //</editor-fold>

        mouseOnLine = -1;

        //<editor-fold defaultstate="collapsed" desc="mouse listener">
        addMouseListener(new MouseAdapter() {

            @Override
            public void mouseExited(MouseEvent e) {
                if (!highlightWhenMouseOver) {
                    return;
                }
                mouseOnLine = -1;
                repaint();
            }
        });
        addMouseMotionListener(new MouseMotionListener() {

            @Override
            public void mouseDragged(MouseEvent e) {
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                if (!highlightWhenMouseOver) {
                    return;
                }

                Element defaultRootElement = getDocument().getDefaultRootElement();
                // get the position of the document the mouse cursor is pointing
                int documentOffsetStart = viewToModel(e.getPoint());

                // the line number that the mouse cursor is currently pointing
                int lineNumber = documentOffsetStart == -1 ? -1 : defaultRootElement.getElementIndex(documentOffsetStart) + 1 + lineNumberOffset;
                if (lineNumber == defaultRootElement.getElementCount()) {
                    // if the line number got is the last line, check if the cursor is actually on the line or already below the line
                    try {
                        Rectangle rectangle = modelToView(documentOffsetStart);
                        if (e.getY() > rectangle.y + rectangle.height) {
                            lineNumber = -1;
                        }
                    } catch (BadLocationException ex) {
                        if (debug) {
                            Logger.getLogger(SyntaxHighlighterPane.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }

                // only repaint when the line number changed
                if (mouseOnLine != lineNumber) {
                    mouseOnLine = lineNumber;
                    repaint();
                }
            }
        });
        //</editor-fold>
    }

    @Override
    public void setHighlighter(Highlighter highlighter) {
        if (highlightPainter != null) {
            getHighlighter().removeHighlight(highlightPainter);
            try {
                highlighter.addHighlight(0, 0, highlightPainter);
            } catch (BadLocationException ex) {
                if (debug) {
                    Logger.getLogger(SyntaxHighlighterPane.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        super.setHighlighter(highlighter);
    }

    /**
     * Set the content of the syntax highlighter. It is better to set other settings first and set this the last.
     * @param content the content to set
     */
    public void setContent(String content) {
        String newContent = content == null ? "" : content;
        DefaultStyledDocument document = (DefaultStyledDocument) getDocument();

        try {
            document.remove(0, document.getLength());
            if (theme != null) {
                document.insertString(0, newContent, theme.getPlain().getAttributeSet());
            } else {
                document.insertString(0, newContent, new SimpleAttributeSet());
            }
        } catch (BadLocationException ex) {
            if (debug) {
                Logger.getLogger(SyntaxHighlighterPane.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        setCaretPosition(0);

        // clear the style list
        styleList = null;
    }

    /**
     * Apply the list of style to the script text pane.
     * @param styleList the style list
     */
    public void setStyle(List<Object> styleList) {
        if (styleList == null) {
            this.styleList = new ArrayList<Object>();
            return;
        }
        this.styleList = new ArrayList<Object>(styleList);

        if (theme == null) {
            return;
        }

        DefaultStyledDocument document = (DefaultStyledDocument) getDocument();
        // clear all the existing style
        document.setCharacterAttributes(0, document.getLength(), theme.getPlain().getAttributeSet(), true);

        Integer startPos = 0, endPos = 0;
        // apply style according to the style list
        for (int i = 0, iEnd = styleList.size(); i < iEnd; i += 2) {
            SimpleAttributeSet attributeSet = theme.getStyle((String) styleList.get(i + 1)).getAttributeSet();
            endPos = i + 2 < iEnd ? (Integer) styleList.get(i + 2) : document.getLength();
            startPos = (Integer) styleList.get(i);
            document.setCharacterAttributes(startPos, endPos - startPos, attributeSet, true);
        }

        repaint();
    }

    /**
     * Get current theme.
     * @return the current theme
     */
    public Theme getTheme() {
        return theme;
    }

    /**
     * Set the theme.
     * @param theme the theme
     */
    public void setTheme(Theme theme) {
        if (theme == null) {
            throw new NullPointerException("argument 'theme' cannot be null");
        }
        this.theme = theme;

        setFont(theme.getFont());
        setBackground(theme.getBackground());
        setHighlightedBackground(theme.getHighlightedBackground());

        if (styleList != null) {
            setStyle(styleList);
        }
    }

    /**
     * Get the line number offset. E.g. set offset to 9 will make the first line number to appear at line 1 + 9 = 10
     * @return the offset
     */
    public int getLineNumberOffset() {
        return lineNumberOffset;
    }

    /**
     * Set the line number offset. E.g. set offset to 9 will make the first line number to appear at line 1 + 9 = 10
     * @param offset the offset
     */
    public void setLineNumberOffset(int offset) {
        lineNumberOffset = Math.max(lineNumberOffset, offset);
        repaint();
    }

    /**
     * Get the color of the highlighted background. Default is black.
     * @return the color
     */
    public Color getHighlightedBackground() {
        return highlightedBackground;
    }

    /**
     * Set the color of the highlighted background. Default is black.
     * @param highlightedBackground the color
     */
    public void setHighlightedBackground(Color highlightedBackground) {
        if (highlightedBackground == null) {
            throw new NullPointerException("argument 'highlightedBackground' cannot be null");
        }
        this.highlightedBackground = highlightedBackground;
        repaint();
    }

    /**
     * Get the status of the mouse-over highlight effect. Default is on.
     * @return true if turned on, false if turned off
     */
    public boolean isHighlightOnMouseOver() {
        return highlightWhenMouseOver;
    }

    /**
     * Set turn on the mouse-over highlight effect or not. Default is on.
     * If set true, there will be a highlight effect on the line that the mouse cursor currently is pointing on (on the script text panel only, not on the line number panel).
     * @param highlightWhenMouseOver true to turn on, false to turn off
     */
    public void setHighlightOnMouseOver(boolean highlightWhenMouseOver) {
        this.highlightWhenMouseOver = highlightWhenMouseOver;
        if (!highlightWhenMouseOver) {
            mouseOnLine = -1;
        }
        repaint();
    }

    /**
     * Get the list of highlighted lines.
     * @return a copy of the list
     */
    public List<Integer> getHighlightedLineList() {
        List<Integer> returnList;
        synchronized (highlightedLineList) {
            returnList = new ArrayList<Integer>(highlightedLineList);
        }
        return returnList;
    }

    /**
     * Set highlighted lines. Note that this will clear all previous recorded highlighted lines.
     * @param highlightedLineList the list that contain the highlighted lines
     */
    public void setHighlightedLineList(List<Integer> highlightedLineList) {
        synchronized (this.highlightedLineList) {
            this.highlightedLineList.clear();
            if (highlightedLineList != null) {
                this.highlightedLineList.addAll(highlightedLineList);
            }
        }
        repaint();
    }

    /**
     * Add highlighted line.
     * @param lineNumber the line number to highlight
     */
    public void addHighlightedLine(int lineNumber) {
        highlightedLineList.add(lineNumber);
        repaint();
    }

    /**
     * Set the <code>font</code> according to <code>bold</code> and <code>italic</code>.
     * @param font the font to set
     * @param bold true to set bold, false not
     * @param italic true to set italic, false not
     * @return the font with bold and italic changed, or null if the input <code>font</code> is null
     */
    protected static Font setFont(Font font, boolean bold, boolean italic) {
        if (font == null) {
            return null;
        }
        if ((font.getStyle() & Font.ITALIC) != 0) {
            if (!bold) {
                return font.deriveFont(font.getStyle() ^ Font.BOLD);
            }
        } else {
            if (bold) {
                return font.deriveFont(font.getStyle() | Font.BOLD);
            }
        }
        if ((font.getStyle() & Font.ITALIC) != 0) {
            if (!italic) {
                return font.deriveFont(font.getStyle() ^ Font.ITALIC);
            }
        } else {
            if (italic) {
                return font.deriveFont(font.getStyle() | Font.ITALIC);
            }
        }
        return font;
    }
}
