package extractor.ui.clusteringUI;

import 	java.awt.*;
import 	java.util.*;
import	javax.swing.*;



public class GridPanel extends JPanel
{
	private final int FILL = 0;
	private final int TOP  = 1;
	private final int TOP_LEFT = TOP;
	private final int TOP_CENTER = 2;
	private final int TOP_RIGHT = 3;

  	private final int CENTER_LEFT = 4;
  	private final int CENTER = 5;
  	private final int CENTER_CENTER = CENTER;
  	private final int CENTER_RIGHT = 6;

  	private final int BOTTOM = 7;
  	private final int BOTTOM_LEFT = BOTTOM;
  	private final int BOTTOM_CENTER = 8;
  	private final int BOTTOM_RIGHT = 9;

  	private int cols;
  	private int rows;

  	private int hgap;
  	private int vgap;

  	private Vector constraints = new Vector();
  	private Insets insets = new Insets(0,0,0,0);



  	public GridPanel(int cols, int rows)
  	{
    		this(cols, rows, 0, 0);
  	}

	/** GridLayout의 Panel을 설정
	*
	* @param cols  	Column Cell의 갯수
	* @param rows 	Row Cell의 갯수
	* @param hgap	높이의 여백 공간 ( 단위 : pixel)
	* @param vgap	폭의 여백 공간  ( 단위 : pixel)
	*/
  	public GridPanel(int cols, int rows, int hgap, int vgap)
  	{
    		this.cols = cols;
    		this.rows = rows;
    		this.hgap = hgap;
    		this.vgap = vgap;
  	}

  	public void doLayout()
  	{
    		Dimension size = getSize();
    		size.height -= insets.top+insets.bottom;
    		size.width  -= insets.left+insets.right;

    		float cellWidth  = size.width/cols;
    		float cellHeight = size.height/rows;

    		for (int i = 0; i < constraints.size(); i++)
    		{
      			GridPanelConstraint c = (GridPanelConstraint) constraints.elementAt(i);

      			float x = cellWidth * c.x + insets.left + hgap/2;
      			float y = cellHeight * c.y + insets.right + vgap/2;

      			float width, height;

      			if (c.handle == FILL)
      			{
        			width  = (cellWidth-hgap) * c.width;
        			height = (cellHeight-vgap) * c.height;
      			}
      			else
      			{
        			Dimension d = c.component.getPreferredSize();
        			width  = d.width;
        			height = d.height;
      			}

      			switch (c.handle)
      			{
      				case TOP_CENTER:
        							x+= (cellWidth+width)/2;
        							break;
      				case TOP_RIGHT:
        							x+= cellWidth-width;
        							break;
      				case CENTER_LEFT:
        							y+= (cellHeight+height)/2;
        							break;
      				case CENTER:
        							x+= (cellWidth+width)/2;
        							y+= (cellHeight+height)/2;
        							break;
      				case CENTER_RIGHT:
        							y+= (cellHeight+height)/2;
        							x+= cellWidth-width;
        							break;
      				case BOTTOM:
        							y+= cellHeight-height;
        							break;
      				case BOTTOM_CENTER:
        							x+= (cellWidth+width)/2;
        							y+= cellHeight-height;
        							break;
      				case BOTTOM_RIGHT:
        							y+= cellHeight-height;
        							x+= cellWidth-width;
        							break;
      			}

      			c.component.setBounds(new Rectangle((int)x, (int)y, (int)width, (int)height));
    		}
  	}

  	public Dimension getPreferredSize()
  	{
    		float dy = 0;
    		float dx = 0;

    		for (int i = 0; i < constraints.size(); i++)
    		{
      				GridPanelConstraint c = (GridPanelConstraint) constraints.elementAt(i);
			      	Dimension d = c.component.getPreferredSize();

      				dx = Math.max(dx, d.width/c.width);
      				dy = Math.max(dy, d.height/c.height);
    		}

    		dx+= hgap;
    		dy+= vgap;

    		dx*= cols;
    		dy*= rows;

    		dx+= insets.left+insets.right;
    		dy+= insets.top+insets.bottom;

    		return new Dimension((int)dx,(int)dy);
  	}


  	public void setInsets(Insets insets)
  	{
    		this.insets = insets;
  	}

	/**
	*	원하는 Cell 위치에 컴포넌트를 추가
	*
	* @param x 		셀의 열 좌표 ( 0 ~ cols-1)
	* @param y 		셀의 행 좌표 ( 0 ~ rows-1)
	* @param c 		컴포넌트
	*/
  	public void add(int x, int y, Component c)
  	{
    		add(x,y,1,1,FILL,c);
  	}

	/**
	*	원하는 Cell 위치에 컴포넌트를 추가
	*
	* @param x 		셀의 열 좌표 ( 0 ~ cols-1)
	* @param y 		셀의 행 좌표 ( 0 ~ rows-1)
	* @param handle 	셀에서의 컴포넌트 위치
	* @param c 		컴포넌트
	*/
  	public void add(int x, int y, int handle, Component c)
  	{
    		add(x,y,1,1,handle,c);
  	}

	/**
	*	원하는 Cell 위치에 컴포넌트를 추가
	*
	* @param x 		셀의 열 좌표 ( 0 ~ cols-1)
	* @param y 		셀의 행 좌표 ( 0 ~ rows-1)
	* @param dx 		폭으로 차지할 셀의 갯수
	* @param dy 		높이로 차지할 셀의 갯수
	* @param c 		컴포넌트
	*/
  	public void add(int x, int y, int dx, int dy, Component c)
  	{
    		add(x,y,dx,dy,FILL,c);
  	}

	/**
	*	원하는 Cell 위치에 컴포넌트를 추가
	*
	* @param x 		셀의 열 좌표 ( 0 ~ cols-1)
	* @param y 		셀의 행 좌표 ( 0 ~ rows-1)
	* @param dx 		폭으로 차지할 셀의 갯수
	* @param dy 		높이로 차지할 셀의 갯수
	* @param handle 	셀에서의 컴포넌트 위치
	* @param c 		컴포넌트
	*/
  	public void add(int x, int y, int dx, int dy, int handle, Component c)
  	{
    		super.add(c);
    		constraints.addElement(new GridPanelConstraint(x,y,dx,dy,handle,c));
  	}
}
