/* $Id$
 *
 * Copyright (c) 1999 Xenonsoft Limited. All Rights Reserved.
 *
 * This software is protected by copyright. You are hereby notified from
 * now by reading this message. This software is also the confidential 
 * and proprietary information of Xenonsoft Limited.  ("Confidential
 * Information"). 
 *
 * This software is distributed under the Xenonsoft Public end user 
 * License ("XPeL"), where the machine-readable source code is provided 
 * under the "Open Source" model.
 * For more information, please read the file "LICENSE-XPL.txt" 
 */

/* $Id$
 *
 * Copyright (c) 1999 Xenonsoft Limited. All Rights Reserved.
 *
 * This software is protected by copyright. You are hereby notified from
 * now by reading this message. This software is also the confidential 
 * and proprietary information of Xenonsoft Limited.  ("Confidential
 * Information"). 
 *
 * This software is distributed under the Xenonsoft Public end user 
 * License ("XPeL"), where the machine-readable source code is provided 
 * under the "Open Source" model.
 * For more information, please read the file "LICENSE-XPL.txt" 
 */

// 
//  DESCRIPTION
//  
//  Peter Pilgrim
//  Mon Apr 19 21:13:28 BST 1999
//  
//  RCS HEADER ``VerticalLayout.java''
//  
//  $Author$
//  $Date$
//  $Source$
//  $Revision$    $State$    $Locker$
// 

package xenon.soundkit.gui;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Insets;
import java.awt.LayoutManager;


/**
 * A custom AWT <B>vertical</B> layout manager that lays out
 * from top to bottom
 * <P>
 *
 */
public class VerticalLayout implements LayoutManager {
    
    /** Orient the layout to the top of the container */
    public final static int	TOP=1;
    /** Orient the layout centrally in the container */
    public final static int	CENTER=2;
    /** Orient the layout to the bottom of the container */
    public final static int	BOTTOM=3;

    protected int	orientation;    
    protected int	hgap;
    protected int	vgap;

    /** 
     * Creates a new vertical layout of component
     * which is centered inside the container
     * with an horizontal gap size of 3 pixel
     * and a vertical gap size of 3 pixel
     */
    public VerticalLayout()
    {
	this( CENTER );
    }
    
    /** 
     * Creates a new vertical layout of component
     * with an horizontal gap size of 3 pixel
     * and a vertical gap size of 3 pixel
     * @param orientation the orientation which must be TOP, CENTER, or BOTTOM
     */
    public VerticalLayout( int orientation )
    {
	this( orientation, 3,3);
    }
    
    /** 
     * Creates a new vertical layout 
     *
     * @param orientation the orientation which must be TOP, CENTER, or BOTTOM
     * @param hgap the horizontal gap size between child component
     * @param vgap the vertical gap size between child component
     */
    public VerticalLayout( int orientation, int hgap, int vgap )
    {
	if ( orientation != TOP && orientation != CENTER &&
	     orientation != BOTTOM )
	    throw new IllegalArgumentException( "illegal orientation" );

	this.orientation = orientation;
	this.hgap = hgap;
	this.vgap = vgap;
    }
    
    /**
       Adds the specified component with the specified name to the layout. 

       Parameters: 
              name - the component name 
              comp - the component to be added 

    */
    public void addLayoutComponent(String name, Component comp)
    {
	/* Does nothing */
    }
    

    /**
       Removes the specified component from the layout. 
       
       Parameters: 
              comp - the component ot be removed 
    */
    public void removeLayoutComponent(Component comp)
    {
	/* Does nothing */
    }

    /**

       Calculates the preferred size dimensions for the specified
       panel given the components in the specified parent container.

       Parameters: 
              parent - the component to be laid out 
       See Also: 
              minimumLayoutSize 

    */
    public Dimension preferredLayoutSize(Container parent)
    {
	// System.out.println( getClass().getName()+".preferredLayoutSize()" );
	
	Insets		parentInsets = parent.getInsets();
	Component	kidList[] = parent.getComponents();
	Dimension	prefSize = new Dimension(0,0);
	int		j;
	
	prefSize.height = vgap;
	for (j=0; j<kidList.length; ++j) {
	    Component kid = kidList[j];
	    if ( kid.isVisible() ) {
		Dimension kidSize = kid.getPreferredSize();
		if ( prefSize.width < kidSize.width )
		    prefSize.width = kidSize.width;
		prefSize.height += kidSize.height + vgap;
		// System.out.println( "["+j+"]  w:"+kidSize.width+" h:"+kidSize.height );
	    }
	}
	
	prefSize.width += parentInsets.left + parentInsets.right;
	prefSize.height += parentInsets.top + parentInsets.bottom;

	// System.out.println("prefSize w:"+prefSize.width+", h:"+prefSize.height );
	
	return (prefSize);
    }

    /** 
       Calculates the minimum size dimensions for the specified panel
       given the components in the specified parent container.

       Parameters: 
              parent - the component to be laid out 
       See Also: 
              preferredLayoutSize 
    */
    public Dimension minimumLayoutSize(Container parent)
    {
	// System.out.println( getClass().getName()+".minimumLayoutSize()" );

	Insets		parentInsets = parent.getInsets();
	Component	kidList[] = parent.getComponents();
	Dimension	minSize = new Dimension();
	int		j;
	
	minSize.height = vgap;
	for (j=0; j<kidList.length; ++j) {
	    Component kid = kidList[j];
	    if ( kid.isVisible() ) {
		Dimension kidSize = kid.getMinimumSize();
		if ( minSize.width < kidSize.width )
		    minSize.width = kidSize.width;
		minSize.height += kidSize.height + vgap;
		// System.out.println( "["+j+"]  w:"+kidSize.width+" h:"+kidSize.height );
	    }
	}
	
	minSize.width += parentInsets.left + parentInsets.right;
	minSize.height += parentInsets.top + parentInsets.bottom;

	// System.out.println("minSize w:"+minSize.width+", h:"+minSize.height );

	return (minSize);
    }
    
    /**
	
       Lays out the container in the specified panel. 

       Parameters: 
              parent - the component which needs to be laid out
    */
    public void layoutContainer(Container parent)
    {
	// System.out.println( getClass().getName()+".layoutContainer()" );

	Insets		parentInsets = parent.getInsets();
	Component	kidList[] = parent.getComponents();
	int		xpos, ypos;	
	Dimension	prefSize = new Dimension();
	Dimension	currSize = parent.getSize();
	Dimension	boundSize = new Dimension();
	int		j;

	// Complete residual width
	int resWidth = currSize.width - 
	    (parentInsets.left + parentInsets.right);
	xpos = parentInsets.left + hgap;
	ypos = parentInsets.top  + vgap;

	boundSize.width = currSize.width - (parentInsets.left + parentInsets.right);
	boundSize.height = currSize.height - (parentInsets.top + parentInsets.bottom);

	for (j=0; j<kidList.length; ++j) {
	    Component kid = kidList[j];
	    if ( kid.isVisible() ) {
		Dimension kidSize = kid.getPreferredSize();
		if ( prefSize.width < kidSize.width )
		    prefSize.width = kidSize.width;
		prefSize.height += kidSize.height + vgap;
	    }
	}

	xpos = parentInsets.left + hgap;
	switch (orientation) {
	  case TOP:
	      ypos = parentInsets.top  + vgap;
	      break;
	  case CENTER:
	      ypos = (boundSize.height - prefSize.height) / 2;
	      break;
	  case BOTTOM:
	      ypos = boundSize.height - prefSize.height;
	      break;
	}

	for (j=0; j<kidList.length; ++j) {
	    Component kid = kidList[j];
	    if ( kid.isVisible() ) {
		Dimension kidSize = kid.getPreferredSize();
		kidList[j].setBounds( xpos, ypos, resWidth, kidSize.height );
		// System.out.println( "["+j+"]  x:"+xpos+" y:"+ypos+
		// 		       " resW:"+resWidth+ 
		// 		       " w:"+kidSize.width+" h:"+kidSize.height );
		ypos += kidSize.height + vgap;
	    }
	}
    }
}

// fini
