/* 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.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.Timer;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.CellEditorListener;
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
{
  /**
   * 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()
    {
      setLayout(null);
    }

    /**
     * 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.
    }
   
    /**
     * 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)
    {
      // Paint editing icon.
      if (editingIcon != null)
        {
          // From the previous version, the left margin is taken as half
          // of the icon width.
          int y = Math.max(0, (getHeight() - editingIcon.getIconHeight()) / 2);
          editingIcon.paintIcon(this, g, 0, y);
        }
      // Paint border.
      Color c = getBorderSelectionColor();
      if (c != null)
        {
          g.setColor(c);
          g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
        }
      super.paint(g);
    }

    /**
     * Lays out this Container, moving the editor component to the left
     * (leaving place for the icon).
     */
    public void doLayout()
    {
      if (editingComponent != null)
        {
          editingComponent.getPreferredSize();
          editingComponent.setBounds(offset, 0, getWidth() - offset,
                                     getHeight());
        }
      }

    public Dimension getPreferredSize()
    {
      Dimension dim;
      if (editingComponent != null)
        {
          dim = editingComponent.getPreferredSize();
          dim.width += offset + 5;
          if (renderer != null)
            {
              Dimension r = renderer.getPreferredSize();
              dim.height = Math.max(dim.height, r.height);
            }
          if (editingIcon != null)
            dim.height = Math.max(dim.height, editingIcon.getIconHeight());
          dim.width = Math.max(100, dim.width);
        }
      else
        dim = new Dimension(0, 0);
      return dim;
    }
  }

  /**
   * 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()
    {
      Dimension size = super.getPreferredSize();
      if (renderer != null && DefaultTreeCellEditor.this.getFont() == null)
        {
          size.height = renderer.getPreferredSize().height;
        }
      return renderer.getPreferredSize();
    }
  }
  
  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;
      
  /**
   * 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)
  {
    this.renderer = renderer;
    realEditor = editor;
    if (realEditor == null)
      realEditor = createTreeCellEditor();
    editingContainer = createContainer();
    setTree(tree);
    Color c = UIManager.getColor("Tree.editorBorderSelectionColor");
    setBorderSelectionColor(c);
  }
  
  /**
   * 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)
  {
    setTree(tree);
    lastRow = row;
    determineOffset(tree, value, isSelected, expanded, leaf, row);
    if (editingComponent != null)
      editingContainer.remove(editingComponent);

    editingComponent = realEditor.getTreeCellEditorComponent(tree, value,
                                                             isSelected,
                                                             expanded, leaf,
                                                             row);
    Font f = getFont();
    if (f == null)
      {
        if (renderer != null)
          f = renderer.getFont();
        if (f == null)
          f = tree.getFont();
      }
    editingContainer.setFont(f);
    prepareForEditing();
    return editingContainer;
  }

  /**
   * 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)
  {
    boolean ret = false;
    boolean ed = false;
    if (event != null)
      {
        if (event.getSource() instanceof JTree)
          {
            setTree((JTree) event.getSource());
            if (event instanceof MouseEvent)
              {
                MouseEvent me = (MouseEvent) event;
                TreePath path = tree.getPathForLocation(me.getX(), me.getY());
                ed = lastPath != null && path != null && lastPath.equals(path);
                if (path != null)
                  {
                    lastRow = tree.getRowForPath(path);
                    Object val = path.getLastPathComponent();
                    boolean isSelected = tree.isRowSelected(lastRow);
                    boolean isExpanded = tree.isExpanded(path);
                    TreeModel m = tree.getModel();
                    boolean isLeaf = m.isLeaf(val);
                    determineOffset(tree, val, isSelected, isExpanded, isLeaf,
                                    lastRow);
                  }
              }
          }
      }
    if (! realEditor.isCellEditable(event))
      ret = false;
    else 
      {
        if (canEditImmediately(event))
          ret = true;
        else if (ed && shouldStartEditingTimer(event))
          startEditingTimer();
        else if (timer != null && timer.isRunning())
          timer.stop();
      }
    if (ret)
      prepareForEditing();
    return ret;
        
  }

  /**
   * 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()
  {
    boolean ret = false;
    if (realEditor.stopCellEditing())
      {
        finish();
        ret = true;
      }
    return ret;
  }

  /**
   * Messages cancelCellEditing to the realEditor and removes it
   * from this instance.
   */
  public void cancelCellEditing()
  {
    realEditor.cancelCellEditing();
    finish();
  }

  private void finish()
  {
    if (editingComponent != null)
      editingContainer.remove(editingComponent);
    editingComponent = null;
  }

  /**
   * 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)
  {
    if (tree != null)
      {
        if (tree.getSelectionCount() == 1)
          lastPath = tree.getSelectionPath();
        else
          lastPath = null;
      }
    // TODO: We really should do the following here, but can't due
    // to buggy DefaultTreeSelectionModel. This selection model
    // should only fire if the selection actually changes.
//    if (timer != null)
//      timer.stop();
  }
  
  /**
   * Messaged when the timer fires.
   * 
   * @param e the event that characterizes the action.
   */
  public void actionPerformed(ActionEvent e)
  {
    if (tree != null && lastPath != null)
      tree.startEditingAtPath(lastPath);
  }

  /**
   * 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)
  {
    if (tree != newTree)
      {
        if (tree != null)
          tree.removeTreeSelectionListener(this);
        tree = newTree;
        if (tree != null)
          tree.addTreeSelectionListener(this);

        if (timer != null)
          timer.stop();
      }
  }

  /**
   * 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)
  {
    boolean ret = false;
    if (event instanceof MouseEvent)
      {
        MouseEvent me = (MouseEvent) event;
        ret = SwingUtilities.isLeftMouseButton(me) && me.getClickCount() == 1
              && inHitRegion(me.getX(), me.getY());
      }
    return ret;
  }

  /**
   * Starts the editing timer (if one installed). 
   */
  protected void startEditingTimer()
  {
    if (timer == null)
      {
        timer = new Timer(1200, this);
        timer.setRepeats(false);
      }
    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)
  {
    if (renderer != null)
      {
        if (leaf)
          editingIcon = renderer.getLeafIcon();
        else if (expanded)
          editingIcon = renderer.getOpenIcon();
        else
          editingIcon = renderer.getClosedIcon();
        if (editingIcon != null)
          offset = renderer.getIconTextGap() + editingIcon.getIconWidth();
        else
          offset = renderer.getIconTextGap();
      }
    else
      {
        editingIcon = null;
        offset = 0;
      }
  }

  /**
   * Invoked just before editing is to start. Will add the 
   * editingComponent to the editingContainer.
   */
  protected void prepareForEditing()
  {
    if (editingComponent != null)
      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()
  {
    Border border = UIManager.getBorder("Tree.editorBorder");
    JTextField tf = new DefaultTreeCellEditor.DefaultTextField(border);
    DefaultCellEditor editor = new DefaultCellEditor(tf);
    editor.setClickCountToStart(1);
    realEditor = editor;
    return editor;
  }
}
