/*
 * 作成日: 2006/03/15
 */
package net.sourceforge.swingx.jspread;

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

import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JPanel;

import net.sourceforge.swingx.Logger;


public class JSpread2x2Panel extends JPanel {
	static Logger logger = Logger.getLogger(JSpread2x2Panel.class);
	final JComponent[][] pane;	// [2..2][2..2]要素はnull不可
	final int fixRow;	// 0,1
	final int fixCol;	// 0,1

	JSpread2x2Panel(int fixRow, int fixCol) {
		assert fixRow == 0 || fixRow == 1: fixRow;
		assert fixCol == 0 || fixCol == 1: fixCol;
		this.fixRow = fixRow;
		this.fixCol = fixCol;
		this.pane = new JComponent[2][2];
		// 各ペインはnull不可なので、ダミーのコンポーネントを設定しておく。
		Dimension dim = new Dimension(1, 1);
		this.pane[0][0] = new Box.Filler(dim, dim, dim);
		this.pane[0][1] = new Box.Filler(dim, dim, dim);
		this.pane[1][0] = new Box.Filler(dim, dim, dim);
		this.pane[1][1] = new Box.Filler(dim, dim, dim);
		setLayout(new JFixSplitInsideLayoutManager());
	}

	public void setPane(int row, int col, JComponent comp) {
		assert 0 <= row && row < 2: row;
		assert 0 <= col && col < 2: col;
		assert comp != null: comp;
		if (pane[row][col] != null) remove(pane[row][col]);
		pane[row][col] = comp;
		add(comp);
	}

	class JFixSplitInsideLayoutManager implements LayoutManager {

	    /** 指定されたコンテナを配置します。 */
		public void layoutContainer(Container target) {
			synchronized (target.getTreeLock()) {
				logger.debug("target="+target.getSize());
				// 一応インセットも対応しているのでボーダーが正しく使える。
				Insets insets = target.getInsets();
				int x0 = insets.left;
				int y0 = insets.top;
				int x9 = target.getWidth() - insets.right;
				int y9 = target.getHeight() - insets.bottom;
				int w = Math.max(
						pane[0][fixCol].getPreferredSize().width, 
						pane[1][fixCol].getPreferredSize().width);
				int h = Math.max(
						pane[fixRow][0].getPreferredSize().height, 
						pane[fixRow][1].getPreferredSize().height);
				int x5 = (fixCol == 0) ? (x0 + w) : (x9 - w);
				int y5 = (fixRow == 0) ? (y0 + h) : (y9 - h);
				pane[0][0].setBounds(x0, y0, x5-x0, y5-y0);
				pane[0][1].setBounds(x5, y0, x9-x5, y5-y0);
				pane[1][0].setBounds(x0, y5, x5-x0, y9-y5);
				pane[1][1].setBounds(x5, y5, x9-x5, y9-y5);
			}
		}

		/** 指定されたコンテナの最小サイズの寸法を計算します。 */
		public Dimension minimumLayoutSize(Container parent) {
			// 個々のペインの最小サイズを加算
			Dimension d00 = pane[0][0].getMinimumSize();
			Dimension d01 = pane[0][1].getMinimumSize();
			Dimension d10 = pane[1][0].getMinimumSize();
			Dimension d11 = pane[1][1].getMinimumSize();
			return new Dimension(
					Math.max(d00.width, d10.width) + Math.max(d01.width, d11.width),
					Math.max(d00.height, d01.height) + Math.max(d10.height, d11.height));
		}
	    /** 指定されたコンテナの推奨サイズの寸法を計算します。 */
		public Dimension preferredLayoutSize(Container parent) {
			// 個々のペインの推奨サイズを加算
			Dimension d00 = pane[0][0].getPreferredSize();
			Dimension d01 = pane[0][1].getPreferredSize();
			Dimension d10 = pane[1][0].getPreferredSize();
			Dimension d11 = pane[1][1].getPreferredSize();
			return new Dimension(
					Math.max(d00.width, d10.width) + Math.max(d01.width, d11.width),
					Math.max(d00.height, d01.height) + Math.max(d10.height, d11.height));
		}
	    /** レイアウトマネージャがコンポーネントごとの文字列を使用する場合、レイアウトにコンポーネントの comp を追加し、name によって指定された文字列に関連付けます。 */
		public void addLayoutComponent(String name, Component comp){}
		/** 指定されたコンポーネントをレイアウトから削除します。 */	
		public void removeLayoutComponent(Component comp) {}
	}
	public String toString() {
		return "JSpread2x2Panel[\n"
			+"pane[0][0]="+JSpreadUtilities.toString(pane[0][0].getBounds())+"\n"
			+"pane[0][1]="+JSpreadUtilities.toString(pane[0][1].getBounds())+"\n"
			+"pane[1][0]="+JSpreadUtilities.toString(pane[1][0].getBounds())+"\n"
			+"pane[1][1]="+JSpreadUtilities.toString(pane[1][1].getBounds())+"\n"
			+"]\n";
	}
}

