/*
 * TableLayout.java
 *
 * Created on 28. prosinec 2000, 16:03
 */

package timetable.gui;

import java.awt.*;
import java.util.Vector;
/**
 *
 * @author  Administrator
 * @version 
 */
public class TableLayout implements java.awt.LayoutManager2 {
    private Vector components,sizes;
    private int rows, cols;
    private int vgap, hgap;
    private boolean resizable = false;
    

    public TableLayout() {
        this(1,1,0,0);
    }
    
    public TableLayout(int rows,int cols) {
        this(rows,cols,0,0);
    }
    
    /** Creates new TableLayout */
    public TableLayout(int rows,int cols, int hgap, int vgap) {
	if ((rows == 0) || (cols == 0)) {
	    throw new IllegalArgumentException("rows or cols cannot be zero");
	}
	this.rows = rows;
	this.cols = cols;
        this.components = new Vector();
        this.sizes = new Vector();
	this.hgap = hgap;
	this.vgap = vgap;
    }

    public int getRows() {
	return rows;
    }
    
    public void setRows(int rows) {
	if ((rows == 0) || (cols == 0)) {
	    throw new IllegalArgumentException("rows or cols cannot be zero");
	}
        this.rows=rows;
    }

    public int getColumns() {
	return cols;
    }

    public void setColumns(int cols) {
	if ((rows == 0) || (cols == 0)) {
	    throw new IllegalArgumentException("rows or cols cannot be zero");
	}
        this.cols=cols;
    }

    public int getHgap() {
	return hgap;
    }

    public int getVgap() {
	return vgap;
    }
    
    public void setResizable(boolean resizable) {
        this.resizable=resizable;
    }
    
    public boolean getResizable() {
        return resizable;
    }
    
    public Component getComponentAt(int row, int col) {
        for (int i=0;i<sizes.size();i++) {
            Rectangle rect = (Rectangle) sizes.get(i);
            if ((rect.x>=col && col<rect.x+rect.width) &&
                (rect.y>=row && row<rect.y+rect.height)) return (Component)components.get(i);
        }
        return null;
    }
    
    public int getComponentCount() {
        return components.size();
    }
    
    public Component getComponent(int i) {
        return (Component)components.get(i);
    }
    
    public void addLayoutComponent(java.lang.String str,final java.awt.Component comp) {
//        System.out.println("Add component "+comp);
        addLayoutComponent(comp,null);
    }

    public void addLayoutComponent(Component comp, Object constraints) {
        Rectangle rect = null;
        if (constraints instanceof java.awt.Rectangle) {
            rect = (Rectangle) constraints;
        } else if (constraints instanceof java.awt.Dimension) {
            int i=0;
            while (getComponentAt(i/cols,i%cols)!=null && i<rows*cols) i++;
            if (i>=rows*cols) return;
            Dimension d = (Dimension)constraints;
            rect = new Rectangle(i%cols,i/cols,d.width,d.height);
        } else {
            int i=0;
            while (getComponentAt(i/cols,i%cols)!=null && i<rows*cols) i++;
            if (i>=rows*cols) return;
            rect = new Rectangle(i%cols,i/cols,1,1);
        }
        if (rect==null) return;
        components.add(comp);
        sizes.add(rect);
    }

    public void removeLayoutComponent(final java.awt.Component component) {
        if (components.indexOf(component)>=0) {
            sizes.remove(components.indexOf(component));
            components.remove(components.indexOf(component));
        }
    }
        
    public void layoutContainer(Container parent) {
//      System.out.println("layoutContainer("+parent+")");
      synchronized (parent.getTreeLock()) {
	Insets insets = parent.getInsets();
	int ncomponents = parent.getComponentCount();
	int nrows = rows;
	int ncols = cols;

	if (ncomponents == 0) return;
        
	int width = parent.getWidth() - (insets.left + insets.right);
	int height = parent.getHeight() - (insets.top + insets.bottom);
        
	width = (width - (ncols - 1) * hgap) ;
	height = (height - (nrows - 1) * vgap) ;
        
        int[] w = new int[cols]; for (int i=0;i<w.length;i++) w[i]=0;
	int[] h = new int[rows]; for (int i=0;i<h.length;i++) h[i]=0;
        
        for (int i=0;i<components.size();i++) {
            Rectangle rect = (Rectangle)sizes.get(i);
            Component comp = (Component)components.get(i);
	    Dimension d = comp.getPreferredSize();
            int dw = d.width/rect.width;
            int dh = d.height/rect.height;
            for (int c=rect.x;c<rect.x+rect.width;c++)
                for (int r=rect.y;r<rect.y+rect.height;r++) {
                    w[c]=max2(w[c],dw);
                    h[r]=max2(h[r],dh);
                }
        }
        
        int maxw=0;for (int i=0;i<w.length;i++) {maxw+=w[i]; if (i>0) w[i]+=w[i-1]+i*hgap;}
        int maxh=0;for (int i=0;i<h.length;i++) {maxh+=h[i]; if (i>0) h[i]+=h[i-1]+i*vgap;}
        
        if (resizable) {
            double wMx=((double)width)/maxw;
            double hMx=((double)height)/maxh;
            for (int i=0;i<components.size();i++) {
                Rectangle rect = (Rectangle)sizes.get(i);
                Component comp = (Component)components.get(i);
                comp.setBounds(insets.left+((int)(wMx*(rect.x>0?w[rect.x-1]:0)+0.5)),
                               insets.top +((int)(hMx*(rect.y>0?h[rect.y-1]:0)+0.5)),
                               (int)(wMx*comp.getPreferredSize().width+0.5),
                               (int)(hMx*comp.getPreferredSize().height+0.5));
            }
        } else {
            for (int i=0;i<components.size();i++) {
                Rectangle rect = (Rectangle)sizes.get(i);
                Component comp = (Component)components.get(i);
                comp.setBounds(insets.left+(rect.x>0?w[rect.x-1]:0),
                               insets.top +(rect.y>0?h[rect.y-1]:0),
                               comp.getPreferredSize().width,
                               comp.getPreferredSize().height);
            }
        }
        
      }
    }
    
    private int min2(int a,int b) { return a<b?a:b;}
    private int max2(int a,int b) { return a>b?a:b;}
    
    public Dimension minimumLayoutSize(Container parent) {
//      System.out.println("minimumLayoutSize("+parent+")");
      synchronized (parent.getTreeLock()) {
        Insets insets = parent.getInsets();
	int ncomponents = parent.getComponentCount();

        int[] w = new int[cols]; for (int i=0;i<w.length;i++) w[i]=0;
	int[] h = new int[rows]; for (int i=0;i<h.length;i++) h[i]=0;
        
        for (int i=0;i<components.size();i++) {
            Rectangle rect = (Rectangle)sizes.get(i);
            Component comp = (Component)components.get(i);
	    Dimension d = comp.getMinimumSize();
            int dw = d.width/rect.width;
            int dh = d.height/rect.height;
            for (int c=rect.x;c<rect.x+rect.width;c++)
                for (int r=rect.y;r<rect.y+rect.height;r++) {
                    w[c]=max2(w[c],dw);
                    h[r]=max2(h[r],dh);
                }
        }
        
        int maxw=0;for (int i=0;i<w.length;i++) maxw+=w[i];
        int maxh=0;for (int i=0;i<h.length;i++) maxh+=h[i];
	return new Dimension(insets.left + insets.right + maxw + (cols-1)*hgap, 
			     insets.top + insets.bottom + maxh + (rows-1)*vgap);
      }
    }
    
    public Dimension preferredLayoutSize(Container parent) {
//      System.out.println("preferredLayoutSize("+parent+")");
      synchronized (parent.getTreeLock()) {
        Insets insets = parent.getInsets();
	int ncomponents = parent.getComponentCount();

        int[] w = new int[cols]; for (int i=0;i<w.length;i++) w[i]=0;
	int[] h = new int[rows]; for (int i=0;i<h.length;i++) h[i]=0;
        
        for (int i=0;i<components.size();i++) {
            Rectangle rect = (Rectangle)sizes.get(i);
            Component comp = (Component)components.get(i);
	    Dimension d = comp.getPreferredSize();
            int dw = d.width/rect.width;
            int dh = d.height/rect.height;
            for (int c=rect.x;c<rect.x+rect.width;c++)
                for (int r=rect.y;r<rect.y+rect.height;r++) {
                    w[c]=max2(w[c],dw);
                    h[r]=max2(h[r],dh);
                }
        }
        
        int maxw=0;for (int i=0;i<w.length;i++) maxw+=w[i];
        int maxh=0;for (int i=0;i<h.length;i++) maxh+=h[i];
	return new Dimension(insets.left + insets.right + maxw + (cols-1)*hgap, 
			     insets.top + insets.bottom + maxh + (rows-1)*vgap);
      }
    }
            
    public java.awt.Dimension maximumLayoutSize(final java.awt.Container parent) {
      System.out.println("maximumLayoutSize("+parent+")");
      synchronized (parent.getTreeLock()) {
        Insets insets = parent.getInsets();
	int ncomponents = parent.getComponentCount();

        int[] w = new int[cols]; for (int i=0;i<w.length;i++) w[i]=0;
	int[] h = new int[rows]; for (int i=0;i<h.length;i++) h[i]=0;
        
        for (int i=0;i<components.size();i++) {
            Rectangle rect = (Rectangle)sizes.get(i);
            Component comp = (Component)components.get(i);
	    Dimension d = comp.getMaximumSize();
            int dw = d.width/rect.width;
            int dh = d.height/rect.height;
            for (int c=rect.x;c<rect.x+rect.width;c++)
                for (int r=rect.y;r<rect.y+rect.height;r++) {
                    w[c]=max2(w[c],dw);
                    h[r]=max2(h[r],dh);
                }
        }
        
        int maxw=0;for (int i=0;i<w.length;i++) maxw+=w[i];
        int maxh=0;for (int i=0;i<h.length;i++) maxh+=h[i];
	return new Dimension(insets.left + insets.right + maxw + (cols-1)*hgap, 
			     insets.top + insets.bottom + maxh + (rows-1)*vgap);
      }
    }
    
    public void invalidateLayout(final java.awt.Container p1) {
    }
    
    public float getLayoutAlignmentY(final java.awt.Container p1) {
        return 0.5f;
    }
    
    public float getLayoutAlignmentX(final java.awt.Container p1) {
        return 0.5f;
    }
    
}
