/* DefaultHighlighter.java -- The default highlight for Swing
   Copyright (C) 2004, 2006  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing.text;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Shape;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.SwingUtilities;
import javax.swing.plaf.TextUI;

/**
 * The default highlight for Swing text components. It highlights text
 * by filling the background with a rectangle.
 */
public class DefaultHighlighter extends LayeredHighlighter
{
  public static class DefaultHighlightPainter
    extends LayerPainter
  {
    private Color color;

    public DefaultHighlightPainter(Color c)
    {
      super();
      color = c;
    }

    public Color getColor()
    {
      return color;
    }

    public void paint(Graphics g, int p0, int p1, Shape bounds,
                      JTextComponent t)
    {
      if (p0 == p1)
        return;

      Rectangle rect = bounds.getBounds();

      Color col = getColor();
      if (col == null)
        col = t.getSelectionColor();
      g.setColor(col);

      TextUI ui = t.getUI();

      try
        {

          Rectangle l0 = ui.modelToView(t, p0, null);
          Rectangle l1 = ui.modelToView(t, p1, null);

          // Note: The computed locations may lie outside of the allocation
          // area if the text is scrolled.

          if (l0.y == l1.y)
          {
            SwingUtilities.computeUnion(l0.x, l0.y, l0.width, l0.height, l1);

            // Paint only inside the allocation area.
            SwingUtilities.computeIntersection(rect.x, rect.y, rect.width,
                                               rect.height, l1);

            g.fillRect(l1.x, l1.y, l1.width, l1.height);
          }
        else
          {
            // 1. The line of p0 is painted from the position of p0
            // to the right border.
            // 2. All lines between the ones where p0 and p1 lie on
            // are completely highlighted. The allocation area is used to find
            // out the bounds.
            // 3. The final line is painted from the left border to the
            // position of p1.

            int firstLineWidth = rect.x + rect.width - l0.x;
            g.fillRect(l0.x, l0.y, firstLineWidth, l0.height);
            if (l0.y + l0.height != l1.y)
              {
                g.fillRect(rect.x, l0.y + l0.height, rect.width,
                           l1.y - l0.y - l0.height);
              }
            g.fillRect(rect.x, l1.y, l1.x - rect.x, l1.height);
          }
      }
    catch (BadLocationException ex)
      {
        // Can't render. Comment out for debugging.
        // ex.printStackTrace();
      }
    }

    public Shape paintLayer(Graphics g, int p0, int p1, Shape bounds,
                            JTextComponent c, View view)
    {
      Color col = getColor();
      if (col == null)
        col = c.getSelectionColor();
      g.setColor(col);

      Rectangle rect = null;
      if (p0 == view.getStartOffset() && p1 == view.getEndOffset())
        {
          // Paint complete bounds region.
          rect = bounds instanceof Rectangle ? (Rectangle) bounds
                                             : bounds.getBounds();
        }
      else
        {
          // Only partly inside the view.
          try
            {
              Shape s = view.modelToView(p0, Position.Bias.Forward,
                                         p1, Position.Bias.Backward,
                                         bounds);
              rect = s instanceof Rectangle ? (Rectangle) s : s.getBounds();
            }
          catch (BadLocationException ex)
            {
              // Can't render the highlight.
            }
        }

      if (rect != null)
        {
          g.fillRect(rect.x, rect.y, rect.width, rect.height);
        }
      return rect;
    }
  }

  private class HighlightEntry implements Highlighter.Highlight
  {
    Position p0;
    Position p1;
    Highlighter.HighlightPainter painter;

    public HighlightEntry(Position p0, Position p1,
                          Highlighter.HighlightPainter painter)
    {
      this.p0 = p0;
      this.p1 = p1;
      this.painter = painter;
    }

    public int getStartOffset()
    {
      return p0.getOffset();
    }

    public int getEndOffset()
    {
      return p1.getOffset();
    }

    public Highlighter.HighlightPainter getPainter()
    {
      return painter;
    }
  }

  /**
   * A HighlightEntry that is used for LayerPainter painters. In addition
   * to the info maintained by the HighlightEntry, this class maintains
   * a painting rectangle. This is used as repaint region when the
   * highlight changes and the text component needs repainting.
   */
  private class LayerHighlightEntry
    extends HighlightEntry
  {

    /**
     * The paint rectangle.
     */
    Rectangle paintRect = new Rectangle();

    LayerHighlightEntry(Position p0, Position p1,
                        Highlighter.HighlightPainter p)
    {
      super(p0, p1, p);
    }

    /**
     * Paints the highlight by calling the LayerPainter. This
     * restricts the area to be painted by startOffset and endOffset
     * and manages the paint rectangle.
     */
    void paintLayeredHighlight(Graphics g, int p0, int p1, Shape bounds,
                               JTextComponent tc, View view)
    {
      p0 = Math.max(getStartOffset(), p0);
      p1 = Math.min(getEndOffset(), p1);

      Highlighter.HighlightPainter painter = getPainter();
      if (painter instanceof LayerPainter)
        {
          LayerPainter layerPainter = (LayerPainter) painter;
          Shape area = layerPainter.paintLayer(g, p0, p1, bounds, tc, view);
          Rectangle rect;
          if (area instanceof Rectangle && paintRect != null)
            rect = (Rectangle) area;
          else
            rect = area.getBounds();

          if (paintRect.width == 0 || paintRect.height == 0)
            paintRect = rect.getBounds();
          else
            paintRect = SwingUtilities.computeUnion(rect.x, rect.y, rect.width,
                                                    rect.height, paintRect);
        }
    }
  }

  /**
   * @specnote final as of 1.4
   */
  public static final LayeredHighlighter.LayerPainter DefaultPainter =
    new DefaultHighlightPainter(null);

  private JTextComponent textComponent;
  private ArrayList highlights = new ArrayList();
  private boolean drawsLayeredHighlights = true;

  public DefaultHighlighter()
  {
    // Nothing to do here.
  }

  public boolean getDrawsLayeredHighlights()
  {
    return drawsLayeredHighlights;
  }

  public void setDrawsLayeredHighlights(boolean newValue)
  {
    drawsLayeredHighlights = newValue;
  }

  private void checkPositions(int p0, int p1)
    throws BadLocationException
  {
    if (p0 < 0)
      throw new BadLocationException("DefaultHighlighter", p0);

    if (p1 < p0)
      throw new BadLocationException("DefaultHighlighter", p1);
  }

  public void install(JTextComponent c)
  {
    textComponent = c;
    removeAllHighlights();
  }

  public void deinstall(JTextComponent c)
  {
    textComponent = null;
  }

  public Object addHighlight(int p0, int p1,
                             Highlighter.HighlightPainter painter)
    throws BadLocationException
  {
    checkPositions(p0, p1);
    HighlightEntry entry;
    Document doc = textComponent.getDocument();
    Position pos0 = doc.createPosition(p0);
    Position pos1 = doc.createPosition(p1);
    if (getDrawsLayeredHighlights() && painter instanceof LayerPainter)
      entry = new LayerHighlightEntry(pos0, pos1, painter);
    else
      entry = new HighlightEntry(pos0, pos1, painter);
    highlights.add(entry);

    textComponent.getUI().damageRange(textComponent, p0, p1);

    return entry;
  }

  public void removeHighlight(Object tag)
  {
    HighlightEntry entry = (HighlightEntry) tag;
    if (entry instanceof LayerHighlightEntry)
      {
        LayerHighlightEntry lEntry = (LayerHighlightEntry) entry;
        Rectangle paintRect = lEntry.paintRect;
        textComponent.repaint(paintRect.x, paintRect.y, paintRect.width,
                              paintRect.height);
      }
    else
      {
        textComponent.getUI().damageRange(textComponent,
                                          entry.getStartOffset(),
                                          entry.getEndOffset());
      }
    highlights.remove(tag);

  }

  public void removeAllHighlights()
  {
    // Repaint damaged region.
    int minX = 0;
    int maxX = 0;
    int minY = 0;
    int maxY = 0;
    int p0 = -1;
    int p1 = -1;
    for (Iterator i = highlights.iterator(); i.hasNext();)
      {
        HighlightEntry e = (HighlightEntry) i.next();
        if (e instanceof LayerHighlightEntry)
          {
            LayerHighlightEntry le = (LayerHighlightEntry) e;
            Rectangle r = le.paintRect;
            minX = Math.min(r.x, minX);
            maxX = Math.max(r.x + r.width, maxX);
            minY = Math.min(r.y, minY);
            maxY = Math.max(r.y + r.height, maxY);
          }
        else
          {
            if (p0 == -1 || p1 == -1)
              {
                p0 = e.getStartOffset();
                p1 = e.getEndOffset();
              }
            else
              {
                p0 = Math.min(p0, e.getStartOffset());
                p1 = Math.max(p1, e.getEndOffset());
              }
          }
        if (minX != maxX && minY != maxY)
          textComponent.repaint(minX, minY, maxX - minX, maxY - minY);
        if (p0 != -1 && p1 != -1)
          {
            TextUI ui = textComponent.getUI();
            ui.damageRange(textComponent, p0, p1);
          }

      }
    highlights.clear();
  }

  public Highlighter.Highlight[] getHighlights()
  {
    return (Highlighter.Highlight[])
      highlights.toArray(new Highlighter.Highlight[highlights.size()]);
  }

  public void changeHighlight(Object tag, int n0, int n1)
    throws BadLocationException
  {
    Document doc = textComponent.getDocument();
    TextUI ui = textComponent.getUI();
    if (tag instanceof LayerHighlightEntry)
      {
        LayerHighlightEntry le = (LayerHighlightEntry) tag;
        Rectangle r = le.paintRect;
        if (r.width > 0 && r.height > 0)
          textComponent.repaint(r.x, r.y, r.width, r.height);
        r.width = 0;
        r.height = 0;
        le.p0 = doc.createPosition(n0);
        le.p1 = doc.createPosition(n1);
        ui.damageRange(textComponent, Math.min(n0, n1), Math.max(n0, n1));
      }
    else if (tag instanceof HighlightEntry)
      {
        HighlightEntry e = (HighlightEntry) tag;
        int p0 = e.getStartOffset();
        int p1 = e.getEndOffset();
        if (p0 == n0)
          {
            ui.damageRange(textComponent, Math.min(p1, n1),
                           Math.max(p1, n1));
          }
        else if (n1 == p1)
          {
            ui.damageRange(textComponent, Math.min(p0, n0),
                           Math.max(p0, n0));
          }
        else
          {
            ui.damageRange(textComponent, p0, p1);
            ui.damageRange(textComponent, n0, n1);
          }
        e.p0 = doc.createPosition(n0);
        e.p1 = doc.createPosition(n1);
      }
  }

  public void paintLayeredHighlights(Graphics g, int p0, int p1,
                                     Shape viewBounds, JTextComponent editor,
                                     View view)
  {
    for (Iterator i = highlights.iterator(); i.hasNext();)
      {
        Object o = i.next();
        if (o instanceof LayerHighlightEntry)
          {
            LayerHighlightEntry entry = (LayerHighlightEntry) o;
            int start = entry.getStartOffset();
            int end = entry.getEndOffset();
            if ((p0 < start && p1 > start) || (p0 >= start && p0 < end))
              entry.paintLayeredHighlight(g, p0, p1, viewBounds, editor, view);
          }
      }
  }

  public void paint(Graphics g)
  {
    int size = highlights.size();

    // Check if there are any highlights.
    if (size == 0)
      return;

    // Prepares the rectangle of the inner drawing area.
    Insets insets = textComponent.getInsets();
    Shape bounds =
      new Rectangle(insets.left,
                    insets.top,
                    textComponent.getWidth() - insets.left - insets.right,
                    textComponent.getHeight() - insets.top - insets.bottom);

    for (int index = 0; index < size; ++index)
      {
        HighlightEntry entry = (HighlightEntry) highlights.get(index);
        if (! (entry instanceof LayerHighlightEntry))
          entry.painter.paint(g, entry.getStartOffset(), entry.getEndOffset(),
                              bounds, textComponent);
      }
  }
}
