/* BasicTableHeaderUI.java --
   Copyright (C) 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.plaf.basic;

import gnu.classpath.NotImplementedException;

import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;

import javax.swing.CellRendererPane;
import javax.swing.JComponent;
import javax.swing.LookAndFeel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.TableHeaderUI;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

/**
 * Basic pluggable look and feel interface for JTableHeader.
 */
public class BasicTableHeaderUI extends TableHeaderUI
{
  /**
   * The width of the space (in both direction) around the column boundary,
   * where mouse cursor changes shape into "resize"
   */
  static int COLUMN_BOUNDARY_TOLERANCE = 3;
  
  public static ComponentUI createUI(JComponent h)
  {
    return new BasicTableHeaderUI();
  }
  
  /**
   * The table header that is using this interface.
   */
  protected JTableHeader header;
  
  /**
   * The mouse input listener, responsible for mouse manipulations with
   * the table header.
   */
  protected MouseInputListener mouseInputListener;
  
  /**
   * Paint the header cell.
   */
  protected CellRendererPane rendererPane;
  
  /**
   * The header cell border.
   */
  private Border cellBorder;

  /**
   * Original mouse cursor prior to resizing.
   */
  private Cursor originalCursor;
  
  /**
   * If not null, one of the columns is currently being dragged.
   */
  Rectangle draggingHeaderRect;
  
  /**
   * Handles column movement and rearrangement by mouse. The same instance works
   * both as mouse listener and the mouse motion listner.
   */
  public class MouseInputHandler
      implements MouseInputListener
  {
    /**
     * If true, the cursor is being already shown in the alternative "resize"
     * shape. 
     */
    boolean showingResizeCursor;

    /**
     * The position, from where the cursor is dragged during resizing. Double
     * purpose field (absolute value during resizing and relative offset during
     * column dragging).
     */
    int draggingFrom = - 1;
    
    /**
     * The number of the column being dragged.
     */
    int draggingColumnNumber;    

    /**
     * The previous preferred width of the column.
     */
    int prevPrefWidth = - 1;

    /**
     * The timer to coalesce column resizing events.
     */
    Timer timer;

    /**
     * Returns without action, part of the MouseInputListener interface.
     */
    public void mouseClicked(MouseEvent e)
    {
      // Nothing to do.
    }

    /**
     * If being in the resizing mode, handle resizing.
     */
    public void mouseDragged(MouseEvent e)
    {
      TableColumn resizeIt = header.getResizingColumn();
      if (resizeIt != null && header.getResizingAllowed())
        {
          // The timer is intialised on demand.
          if (timer == null)
            {
              // The purpose of timer is to coalesce events. If the queue
              // is free, the repaint event is fired immediately.
              timer = new Timer(1, new ActionListener()
              {
                public void actionPerformed(ActionEvent e)
                {
                  header.getTable().doLayout();
                }
              });
              timer.setRepeats(false);
              timer.setCoalesce(true);
            }
          resizeIt.setPreferredWidth(prevPrefWidth + e.getX() - draggingFrom);
          timer.restart();
        }
      else if (draggingHeaderRect != null && header.getReorderingAllowed())
        {
          draggingHeaderRect.x = e.getX() + draggingFrom;
          header.repaint();
        }
    }

    /**
     * Returns without action, part of the MouseInputListener interface.
     */
    public void mouseEntered(MouseEvent e)
    {
      // Nothing to do.
    }

    /**
     * Reset drag information of the column resizing.
     */
    public void mouseExited(MouseEvent e)
    {
      // Nothing to do.
    }

    /**
     * Change the mouse cursor if the mouse if above the column boundary.
     */
    public void mouseMoved(MouseEvent e)
    {
      // When dragging, the functionality is handled by the mouseDragged.
      if (e.getButton() == 0 && header.getResizingAllowed())
        {
          TableColumnModel model = header.getColumnModel();
          int n = model.getColumnCount();
          if (n < 2)
            // It must be at least two columns to have at least one boundary.
            // Otherwise, nothing to do.
            return;

          boolean onBoundary = false;

          int x = e.getX();
          int a = x - COLUMN_BOUNDARY_TOLERANCE;
          int b = x + COLUMN_BOUNDARY_TOLERANCE;

          int p = 0;

          Scan: for (int i = 0; i < n - 1; i++)
            {
              p += model.getColumn(i).getWidth();

              if (p >= a && p <= b)
                {
                  TableColumn column = model.getColumn(i);
                  onBoundary = true;

                  draggingFrom = x;
                  prevPrefWidth = column.getWidth();
                  header.setResizingColumn(column);
                  break Scan;
                }
            }

          if (onBoundary != showingResizeCursor)
            {
              // Change the cursor shape, if needed.
              if (onBoundary)
                {

		  originalCursor = header.getCursor();
                  if (p < x)
                    header.setCursor(Cursor.getPredefinedCursor(
                        Cursor.W_RESIZE_CURSOR));
                  else
                    header.setCursor(Cursor.getPredefinedCursor(
                        Cursor.E_RESIZE_CURSOR));
                }
              else
                {
                  header.setCursor(originalCursor);
                  header.setResizingColumn(null);
                }

              showingResizeCursor = onBoundary;
            }
        }
    }

    /**
     * Starts the dragging/resizing procedure.
     */
    public void mousePressed(MouseEvent e)
    {
      if (header.getResizingAllowed())
        {
          TableColumn resizingColumn = header.getResizingColumn();
          if (resizingColumn != null)
            {
              resizingColumn.setPreferredWidth(resizingColumn.getWidth());
              return;
            }
        }

      if (header.getReorderingAllowed())
        {
          TableColumnModel model = header.getColumnModel();
          int n = model.getColumnCount();
          if (n < 2)
            // It must be at least two columns to change the column location.
            return;

          boolean onBoundary = false;

          int x = e.getX();
          int p = 0;
          int col = - 1;

          Scan: for (int i = 0; i < n; i++)
            {
              p += model.getColumn(i).getWidth();
              if (p > x)
                {
                  col = i;
                  break Scan;
                }
            }
          if (col < 0)
            return;

          TableColumn dragIt = model.getColumn(col);
          header.setDraggedColumn(dragIt);

          draggingFrom = (p - dragIt.getWidth()) - x;
          draggingHeaderRect = new Rectangle(header.getHeaderRect(col));
          draggingColumnNumber = col;
        }
    }

    /**
     * Set all column preferred width to the current width to prevend abrupt
     * width changes during the next resize.
     */
    public void mouseReleased(MouseEvent e)
    {
      if (header.getResizingColumn() != null && header.getResizingAllowed())
        endResizing();
      if (header.getDraggedColumn() != null &&  header.getReorderingAllowed())
        endDragging(e);
    }

    /**
     * Stop resizing session.
     */
    void endResizing()
    {
      TableColumnModel model = header.getColumnModel();
      int n = model.getColumnCount();
      if (n > 2)
        {
          TableColumn c;
          for (int i = 0; i < n; i++)
            {
              c = model.getColumn(i);
              c.setPreferredWidth(c.getWidth());
            }
        }
      header.setResizingColumn(null);
      showingResizeCursor = false;
      if (timer != null)
        timer.stop();
      header.setCursor(originalCursor);
    }

    /**
     * Stop the dragging session.
     * 
     * @param e the "mouse release" mouse event, needed to determing the final
     *          location for the dragged column.
     */
    void endDragging(MouseEvent e)
    {
      header.setDraggedColumn(null);
      draggingHeaderRect = null;

      TableColumnModel model = header.getColumnModel();

      // Find where have we dragged the column.
      int x = e.getX();
      int p = 0;
      
      int col = model.getColumnCount() - 1;
      int n = model.getColumnCount();

      // This loop does not find the column if the mouse if out of the 
      // right boundary of the table header. Then we make this column the
      // rightmost column.
      Scan: for (int i = 0; i < n; i++)
        {
          p += model.getColumn(i).getWidth();
          if (p > x)
            {
              col = i;
              break Scan;
            }
        }

      header.getTable().moveColumn(draggingColumnNumber, col);
    }
  }
 
  /**
   * Create and return the mouse input listener.
   * 
   * @return the mouse listener ({@link MouseInputHandler}, if not overridden.
   */
  protected MouseInputListener createMouseInputListener()
  {
    return new MouseInputHandler();
  }
  
  /**
   * Construct a new BasicTableHeaderUI, create mouse listeners.
   */
  public BasicTableHeaderUI()
  {
    mouseInputListener = createMouseInputListener();
  }

  protected void installDefaults()
  {
    LookAndFeel.installColorsAndFont(header, "TableHeader.background",
                                     "TableHeader.foreground",
                                     "TableHeader.font");
    cellBorder = UIManager.getBorder("TableHeader.cellBorder");
  }

  protected void installKeyboardActions()
    throws NotImplementedException
  {
    // TODO: Implement this properly.
  }

  /**
   * Add the mouse listener and the mouse motion listener to the table
   * header. The listeners support table column resizing and rearrangement
   * by mouse.
   */
  protected void installListeners()
  {
    header.addMouseListener(mouseInputListener);
    header.addMouseMotionListener(mouseInputListener);
  }

  public void installUI(JComponent c)
  {
    header = (JTableHeader) c;
    rendererPane = new CellRendererPane();
    installDefaults();
    installKeyboardActions();
    installListeners();
  }

  protected void uninstallDefaults()
  {
    header.setBackground(null);
    header.setForeground(null);
    header.setFont(null);
  }

  protected void uninstallKeyboardActions()
    throws NotImplementedException
  {
    // TODO: Implement this properly.
  }
  
  /**
   * Remove the previously installed listeners.
   */
  protected void uninstallListeners()
  {
    header.removeMouseListener(mouseInputListener);
    header.removeMouseMotionListener(mouseInputListener);
  }

  public void uninstallUI(JComponent c)
  {
    uninstallListeners();
    uninstallKeyboardActions();
    uninstallDefaults();
  }
  
  /**
   * Repaint the table header. 
   */
  public void paint(Graphics gfx, JComponent c)
  {
    TableColumnModel cmod = header.getColumnModel();
    int ncols = cmod.getColumnCount();
    if (ncols == 0)
      return;
    
    Rectangle clip = gfx.getClipBounds();
    TableCellRenderer defaultRend = header.getDefaultRenderer();

    for (int i = 0; i < ncols; ++i)
      {
        Rectangle bounds = header.getHeaderRect(i);
        if (bounds.intersects(clip))
          {
            Rectangle oldClip = gfx.getClipBounds();
            TableColumn col = cmod.getColumn(i);
            TableCellRenderer rend = col.getHeaderRenderer();
            if (rend == null)
              rend = defaultRend;
            Object val = col.getHeaderValue();
            Component comp = rend.getTableCellRendererComponent(header.getTable(),
                                                                val,
                                                                false, // isSelected
                                                                false, // isFocused
                                                                -1, i);
            // FIXME: The following settings should be performed in
            // rend.getTableCellRendererComponent().
            comp.setFont(header.getFont());
            comp.setBackground(header.getBackground());
            comp.setForeground(header.getForeground());
            if (comp instanceof JComponent)
              ((JComponent) comp).setBorder(cellBorder);
            rendererPane.paintComponent(gfx, comp, header, bounds.x, bounds.y,
                                        bounds.width, bounds.height);
          }
      }
    
    // This displays a running rectangle that is much simplier than the total
    // animation, as it is seen in Sun's application.
    // TODO animate the collumn dragging like in Sun's jre.
    if (draggingHeaderRect != null)
      {
        gfx.setColor(header.getForeground()); 
        gfx.drawRect(draggingHeaderRect.x, draggingHeaderRect.y + 2,
            draggingHeaderRect.width - 1, draggingHeaderRect.height - 6);
      }
  }
  
  /**
   * Get the preferred header size.
   * 
   * @param ignored unused
   * 
   * @return the preferred size of the associated header.
   */
  public Dimension getPreferredSize(JComponent ignored)
  {
    TableColumnModel cmod = header.getColumnModel();
    TableCellRenderer defaultRend = header.getDefaultRenderer();
    int ncols = cmod.getColumnCount();    
    Dimension ret = new Dimension(0, 0);
    int spacing = 0;

    if (header.getTable() != null 
        && header.getTable().getIntercellSpacing() != null)
      spacing = header.getTable().getIntercellSpacing().width;
    
    for (int i = 0; i < ncols; ++i)      
      {
        TableColumn col = cmod.getColumn(i);
        TableCellRenderer rend = col.getHeaderRenderer();
        if (rend == null)
          rend = defaultRend;
        Object val = col.getHeaderValue();
        Component comp = rend.getTableCellRendererComponent(header.getTable(),
                                                            val,
                                                            false, // isSelected
                                                            false, // isFocused
                                                            -1, i);
        comp.setFont(header.getFont());
        comp.setBackground(header.getBackground());
        comp.setForeground(header.getForeground());
        if (comp instanceof JComponent)
          ((JComponent) comp).setBorder(cellBorder);

        Dimension d = comp.getPreferredSize();
        ret.width += spacing;
        ret.height = Math.max(d.height, ret.height);        
      }
    ret.width = cmod.getTotalColumnWidth();
    return ret;
  }
  
  
}
