/*
 * 作成日: 2005/10/09
 */
package net.sourceforge.swingx.jspread;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;

import javax.swing.CellRendererPane;
import javax.swing.JComponent;

import net.sourceforge.swingx.Logger;


class JSpreadHeaderPane  extends JComponent {
	private static Logger logger = Logger.getLogger(JSpreadHeaderPane.class);

	/** 向き. JSpread.CORNER/ROW/COLUMN */
	int orientation;
	
	transient JSpread spread;
	/** セルレンダラーを行うクラス. */
	CellRendererPane rendererPane = new CellRendererPane();
	
	JSpreadHeaderPane(int orientation, JSpread spread) {
		assert orientation == JSpread.CORNER || orientation == JSpread.ROW || orientation == JSpread.COLUMN;
		assert spread != null;
		this.orientation = orientation;
		this.spread = spread;
		setFocusable(false);	// TODO:よいか？
		JSpreadHeaderListener listener = new JSpreadHeaderListener(spread, this);
		addMouseListener(listener);
		addMouseMotionListener(listener);
		setBackground(spread.properties.getColor(JSpread.BACKGROUND_COLOR));
	}

	public void paintComponent(Graphics g) {
		logger.debug("enter orientation="+orientation);
		super.paintComponent(g);
		JSpreadSheet sheet = spread.getSheet();
		Graphics2D g2 = (Graphics2D) g;
		Rectangle rect = g2.getClipBounds();

		// 背景を表示する
		int width = getWidth();
		int height = getHeight();
		g2.setPaint(spread.properties.getColor(JSpread.BACKGROUND_COLOR));
		g2.fillRect(0, 0, width, height);
		
		// ヘッダを表示する
		Color gridColor = (orientation == JSpread.HORIZONTAL) ? 
				spread.properties.getColor(JSpread.HORIZONTAL_GRID_COLOR) :
				spread.properties.getColor(JSpread.VERTICAL_GRID_COLOR);
		int space = (gridColor != null ? 1 : 0);
		
		// 上側のカラムヘッダを表示する
		if (orientation == JSpread.HORIZONTAL) {
			int startCol = spread.getSheet().colHeader.getViewPositionAtPoint(rect.x);
			if (startCol == -1) return;	// セル外の再描画
			int endCol = spread.getSheet().colHeader.getViewPositionAtPoint(rect.x+rect.width);
			if (endCol == -1) endCol = spread.getSheet().colHeader.getViewCount() - 1;
			Rectangle cellRect = new Rectangle();
			int header_h = sheet.colHeader.thickness;
			cellRect.y = 0;
			cellRect.height = header_h;
			cellRect.x = sheet.colHeader.getPoint(startCol);
			for (int c=startCol; c<=endCol; c++) {
				int col_data_index = sheet.colHeader.getDataIndex(c); 
				Object value = spread.getHeaderValueAt(JSpread.COLUMN, col_data_index);
				cellRect.width = sheet.colHeader.getWidth(col_data_index) + space;
			   	boolean isSelected = sheet.getHeaderSelection(JSpread.COLUMN, c);
				boolean hasFocus = sheet.focusCol == c && sheet.focusRow == -1;	// TODO:あってる？
				// レンダラーを取得
			   	if (value instanceof JComponent) {
			   		JComponent comp = (JComponent) value;
			   		add(comp);
			   		comp.setBounds(cellRect);
			   	} else {
					JSpreadCellRenderer renderer = spread.getHeaderRenderer(value, JSpread.COLUMN, col_data_index);
					JComponent comp = renderer.getSpreadRendererComponent(
							spread, value, isSelected, hasFocus,
							JSpread.COLUMN, 0, col_data_index);
					rendererPane.paintComponent(g2, comp, this, cellRect.x,
							cellRect.y, cellRect.width, cellRect.height, true);
			   	}
//			   	paintColHeader(g2, cellRect, sheet.colHeader, col_data_index, isSelected);
				cellRect.x += cellRect.width; 
			}
		}		
		// 左側のカラムヘッダを表示する
		else if (orientation == JSpread.VERTICAL) {
			int startRow = spread.getSheet().rowHeader.getViewPositionAtPoint(rect.y);
			if (startRow == -1) return;	// セル外の再描画
			int endRow = spread.getSheet().rowHeader.getViewPositionAtPoint(rect.y+rect.height);
			if (endRow == -1) endRow = spread.getSheet().rowHeader.getViewCount() - 1;

			Rectangle cellRect = new Rectangle();
			int header_w = sheet.rowHeader.thickness;
			cellRect.x = 0;
			cellRect.width = header_w;
			cellRect.y = sheet.rowHeader.getPoint(startRow);
			for (int r=startRow; r<=endRow; r++) {
				int row_index = sheet.rowHeader.getDataIndex(r); 
				Object value = spread.getHeaderValueAt(JSpread.ROW, row_index);
				cellRect.height = sheet.rowHeader.getWidth(row_index) + space;
			   	boolean isSelected = sheet.getHeaderSelection(JSpread.ROW, r);
				boolean hasFocus = sheet.focusCol == -1 && sheet.focusRow == r;	// TODO:あってる？
				// レンダラーを取得
			   	if (value instanceof JComponent) {
			   		JComponent comp = (JComponent) value;
			   		add(comp);
			   		comp.setBounds(cellRect);
			   	} else {
					JSpreadCellRenderer renderer = spread.getHeaderRenderer(value, JSpread.ROW, row_index);
					JComponent comp = renderer.getSpreadRendererComponent(
							spread, value, isSelected, hasFocus,
							JSpread.ROW, row_index, 0);
					rendererPane.paintComponent(g2, comp, this, cellRect.x,
							cellRect.y, cellRect.width, cellRect.height, true);
			   	}
			   	//paintRowHeader(g2, cellRect, sheet.rowHeader, row_index, isSelected);
				cellRect.y += cellRect.height; 
			}
		}		
		// 左上のコーナーを表示する
		else if (orientation == JSpread.CORNER) {
			Rectangle cellRect = new Rectangle();
			int header_w = sheet.rowHeader.thickness;
			int header_h = sheet.colHeader.thickness;
			cellRect.x = 0;
			cellRect.y = 0;
			cellRect.width = header_w;
			cellRect.height = header_h;
			Object value = spread.getCornerValue();
			boolean isSelected = spread.getSheet().getHeaderSelection(JSpread.CORNER, 0);
			boolean hasFocus = sheet.focusCol == -1 && sheet.focusRow == -1;	// TODO:あってる？
			// レンダラーを取得
		   	if (value instanceof JComponent) {
		   		JComponent comp = (JComponent) value;
		   		add(comp);
		   		comp.setBounds(cellRect);
		   	} else {
				JSpreadCellRenderer renderer = spread.getHeaderRenderer(value, JSpread.CORNER, 0);
				JComponent comp = renderer.getSpreadRendererComponent(
						spread, value, isSelected, hasFocus,
						JSpread.CORNER, 0, 0);
				rendererPane.paintComponent(g2, comp, this, cellRect.x,
						cellRect.y, cellRect.width, cellRect.height, true);
		   	}
//			paintCorner(g2, cellRect);
		}
		logger.debug("exit");
	}

    public Dimension getPreferredSize() {
    	JSpreadSheet sheet = spread.getSheet();
    	switch (orientation) {
    	case JSpread.CORNER:
    		return new Dimension(0, 0);
    	case JSpread.ROW:
    		return new Dimension(
    			sheet.rowHeader.thickness, 
    			sheet.rowHeader.getTotalWidth());
    	case JSpread.COLUMN:
    		return new Dimension(
    			sheet.colHeader.getTotalWidth(),
    			sheet.colHeader.thickness);
    	default:
    		assert false: orientation;
    	}
    	return null;
    }
	public String getToolTipText(MouseEvent event) {
		return spread.getToolTipText(getName(), event);
	}
}
