// Copyright (C) 2011 Chan Wai Shing
//
// Licensed 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.
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;
    }
}
