/* StyledEditorKit.java --
   Copyright (C) 2002, 2004 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.event.ActionEvent;

import javax.swing.Action;
import javax.swing.JEditorPane;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;

/**
 * An {@link EditorKit} that supports editing styled text.
 *
 * @author Andrew Selkirk
 * @author Roman Kennke (roman@kennke.org)
 */
public class StyledEditorKit extends DefaultEditorKit
{
  /** The serialVersionUID. */
  private static final long serialVersionUID = 7002391892985555948L;

  /**
   * Toggles the underline attribute for the selected text.
   */
  public static class UnderlineAction extends StyledEditorKit.StyledTextAction
  {
    /**
     * Creates an instance of <code>UnderlineAction</code>.
     */
    public UnderlineAction()
    {
      super("font-underline");
    }

    /**
     * Performs the action.
     *
     * @param event the <code>ActionEvent</code> that describes the action
     */
    public void actionPerformed(ActionEvent event)
    {
      JEditorPane editor = getEditor(event);
      StyledDocument doc = getStyledDocument(editor);
      Element el = doc.getCharacterElement(editor.getSelectionStart());
      boolean isUnderline = StyleConstants.isUnderline(el.getAttributes());
      SimpleAttributeSet atts = new SimpleAttributeSet();
      StyleConstants.setUnderline(atts, ! isUnderline);
      setCharacterAttributes(editor, atts, false);
    }
  }

  /**
   * Toggles the italic attribute for the selected text.
   */
  public static class ItalicAction extends StyledEditorKit.StyledTextAction
  {
    /**
     * Creates an instance of <code>ItalicAction</code>.
     */
    public ItalicAction()
    {
      super("font-italic");
    }

    /**
     * Performs the action.
     *
     * @param event the <code>ActionEvent</code> that describes the action
     */
    public void actionPerformed(ActionEvent event)
    {
      JEditorPane editor = getEditor(event);
      StyledDocument doc = getStyledDocument(editor);
      Element el = doc.getCharacterElement(editor.getSelectionStart());
      boolean isItalic = StyleConstants.isItalic(el.getAttributes());
      SimpleAttributeSet atts = new SimpleAttributeSet();
      StyleConstants.setItalic(atts, ! isItalic);
      setCharacterAttributes(editor, atts, false);
    }
  }

  /**
   * Toggles the bold attribute for the selected text.
   */
  public static class BoldAction extends StyledEditorKit.StyledTextAction
  {
    /**
     * Creates an instance of <code>BoldAction</code>.
     */
    public BoldAction()
    {
      super("font-bold");
    }

    /**
     * Performs the action.
     *
     * @param event the <code>ActionEvent</code> that describes the action
     */
    public void actionPerformed(ActionEvent event)
    {
      JEditorPane editor = getEditor(event);
      StyledDocument doc = getStyledDocument(editor);
      Element el = doc.getCharacterElement(editor.getSelectionStart());
      boolean isBold = StyleConstants.isBold(el.getAttributes());
      SimpleAttributeSet atts = new SimpleAttributeSet();
      StyleConstants.setBold(atts, ! isBold);
      setCharacterAttributes(editor, atts, false);
    }
  }

  /**
   * Sets the alignment attribute on the selected text.
   */
  public static class AlignmentAction extends StyledEditorKit.StyledTextAction
  {
    /**
     * The aligment to set.
     */
    private int a;

    /**
     * Creates a new instance of <code>AlignmentAction</code> to set the
     * alignment to <code>a</code>.
     *
     * @param nm the name of the Action
     * @param a the alignment to set
     */
    public AlignmentAction(String nm, int a)
    {
      super(nm);
      this.a = a;
    }

    /**
     * Performs the action.
     *
     * @param event the <code>ActionEvent</code> that describes the action
     */
    public void actionPerformed(ActionEvent event)
    {
      SimpleAttributeSet atts = new SimpleAttributeSet();
      StyleConstants.setAlignment(atts, a);
      setParagraphAttributes(getEditor(event), atts, false);
    }
  }

  /**
   * Sets the foreground color attribute on the selected text.
   */
  public static class ForegroundAction extends StyledEditorKit.StyledTextAction
  {
    /**
     * The foreground color to set.
     */
    private Color fg;

    /**
     * Creates a new instance of <code>ForegroundAction</code> to set the
     * foreground color to <code>fg</code>.
     *
     * @param nm the name of the Action
     * @param fg the foreground color to set
     */
    public ForegroundAction(String nm, Color fg)
    {
      super(nm);
      this.fg = fg;
    }

    /**
     * Performs the action.
     *
     * @param event the <code>ActionEvent</code> that describes the action
     */
    public void actionPerformed(ActionEvent event)
    {
      SimpleAttributeSet atts = new SimpleAttributeSet();
      StyleConstants.setForeground(atts, fg);
      setCharacterAttributes(getEditor(event), atts, false);
    }
  }

  /**
   * Sets the font size attribute on the selected text.
   */
  public static class FontSizeAction extends StyledEditorKit.StyledTextAction
  {
    /**
     * The font size to set.
     */
    private int size;

    /**
     * Creates a new instance of <code>FontSizeAction</code> to set the
     * font size to <code>size</code>.
     *
     * @param nm the name of the Action
     * @param size the font size to set
     */
    public FontSizeAction(String nm, int size)
    {
      super(nm);
      this.size = size;
    }

    /**
     * Performs the action.
     *
     * @param event the <code>ActionEvent</code> that describes the action
     */
    public void actionPerformed(ActionEvent event)
    {
      SimpleAttributeSet atts = new SimpleAttributeSet();
      StyleConstants.setFontSize(atts, size);
      setCharacterAttributes(getEditor(event), atts, false);
    }
  }

  /**
   * Sets the font family attribute on the selected text.
   */
  public static class FontFamilyAction extends StyledEditorKit.StyledTextAction
  {
    /**
     * The font family to set.
     */
    private String family;

    /**
     * Creates a new instance of <code>FontFamilyAction</code> to set the
     * font family to <code>family</code>.
     *
     * @param nm the name of the Action
     * @param family the font family to set
     */
    public FontFamilyAction(String nm, String family)
    {
      super(nm);
      this.family = family;
    }

    /**
     * Performs the action.
     *
     * @param event the <code>ActionEvent</code> that describes the action
     */
    public void actionPerformed(ActionEvent event)
    {
      SimpleAttributeSet atts = new SimpleAttributeSet();
      StyleConstants.setFontFamily(atts, family);
      setCharacterAttributes(getEditor(event), atts, false);
    }
  }

  /**
   * The abstract superclass of all styled TextActions. This class
   * provides some useful methods to manipulate the text attributes.
   */
  public abstract static class StyledTextAction extends TextAction
  {
    /**
     * Creates a new instance of <code>StyledTextAction</code>.
     *
     * @param nm the name of the <code>StyledTextAction</code>
     */
    public StyledTextAction(String nm)
    {
      super(nm);
    }

    /**
     * Returns the <code>JEditorPane</code> component from which the
     * <code>ActionEvent</code> originated.
     *
     * @param event the <code>ActionEvent</code>
     * @return the <code>JEditorPane</code> component from which the
     *         <code>ActionEvent</code> originated
     */
    protected final JEditorPane getEditor(ActionEvent event)
    {
      return (JEditorPane) getTextComponent(event);
    }

    /**
     * Sets the specified character attributes on the currently selected
     * text of <code>editor</code>. If <code>editor</code> does not have
     * a selection, then the attributes are used as input attributes
     * for newly inserted content.
     *
     * @param editor the <code>JEditorPane</code> component
     * @param atts the text attributes to set
     * @param replace if <code>true</code> the current attributes of the
     *        selection are replaces, otherwise they are merged
     */
    protected final void setCharacterAttributes(JEditorPane editor,
                                                AttributeSet atts,
                                                boolean replace)
    {
      int p0 = editor.getSelectionStart();
      int p1 = editor.getSelectionEnd();
      if (p0 != p1)
        {
          StyledDocument doc = getStyledDocument(editor);
          doc.setCharacterAttributes(p0, p1 - p0, atts, replace);
        }
      // Update input attributes.
      StyledEditorKit kit = getStyledEditorKit(editor);
      MutableAttributeSet inputAtts = kit.getInputAttributes();
      if (replace)
        {
          inputAtts.removeAttributes(inputAtts);
        }
      inputAtts.addAttributes(atts);
    }

    /**
     * Returns the {@link StyledDocument} that is used by <code>editor</code>.
     *
     * @param editor the <code>JEditorPane</code> from which to get the
     *        <code>StyledDocument</code>
     *
     * @return the {@link StyledDocument} that is used by <code>editor</code>
     */
    protected final StyledDocument getStyledDocument(JEditorPane editor)
    {
      Document doc = editor.getDocument();
      if (!(doc instanceof StyledDocument))
	throw new AssertionError("The Document for StyledEditorKits is "
				 + "expected to be a StyledDocument.");

      return (StyledDocument) doc;
    }

    /**
     * Returns the {@link StyledEditorKit} that is used by <code>editor</code>.
     *
     * @param editor the <code>JEditorPane</code> from which to get the
     *        <code>StyledEditorKit</code>
     *
     * @return the {@link StyledEditorKit} that is used by <code>editor</code>
     */
    protected final StyledEditorKit getStyledEditorKit(JEditorPane editor)
    {
      EditorKit kit = editor.getEditorKit();
      if (!(kit instanceof StyledEditorKit))
	throw new AssertionError("The EditorKit for StyledDocuments is "
				 + "expected to be a StyledEditorKit.");

      return (StyledEditorKit) kit;
    }

    /**
     * Sets the specified character attributes on the paragraph that
     * contains the currently selected
     * text of <code>editor</code>. If <code>editor</code> does not have
     * a selection, then the attributes are set on the paragraph that
     * contains the current caret position.
     *
     * @param editor the <code>JEditorPane</code> component
     * @param atts the text attributes to set
     * @param replace if <code>true</code> the current attributes of the
     *        selection are replaces, otherwise they are merged
     */
    protected final void setParagraphAttributes(JEditorPane editor,
                                                AttributeSet atts,
                                                boolean replace)
    {
      Document doc = editor.getDocument();
      if (doc instanceof StyledDocument)
	{
	  StyledDocument styleDoc = (StyledDocument) editor.getDocument();
	  EditorKit kit = editor.getEditorKit();
	  if (!(kit instanceof StyledEditorKit))
	    {
	      StyledEditorKit styleKit = (StyledEditorKit) kit;
	      int start = editor.getSelectionStart();
	      int end = editor.getSelectionEnd();
	      int dot = editor.getCaret().getDot();
	      if (start == dot && end == dot)
		{
		  // If there is no selection, then we only update the
		  // input attributes.
		  MutableAttributeSet inputAttributes =
		    styleKit.getInputAttributes();
		  inputAttributes.addAttributes(atts);
		}
	      else
		styleDoc.setParagraphAttributes(start, end, atts, replace);
	    }
	  else
	    throw new AssertionError("The EditorKit for StyledTextActions "
				     + "is expected to be a StyledEditorKit");
	}
      else
	throw new AssertionError("The Document for StyledTextActions is "
				 + "expected to be a StyledDocument.");
    }
  }

  /**
   * A {@link ViewFactory} that is able to create {@link View}s for
   * the <code>Element</code>s that are supported by
   * <code>StyledEditorKit</code>, namely the following types of Elements:
   *
   * <ul>
   * <li>{@link AbstractDocument#ContentElementName}</li>
   * <li>{@link AbstractDocument#ParagraphElementName}</li>
   * <li>{@link AbstractDocument#SectionElementName}</li>
   * <li>{@link StyleConstants#ComponentElementName}</li>
   * <li>{@link StyleConstants#IconElementName}</li>
   * </ul>
   */
  static class StyledViewFactory
    implements ViewFactory
  {
    /**
     * Creates a {@link View} for the specified <code>Element</code>.
     *
     * @param element the <code>Element</code> to create a <code>View</code>
     *        for
     * @return the <code>View</code> for the specified <code>Element</code>
     *         or <code>null</code> if the type of <code>element</code> is
     *         not supported
     */
    public View create(Element element)
    {
      String name = element.getName();
      View view = null;
      if (name.equals(AbstractDocument.ContentElementName))
	view = new LabelView(element);
      else if (name.equals(AbstractDocument.ParagraphElementName))
	view = new ParagraphView(element);
      else if (name.equals(AbstractDocument.SectionElementName))
	view = new BoxView(element, View.Y_AXIS);
      else if (name.equals(StyleConstants.ComponentElementName))
	view = new ComponentView(element);
      else if (name.equals(StyleConstants.IconElementName))
	view = new IconView(element);
      else
        throw new AssertionError("Unknown Element type: "
                                 + element.getClass().getName() + " : "
                                 + name);
      return view;
    }
  }

  /**
   * Keeps track of the caret position and updates the currentRun
   * <code>Element</code> and the <code>inputAttributes</code>.
   */
  class CaretTracker
    implements CaretListener
  {
    /**
     * Notifies an update of the caret position.
     *
     * @param ev the event for the caret update
     */
    public void caretUpdate(CaretEvent ev)
    {
      Object source = ev.getSource();
      if (!(source instanceof JTextComponent))
	throw new AssertionError("CaretEvents are expected to come from a"
				 + "JTextComponent.");

      JTextComponent text = (JTextComponent) source;
      Document doc = text.getDocument();
      if (!(doc instanceof StyledDocument))
	throw new AssertionError("The Document used by StyledEditorKits is"
				 + "expected to be a StyledDocument");

      StyledDocument styleDoc = (StyledDocument) doc;
      currentRun = styleDoc.getCharacterElement(ev.getDot());
      createInputAttributes(currentRun, inputAttributes);
    }
  }

  /**
   * Stores the <code>Element</code> at the current caret position. This
   * is updated by {@link CaretTracker}.
   */
  Element currentRun;

  /**
   * The current input attributes. This is updated by {@link CaretTracker}.
   */
  MutableAttributeSet inputAttributes;

  /**
   * The CaretTracker that keeps track of the current input attributes, and
   * the current character run Element.
   */
  CaretTracker caretTracker;

  /**
   * The ViewFactory for StyledEditorKits.
   */
  StyledViewFactory viewFactory;

  /**
   * Creates a new instance of <code>StyledEditorKit</code>.
   */
  public StyledEditorKit()
  {
    inputAttributes = new SimpleAttributeSet();
  }

  /**
   * Creates an exact copy of this <code>StyledEditorKit</code>.
   *
   * @return an exact copy of this <code>StyledEditorKit</code>
   */
  public Object clone()
  {
    StyledEditorKit clone = (StyledEditorKit) super.clone();
    // FIXME: Investigate which fields must be copied.
    return clone;
  }

  /**
   * Returns the <code>Action</code>s supported by this {@link EditorKit}.
   * This includes the {@link BoldAction}, {@link ItalicAction} and
   * {@link UnderlineAction} as well as the <code>Action</code>s supported
   * by {@link DefaultEditorKit}.
   *
   * The other <code>Action</code>s of <code>StyledEditorKit</code> are not
   * returned here, since they require a parameter and thus custom
   * instantiation.
   *
   * @return the <code>Action</code>s supported by this {@link EditorKit}
   */
  public Action[] getActions()
  {
    Action[] actions1 = super.getActions();
    Action[] myActions = new Action[] { 
      new FontSizeAction("font-size-8", 8),
      new FontSizeAction("font-size-10", 10),
      new FontSizeAction("font-size-12", 12),
      new FontSizeAction("font-size-14", 14),
      new FontSizeAction("font-size-16", 16),
      new FontSizeAction("font-size-18", 18),
      new FontSizeAction("font-size-24", 24),
      new FontSizeAction("font-size-36", 36),
      new FontSizeAction("font-size-48", 48),
      new FontFamilyAction("font-family-Serif", "Serif"),
      new FontFamilyAction("font-family-Monospaced", "Monospaced"),
      new FontFamilyAction("font-family-SansSerif", "SansSerif"),
      new AlignmentAction("left-justify", StyleConstants.ALIGN_LEFT),
      new AlignmentAction("center-justify", StyleConstants.ALIGN_CENTER),
      new AlignmentAction("right-justify", StyleConstants.ALIGN_RIGHT),
      new BoldAction(),
      new ItalicAction(),
      new UnderlineAction()
    };
    return TextAction.augmentList(actions1, myActions);
  }

  /**
   * Returns the current input attributes. These are automatically set on
   * any newly inserted content, if not specified otherwise.
   *
   * @return the current input attributes
   */
  public MutableAttributeSet getInputAttributes()
  {
    return inputAttributes;
  }

  /**
   * Returns the {@link Element} that represents the character run at the
   * current caret position.
   *
   * @return the {@link Element} that represents the character run at the
   *         current caret position
   */
  public Element getCharacterAttributeRun()
  {
    return currentRun;
  }

  /**
   * Creates the default {@link Document} supported by this
   * <code>EditorKit</code>. This is an instance of
   * {@link DefaultStyledDocument} in this case but may be overridden by
   * subclasses.
   *
   * @return an instance of <code>DefaultStyledDocument</code>
   */
  public Document createDefaultDocument()
  {
    return new DefaultStyledDocument();
  }

  /**
   * Installs this <code>EditorKit</code> on the specified {@link JEditorPane}.
   * This basically involves setting up required listeners on the
   * <code>JEditorPane</code>.
   *
   * @param component the <code>JEditorPane</code> to install this
   *        <code>EditorKit</code> on
   */
  public void install(JEditorPane component)
  {
    CaretTracker tracker = new CaretTracker();
    component.addCaretListener(tracker);
  }

  /**
   * Deinstalls this <code>EditorKit</code> from the specified
   * {@link JEditorPane}. This basically involves removing all listeners from
   * <code>JEditorPane</code> that have been set up by this
   * <code>EditorKit</code>.
   *
   * @param component the <code>JEditorPane</code> from which to deinstall this
   *        <code>EditorKit</code>
   */
  public void deinstall(JEditorPane component)
  {
    CaretTracker t = caretTracker;
    if (t != null)
      component.removeCaretListener(t);
    caretTracker = null;
  }

  /**
   * Returns a {@link ViewFactory} that is able to create {@link View}s
   * for {@link Element}s that are supported by this <code>EditorKit</code>,
   * namely the following types of <code>Element</code>s:
   *
   * <ul>
   * <li>{@link AbstractDocument#ContentElementName}</li>
   * <li>{@link AbstractDocument#ParagraphElementName}</li>
   * <li>{@link AbstractDocument#SectionElementName}</li>
   * <li>{@link StyleConstants#ComponentElementName}</li>
   * <li>{@link StyleConstants#IconElementName}</li>
   * </ul>
   *
   * @return a {@link ViewFactory} that is able to create {@link View}s
   *          for {@link Element}s that are supported by this <code>EditorKit</code>
   */
  public ViewFactory getViewFactory()
  {
    if (viewFactory == null)
      viewFactory = new StyledViewFactory();
    return viewFactory;
  }

  /**
   * Copies the text attributes from <code>element</code> to <code>set</code>.
   * This is called everytime when the caret position changes to keep
   * track of the current input attributes. The attributes in <code>set</code>
   * are cleaned before adding the attributes of <code>element</code>.
   *
   * This method filters out attributes for element names, <code>Icon</code>s
   * and <code>Component</code>s.
   *
   * @param element the <code>Element</code> from which to copy the text
   *         attributes
   * @param set the inputAttributes to copy the attributes to
   */
  protected void createInputAttributes(Element element,
				       MutableAttributeSet set)
  {
    // FIXME: Filter out component, icon and element name attributes.
    set.removeAttributes(set);
    set.addAttributes(element.getAttributes());
  }
}
