/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.xsd.ui.internal.gef.util.figures;

import java.util.Iterator;
import java.util.List;

import org.eclipse.draw2d.AbstractLayout;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;


public class FillLayout extends AbstractLayout
{         
  protected boolean isHorizontal = false;                    
  protected int spacing = 0;
  public Dimension min;

  public FillLayout(){}     
  
  public FillLayout(int spacing)
  { 
    this.spacing = spacing; 
  }
  
  public void setHorizontal(boolean isHorizontal)
  {
   this.isHorizontal = isHorizontal;
  }
  
  /**
   * Calculates and returns the preferred size of the input container.
   * This is the size of the largest child of the container, as all
   * other children fit into this size.
   *
   * @param figure  Container figure for which preferred size is required.
   * @return  The preferred size of the input figure.
   */

  protected Dimension calculatePreferredSize(IFigure figure, int width, int height)
  {	                 
    Dimension d = calculatePreferredClientAreaSize(figure);
  	d.expand(figure.getInsets().getWidth(),
  	         figure.getInsets().getHeight());
  	d.union(getBorderPreferredSize(figure));
  	return d;
  } 
  
  protected Dimension calculatePreferredClientAreaSize(IFigure figure)
  {
    Dimension d = new Dimension();
  	List children = figure.getChildren(); 
  
  
  	for (Iterator i = children.iterator(); i.hasNext(); )
    {
  		IFigure child = (IFigure)i.next();
      Dimension childSize = child.getPreferredSize();
  
      if (isHorizontal)
      {
        d.width += childSize.width;
        d.height = Math.max(childSize.height, d.height);
      }
      else
      {
        d.height += childSize.height;
        d.width = Math.max(childSize.width, d.width);
      }
  	}	 
  
                     
    int childrenSize = children.size();       
    if (childrenSize > 0)
    {
      if (isHorizontal)
      {
        d.width += spacing * (childrenSize - 1); 
      }
      else
      {
        d.height += spacing * (childrenSize - 1);  
      }
    }       
      
    if (min != null)
    {
      d.width = Math.max(d.width, min.width);
      d.height = Math.max(d.height, min.height);
    }
    return d;
  }
  
  /*
   * Returns the minimum size required by the input container.
   * This is the size of the largest child of the container, as all
   * other children fit into this size.
   */
  public Dimension getMinimumSize(IFigure figure, int width, int height)
  {
  	Dimension d = new Dimension();
  	List children = figure.getChildren();
  	IFigure child;

  	for (int i=0; i < children.size(); i++)
    {
  		child = (IFigure)children.get(i);
  		d.union(child.getMinimumSize());
  	}
  	d.expand(figure.getInsets().getWidth(),
  	         figure.getInsets().getHeight());
  	return d;
  }
  
  public Dimension getPreferredSize(IFigure figure, int width, int height)
  {
  	return calculatePreferredSize(figure, width, height);
  }
  
  /*
   * Lays out the children on top of each other with
   * their sizes equal to that of the available
   * paintable area of the input container figure.
   */
  public void layout(IFigure figure)
  {                         
    Dimension	preferredSize = calculatePreferredClientAreaSize(figure);
  	Rectangle r = figure.getClientArea().getCopy();
  	List children = figure.getChildren();

    int nChildren = children.size();                                                          
    int extraHorizontalSpace = r.width - preferredSize.width;

  	for (Iterator i = children.iterator(); i.hasNext(); )
    {
  		IFigure child = (IFigure)i.next();
      Dimension preferredChildSize = child.getPreferredSize();
         
      if (isHorizontal)
      {                       
        int w = preferredChildSize.width + (extraHorizontalSpace / nChildren);
  		  child.setBounds(new Rectangle(r.x, r.y, w, Math.max(preferredSize.height, r.height)));
        r.x += w + spacing;
      }
      else
      {
  		  child.setBounds(new Rectangle(r.x, r.y, Math.max(preferredSize.width, r.width), preferredChildSize.height));
        r.y += preferredChildSize.height + spacing;
      }
  	}
  }   
}