/* This is a component which contains two children, arranged either horizontally or
   vertically.  They are separated by a divider bar, which can be dragged to resize
   the children. */

/* Copyright (C) 2001,2003 by Peter Eastman

   This program 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 of the License, or (at your option) any later version.

   This program 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. */

package artofillusion.ui;

import java.awt.*;
import java.awt.event.*;

public class DividedPanel extends Panel implements MouseListener, MouseMotionListener
{
  Component child1, child2;
  float weight;
  boolean vertical, revalidate1, revalidate2, hide1, hide2;
  int offset, dividerPos;
  
  static final int BAR_WIDTH = 8;
  
  public DividedPanel(Component c1, Component c2, float weight1, float weight2, boolean isVertical)
  {
    child1 = c1;
    child2 = c2;
    if (weight1+weight2 == 0.0f)
      weight = 0.5f;
    else
      weight = weight1 / (weight1+weight2);
    vertical = isVertical;
    add(child1);
    add(child2);
    child1.setCursor(child1.getCursor());
    child2.setCursor(child2.getCursor());
    setCursor(Cursor.getPredefinedCursor(vertical ? Cursor.N_RESIZE_CURSOR : Cursor.E_RESIZE_CURSOR));
    addMouseListener(this);
    addMouseMotionListener(this);
  }
  
  // We do our own layout, rather than using a layout manager.
  
  public void doLayout()
  {
    Dimension dim = getSize(), prefSize1 = child1.getPreferredSize(), prefSize2 = child2.getPreferredSize();
    Rectangle bounds1 = new Rectangle(), bounds2 = new Rectangle();
    
    if (hide1)
      {
        bounds1.x = bounds1.y = bounds1.width = bounds1.height = 0;
        bounds2.x = bounds2.y = 0;
        bounds2.width = dim.width;
        bounds2.height = dim.height;
      }
    else if (hide2)
      {
        bounds2.x = bounds2.y = bounds2.width = bounds2.height = 0;
        bounds1.x = bounds1.y = 0;
        bounds1.width = dim.width;
        bounds1.height = dim.height;
      }
    else if (vertical)
      {
        int available = dim.height-prefSize1.height-prefSize2.height-BAR_WIDTH;
        dividerPos = (int) (prefSize1.height+available*weight);
        bounds1.x = bounds2.x = 0;
        bounds1.width = bounds2.width = dim.width;
        bounds1.y = 0;
        bounds1.height = dividerPos;
        bounds2.y = bounds1.height+BAR_WIDTH;
        bounds2.height = dim.height-bounds2.y;
      }
    else
      {
        int available = dim.width-prefSize1.width-prefSize2.width-BAR_WIDTH;
        dividerPos = (int) (prefSize1.width+available*weight);
        bounds1.y = bounds2.y = 0;
        bounds1.height = bounds2.height = dim.height;
        bounds1.x = 0;
        bounds1.width = dividerPos;
        bounds2.x = bounds1.width+BAR_WIDTH;
        bounds2.width = dim.width-bounds2.x;
      }
    child1.setBounds(bounds1);
    child2.setBounds(bounds2);
  }

  /* Set whether each component should be visible. */
  
  public void setHidden(boolean hide1, boolean hide2)
  {
    this.hide1 = hide1;
    this.hide2 = hide2;
    doLayout();
    child1.validate();
    child2.validate();
  }

  /* Set whether each component should be continuously revalidated as the divider is moved. */
  
  public void setLiveValidate(boolean validate1, boolean validate2)
  {
    revalidate1 = validate1;
    revalidate2 = validate2;
  }

  public void mousePressed(MouseEvent ev)
  {
    if (vertical)
      offset = ev.getY()-child1.getSize().height;
    else
      offset = ev.getX()-child1.getSize().width;
  }

  public void mouseReleased(MouseEvent ev)
  {
    child1.validate();
    child2.validate();
  }

  public void mouseClicked(MouseEvent ev)
  {
  }

  public void mouseEntered(MouseEvent ev)
  {
  }

  public void mouseExited(MouseEvent ev)
  {
  }

  public void mouseMoved(MouseEvent ev)
  {
  }
  
  public void mouseDragged(MouseEvent ev)
  {
    Rectangle bounds1 = child1.getBounds(), bounds2 = child2.getBounds();
    Dimension dim = getSize();
    Point pos = ev.getPoint();
    
    if (vertical)
      {
        if (pos.y < 0)
          pos.y = 0;
        if (pos.y > (dim.height-BAR_WIDTH))
          pos.y = dim.height-BAR_WIDTH;
        bounds1.height = pos.y-offset;
        bounds2.y = bounds1.height+BAR_WIDTH;
        bounds2.height = dim.height-bounds2.y;
        dividerPos = bounds1.height;
      }
    else
      {
        if (pos.x < 0)
          pos.x = 0;
        if (pos.x > (dim.width-BAR_WIDTH))
          pos.x = dim.width-BAR_WIDTH;
        bounds1.width = pos.x-offset;
        bounds2.x = bounds1.width+BAR_WIDTH;
        bounds2.width = dim.width-bounds2.x;
        dividerPos = bounds1.width;
      }
    child1.setBounds(bounds1);
    child2.setBounds(bounds2);
    if (revalidate1)
      child1.validate();
    if (revalidate2)
      child2.validate();
    repaint();
  }
}