/* DefaultTreeCellEditor.java --
   Copyright (C) 2002, 2004, 2005  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.tree;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.EventObject;

import javax.swing.DefaultCellEditor;
import javax.swing.Icon;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.EventListenerList;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;

/**
 * Participates in the tree cell editing.
 * 
 * @author Andrew Selkirk
 * @author Audrius Meskauskas
 */
public class DefaultTreeCellEditor
  implements ActionListener, TreeCellEditor, TreeSelectionListener
{
  /**
   * The number of the fast mouse clicks, required to start the editing 
   * session.
   */
  static int CLICK_COUNT_TO_START = 3;
  
  /**
   * This container that appears on the tree during editing session.
   * It contains the editing component displays various other editor - 
   * specific parts like editing icon. 
   */
  public class EditorContainer extends Container
  {
   /**
    * Use v 1.5 serial version UID for interoperability.
    */
    static final long serialVersionUID = 6470339600449699810L;
    
    /**
     * Creates an <code>EditorContainer</code> object.
     */
    public EditorContainer()
    {
      // Do nothing here.
    }

    /**
     * This method only exists for API compatibility and is useless as it does
     * nothing. It got probably introduced by accident.
     */
    public void EditorContainer()
    {
      // Do nothing here.
    }
   
    public void setBounds(Rectangle bounds)
    {
      super.setBounds(bounds);
      doLayout();
    }

    /**
     * Overrides Container.paint to paint the node's icon and use the selection
     * color for the background.
     * 
     * @param g -
     *          the specified Graphics window
     */
    public void paint(Graphics g)
    {
      if (editingIcon != null)
        {
          // From the previous version, the left margin is taken as half
          // of the icon width.
          editingIcon.paintIcon(this, g, 0, 0);
        }
      super.paint(g);
    }

    /**
     * Lays out this Container, moving the editor component to the left
     * (leaving place for the icon).
     */
    public void doLayout()
    {
      // The offset of the editing component.
      int eOffset;

      // Move the component to the left, leaving room for the editing icon:
      if (editingIcon != null)
        eOffset = editingIcon.getIconWidth();
      else
        eOffset = 0;

      Rectangle bounds = getBounds();
      Component c = getComponent(0);
      c.setLocation(eOffset, 0);

      // Span the editing component near over all window width.
      c.setSize(bounds.width - eOffset, bounds.height);
      /*
       * @specnote the Sun sets some more narrow editing component width (it is
       * not documented how does it is calculated). However as our text field is
       * still not able to auto - scroll horizontally, replicating such strategy
       * would prevent adding extra characters to the text being edited.
       */
    }
  }

  /**
   * The default text field, used in the editing sessions.
   */
  public class DefaultTextField extends JTextField
  {
   /**
    * Use v 1.5 serial version UID for interoperability.
    */
    static final long serialVersionUID = -6629304544265300143L; 
    
    /**
     * The border of the text field.
     */
    protected Border border;

    /**
     * Creates a <code>DefaultTextField</code> object.
     *
     * @param aBorder the border to use
     */
    public DefaultTextField(Border aBorder)
    {
      border = aBorder;
    }

    /**
     * Gets the font of this component.
     * @return this component's font; if a font has not been set for 
     * this component, the font of its parent is returned (if the parent
     * is not null, otherwise null is returned). 
     */
    public Font getFont()
    {
      Font font = super.getFont();
      if (font == null)
        {
          Component parent = getParent();
          if (parent != null)
            return parent.getFont();
          return null;
        }
      return font;
    }

    /**
     * Returns the border of the text field.
     *
     * @return the border
     */
    public Border getBorder()
    {
      return border;
    }

    /**
     * Overrides JTextField.getPreferredSize to return the preferred size 
     * based on current font, if set, or else use renderer's font.
     * 
     * @return the Dimension of this textfield.
     */
    public Dimension getPreferredSize()
    {
      String s = getText();

      Font f = getFont();

      if (f != null)
        {
          FontMetrics fm = getToolkit().getFontMetrics(f);

          return new Dimension(SwingUtilities.computeStringWidth(fm, s),
                               fm.getHeight());
        }
      return renderer.getPreferredSize();
    }
  }
  
  /**
   * Listens for the events from the realEditor.
   */
  class RealEditorListener implements CellEditorListener
  {
    /**
     * The method is called when the editing has been cancelled.
     * @param event unused
     */
    public void editingCanceled(ChangeEvent event)
    {
      cancelCellEditing();
    }

    /**
     * The method is called after completing the editing session.
     * 
     * @param event unused
     */
    public void editingStopped(ChangeEvent event)
    {
      stopCellEditing();
    }
  }

  private EventListenerList listenerList = new EventListenerList();
  
  /**
   * Editor handling the editing.
   */
  protected TreeCellEditor realEditor;

  /**
   * Renderer, used to get border and offsets from.
   */
  protected DefaultTreeCellRenderer renderer;

  /**
   * Editing container, will contain the editorComponent.
   */
  protected Container editingContainer;

  /**
   * Component used in editing, obtained from the editingContainer.
   */
  protected transient Component editingComponent;

  /**
   * As of Java 2 platform v1.4 this field should no longer be used. 
   * If you wish to provide similar behavior you should directly 
   * override isCellEditable.
   */
  protected boolean canEdit;

  /**
   * Used in editing. Indicates x position to place editingComponent.
   */
  protected transient int offset;

  /**
   * JTree instance listening too.
   */
  protected transient JTree tree;

  /**
   * Last path that was selected.
   */
  protected transient TreePath lastPath;

  /**
   * Used before starting the editing session.
   */
  protected transient javax.swing.Timer timer;

  /**
   * Row that was last passed into getTreeCellEditorComponent.
   */
  protected transient int lastRow;

  /**
   * True if the border selection color should be drawn.
   */
  protected Color borderSelectionColor;

  /**
   * Icon to use when editing.
   */
  protected transient Icon editingIcon;

  /**
   * Font to paint with, null indicates font of renderer is to be used.
   */
  protected Font font;
  
  /**
   * Helper field used to save the last path seen while the timer was
   * running.
   */
    private TreePath tPath;
    
  /**
   * Constructs a DefaultTreeCellEditor object for a JTree using the 
   * specified renderer and a default editor. (Use this constructor 
   * for normal editing.)
   * 
   * @param tree - a JTree object
   * @param renderer - a DefaultTreeCellRenderer object
   */
  public DefaultTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer)
  {
    this(tree, renderer, null);
  }

  /**
   * Constructs a DefaultTreeCellEditor  object for a JTree using the specified 
   * renderer and the specified editor. (Use this constructor 
   * for specialized editing.)
   * 
   * @param tree - a JTree object
   * @param renderer - a DefaultTreeCellRenderer object
   * @param editor - a TreeCellEditor object
   */
  public DefaultTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer,
                               TreeCellEditor editor)
  {
    setTree(tree);
    this.renderer = renderer;
    
    if (editor == null)
      editor = createTreeCellEditor();
    else
      editor.addCellEditorListener(new RealEditorListener());
    
    realEditor = editor;
    
    lastPath = tree.getLeadSelectionPath();
    tree.addTreeSelectionListener(this);
    editingContainer = createContainer();
    setFont(UIManager.getFont("Tree.font"));
    setBorderSelectionColor(UIManager.getColor("Tree.selectionBorderColor"));
  }

  /**
   * Configures the editing component whenever it is null.
   * 
   * @param tree the tree to configure to component for.
   * @param renderer the renderer used to set up the nodes
   * @param editor the editor used 
   */
  private void configureEditingComponent(JTree tree,
                                         DefaultTreeCellRenderer renderer,
                                         TreeCellEditor editor)
  {    
    if (tree != null && lastPath != null)
      {
        Object val = lastPath.getLastPathComponent();
        boolean isLeaf = tree.getModel().isLeaf(val);
        boolean expanded = tree.isExpanded(lastPath);
        determineOffset(tree, val, true, expanded, isLeaf, lastRow);

        // set up icon
        if (isLeaf)
          renderer.setIcon(renderer.getLeafIcon());
        else if (expanded)
          renderer.setIcon(renderer.getOpenIcon());
        else
          renderer.setIcon(renderer.getClosedIcon());
        editingIcon = renderer.getIcon();
        
        editingComponent = getTreeCellEditorComponent(tree, val, true,
                                                      expanded, isLeaf, lastRow);
      }
  }
  
  /**
   * writeObject
   * 
   * @param value0
   *          TODO
   * @exception IOException
   *              TODO
   */
  private void writeObject(ObjectOutputStream value0) throws IOException
  {
    // TODO
  }

  /**
   * readObject
   * @param value0 TODO
   * @exception IOException TODO
   * @exception ClassNotFoundException TODO
   */
  private void readObject(ObjectInputStream value0)
    throws IOException, ClassNotFoundException
  {
    // TODO
  }

  /**
   * Sets the color to use for the border.
   * @param newColor - the new border color
   */
  public void setBorderSelectionColor(Color newColor)
  {
    this.borderSelectionColor = newColor;
  }

  /**
   * Returns the color the border is drawn.
   * @return Color
   */
  public Color getBorderSelectionColor()
  {
    return borderSelectionColor;
  }

  /**
   * Sets the font to edit with. null indicates the renderers 
   * font should be used. This will NOT override any font you have 
   * set in the editor the receiver was instantied with. If null for 
   * an editor was passed in, a default editor will be created that 
   * will pick up this font.
   * 
   * @param font - the editing Font
   */
  public void setFont(Font font)
  {
    if (font != null)
      this.font = font;
    else
      this.font = renderer.getFont();
  }

  /**
   * Gets the font used for editing.
   * 
   * @return the editing font
   */
  public Font getFont()
  {
    return font;
  }

  /**
   * Configures the editor. Passed onto the realEditor.
   * Sets an initial value for the editor. This will cause 
   * the editor to stopEditing and lose any partially edited value 
   * if the editor is editing when this method is called. 
   * Returns the component that should be added to the client's Component 
   * hierarchy. Once installed in the client's hierarchy this component will 
   * then be able to draw and receive user input. 
   * 
   * @param tree - the JTree that is asking the editor to edit; this parameter can be null
   * @param value - the value of the cell to be edited
   * @param isSelected - true is the cell is to be rendered with selection highlighting
   * @param expanded - true if the node is expanded
   * @param leaf - true if the node is a leaf node
   * @param row - the row index of the node being edited
   * 
   * @return the component for editing
   */
  public Component getTreeCellEditorComponent(JTree tree, Object value,
                                              boolean isSelected, boolean expanded,
                                              boolean leaf, int row)
  {
    if (realEditor == null)
      realEditor = createTreeCellEditor();

    return realEditor.getTreeCellEditorComponent(tree, value, isSelected,
                                                        expanded, leaf, row);
  }

  /**
   * Returns the value currently being edited (requests it from the
   * {@link realEditor}.
   * 
   * @return the value currently being edited
   */
  public Object getCellEditorValue()
  {
    return realEditor.getCellEditorValue();
  }
  
  /**
   * If the realEditor returns true to this message, prepareForEditing  
   * is messaged and true is returned.
   * 
   * @param event - the event the editor should use to consider whether to 
   * begin editing or not
   * @return true if editing can be started
   */
  public boolean isCellEditable(EventObject event)
  { 
    if (editingComponent == null)
        configureEditingComponent(tree, renderer, realEditor);
    
    if (editingComponent != null && realEditor.isCellEditable(event))
      {
        prepareForEditing();
        return true;
      }
    return false;
  }

  /**
   * Messages the realEditor for the return value.
   * 
   * @param event -
   *          the event the editor should use to start editing
   * @return true if the editor would like the editing cell to be selected;
   *         otherwise returns false
   */
  public boolean shouldSelectCell(EventObject event)
  {
    return true;
  }

  /**
   * If the realEditor will allow editing to stop, the realEditor
   * is removed and true is returned, otherwise false is returned.
   * @return true if editing was stopped; false otherwise
   */
  public boolean stopCellEditing()
  {
    if (editingComponent != null)
      {
        stopEditingTimer();
        tree.stopEditing();
        editingComponent = null;
        return true;
      }
    return false;
  }

  /**
   * Messages cancelCellEditing to the realEditor and removes it
   * from this instance.
   */
  public void cancelCellEditing()
  {
    if (editingComponent != null)
      {
        tree.cancelEditing();
        editingComponent = null;
      }
    stopEditingTimer();
  }
  
  /**
   * Stop the editing timer, if it is installed and running.
   */
  private void stopEditingTimer()
  {
    if (timer != null && timer.isRunning())
      timer.stop();
  }

  /**
   * Adds a <code>CellEditorListener</code> object to this editor.
   * 
   * @param listener
   *          the listener to add
   */
  public void addCellEditorListener(CellEditorListener listener)
  {
    realEditor.addCellEditorListener(listener);
  }

  /**
   * Removes a <code>CellEditorListener</code> object.
   *
   * @param listener the listener to remove
   */
  public void removeCellEditorListener(CellEditorListener listener)
  {
    realEditor.removeCellEditorListener(listener);
  }

  /**
   * Returns all added <code>CellEditorListener</code> objects to this editor.
   *
   * @return an array of listeners
   *
   * @since 1.4
   */
  public CellEditorListener[] getCellEditorListeners()
  {
    return (CellEditorListener[]) listenerList.getListeners(CellEditorListener.class);
  }

  /**
   * Resets lastPath.
   * 
   * @param e - the event that characterizes the change.
   */
  public void valueChanged(TreeSelectionEvent e)
  {
    tPath = lastPath;
    lastPath = e.getNewLeadSelectionPath();
    lastRow = tree.getRowForPath(lastPath);
    stopCellEditing();
  }
  
  /**
   * Messaged when the timer fires.
   * 
   * @param e the event that characterizes the action.
   */
  public void actionPerformed(ActionEvent e)
  {
  }

  /**
   * Sets the tree currently editing for. This is needed to add a selection
   * listener.
   * 
   * @param newTree -
   *          the new tree to be edited
   */
  protected void setTree(JTree newTree)
  {
    tree = newTree;
  }

  /**
   * Returns true if event is a MouseEvent and the click count is 1.
   * 
   * @param event - the event being studied
   * @return true if editing should start
   */
  protected boolean shouldStartEditingTimer(EventObject event)
  {
    if ((event instanceof MouseEvent) && 
        ((MouseEvent) event).getClickCount() == 1)
      return true;
    return false;
  }

  /**
   * Starts the editing timer (if one installed). 
   */
  protected void startEditingTimer()
  {
    if (timer != null)
      timer.start();
  }

  /**
   * Returns true if event is null, or it is a MouseEvent with 
   * a click count > 2 and inHitRegion returns true.
   * 
   * @param event - the event being studied
   * @return true if event is null, or it is a MouseEvent with 
   * a click count > 2 and inHitRegion returns true 
   */
  protected boolean canEditImmediately(EventObject event)
  {
    if (event == null || !(event instanceof MouseEvent) || (((MouseEvent) event).
        getClickCount() > 2 && inHitRegion(((MouseEvent) event).getX(), 
                                         ((MouseEvent) event).getY())))
      return true;
    return false;
  }

  /**
   * Returns true if the passed in location is a valid mouse location 
   * to start editing from. This is implemented to return false if x is
   * less than or equal to the width of the icon and icon 
   * gap displayed by the renderer. In other words this returns true if 
   * the user clicks over the text part displayed by the renderer, and 
   * false otherwise.
   * 
   * @param x - the x-coordinate of the point
   * @param y - the y-coordinate of the point
   * 
   * @return true if the passed in location is a valid mouse location
   */
  protected boolean inHitRegion(int x, int y)
  {
    Rectangle bounds = tree.getPathBounds(lastPath);
    
    return bounds.contains(x, y);
  }

  /**
   * determineOffset
   * @param tree -
   * @param value - 
   * @param isSelected - 
   * @param expanded - 
   * @param leaf - 
   * @param row - 
   */
  protected void determineOffset(JTree tree, Object value, boolean isSelected,
                                 boolean expanded, boolean leaf, int row)
  {
    renderer.getTreeCellRendererComponent(tree, value, isSelected, expanded, 
                                          leaf, row, true);
    Icon c = renderer.getIcon();
    if (c != null)
        offset = renderer.getIconTextGap() + c.getIconWidth();
    else
      offset = 0;
  }

  /**
   * Invoked just before editing is to start. Will add the 
   * editingComponent to the editingContainer.
   */
  protected void prepareForEditing()
  {
    editingContainer.removeAll();
    editingContainer.add(editingComponent);
  }

  /**
   * Creates the container to manage placement of editingComponent.
   * 
   * @return the container to manage the placement of the editingComponent.
   */
  protected Container createContainer()
  {
    return new DefaultTreeCellEditor.EditorContainer();
  }

  /**
   * This is invoked if a TreeCellEditor is not supplied in the constructor. 
   * It returns a TextField editor.
   * 
   * @return a new TextField editor
   */
  protected TreeCellEditor createTreeCellEditor()
  {
    DefaultCellEditor editor = new DefaultCellEditor(new DefaultTreeCellEditor.DefaultTextField(
                                  UIManager.getBorder("Tree.selectionBorder")));
    editor.addCellEditorListener(new RealEditorListener());
    editor.setClickCountToStart(CLICK_COUNT_TO_START);
    realEditor = editor;
    return editor;
  }
}
