/*******************************************************************************
 * Copyright (c) 2001, 2006 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.wsdl.ui.internal.asd.design.layouts;

import java.util.HashMap;
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 RowLayout extends AbstractLayout
{
  // layout is associated with a parent context
  // any layout manager under the parent context is connected
  // column rows are maintained accross container boundaries  
  protected ColumnData columnData;
  protected HashMap figureToContstraintMap = new HashMap();
  
  public RowLayout()
  {
    super();
  }
  

  // this method computes the minimum size required to display the figures
  //
  private Dimension calculateChildrenSize(IFigure container, List children, int wHint, int hHint, boolean preferred)
  {
    Dimension childSize;
    IFigure child;
    int height = 0;
    int width = 0;
    
    //IRowFigure figure = (IRowFigure)container;
    
    // for each cell in the row
    //
    for (int i = 0; i < children.size(); i++)
    {
      child = (IFigure) children.get(i);
      String columnIdenifier = (String)getConstraint(child);
             
      // first we compute the child size without regard for columnData
      //
      childSize = child.getPreferredSize(wHint, hHint);// : child.getMinimumSize(wHint, hHint);
        
      // now that the columnData has been populated we can consider if the row needs to be larger
      //
      int effectiveWidth = childSize.width;
      if (columnIdenifier != null)
      {  
        columnData.stretchColumnWidthIfNeeded(columnIdenifier, childSize.width);
        effectiveWidth = columnData.getColumnWidth(columnIdenifier);
      }                       
      height = Math.max(childSize.height, height);
      width += effectiveWidth;
    }  
    return new Dimension(width, height);
  }
  
  
  
  protected Dimension calculatePreferredSize(IFigure container, int wHint, int hHint)
  {    
    List children = container.getChildren();
    Dimension prefSize = calculateChildrenSize(container, children, wHint, hHint, true);
    //System.out.println("preferredSize=" + prefSize);
    return prefSize;
  }

  public void layout(IFigure parent)
  {
    // layout a table with the columns aligned      
    //IRowFigure rowFigure = (IRowFigure)parent;    
    Rectangle clientArea = parent.getClientArea();   
    List children = parent.getChildren();
    Rectangle r = new Rectangle();
    r.x = clientArea.x;
    r.y = clientArea.y;
    r.height = clientArea.height;
    
    int childrenSize = children.size();
    Rectangle[] bounds = new Rectangle[childrenSize];
    
    // for each cell in the row
    //
    int requiredWidth = 0;
    int totalColumnWeight = 0;
    for (int i = 0; i < childrenSize; i++)
    {
      IFigure child = (IFigure) children.get(i);
      //String columnIdenifier = figure.getColumnIdentifier(child);             
      // first we compute the child size without regard for columnData
      //
      Dimension childSize = child.getPreferredSize(-1, -1);
      
      int columnWidth = -1;
      //String columnIdentifier = rowFigure.getColumnIdentifier(child);
      String columnIdentifier = (String)getConstraint(child);
      if (columnIdentifier != null)
      {
        //columnData.stretchColumnWidthIfNeeded(columnIdentifier, childSize.width);        
        columnWidth = columnData.getColumnWidth(columnIdentifier);
        totalColumnWeight += columnData.getColumnWeight(columnIdentifier);
        //System.out.println("columnWidth(" + columnIdentifier + ")=" + columnWidth);        
      }  
      r.width = Math.max(childSize.width, columnWidth);
      requiredWidth += r.width;
      bounds[i] = new Rectangle(r);      
      r.x += r.width;
    }          
    if (totalColumnWeight < 1)
    {
      totalColumnWeight = 1;
    }
    //System.out.println("clientArea.width=" + clientArea.width + ", " + r.x);
    int extraWidth = Math.max(clientArea.width - requiredWidth, 0);    
    //System.out.println("extraWidth=" + extraWidth + " totalColumnWeight=" + totalColumnWeight);  
    int extraWidthAllocated = 0;
    for (int i = 0; i < childrenSize; i++)
    {
      IFigure child = (IFigure) children.get(i);      
      Rectangle b = bounds[i];    
      if (extraWidth > 0)
      {  
        String columnIdentifier = (String)getConstraint(child);
        if (columnIdentifier != null)
        {        
          int weight = columnData.getColumnWeight(columnIdentifier);
          float fraction = (float)weight / (float)totalColumnWeight;
          int extraWidthForChild = (int)(extraWidth * fraction);
          //System.out.println("extraWidthForChild(" + fraction + ")=" + extraWidthForChild);        
          b.width += extraWidthForChild;        
          b.x += extraWidthAllocated;
          extraWidthAllocated += extraWidthForChild;
        }  
        else
        {
          b.x += extraWidthAllocated;
        }
      }
      child.setBounds(new Rectangle(b));  
    }  
  }

  public ColumnData getColumnData()
  {
    return columnData;
  }

  public void setColumnData(ColumnData columnData)
  {
    this.columnData = columnData;
  }    
  
  public Object getConstraint(IFigure child)
  {
    return figureToContstraintMap.get(child);
  }
  
  public void setConstraint(IFigure child, Object constraint)
  {
    figureToContstraintMap.put(child, constraint);
  }
  
  public void invalidate()
  {
    //figureToContstraintMap.clear();
    //this.columnData.clearColumnWidths();
    super.invalidate();
    //System.out.println("invalidate");    
  }
}
