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

import java.awt.Cursor;
import java.awt.event.MouseEvent;

import javax.swing.event.MouseInputAdapter;

import net.sourceforge.swingx.Logger;
import net.sourceforge.swingx.jspread.JSpreadSheet.CurrentFocus;

/**
 * ヘッダを選択したり、幅を変更するリスナー 
 * @author Asan
 */
public class JSpreadHeaderListener extends MouseInputAdapter {
	private static Logger logger = Logger.getLogger(JSpreadHeaderListener.class);
	static final int RESIZE = 1;
	static final int SELECT = 0;
	
	final JSpreadHeaderPane pane;
	final JSpread spread;
	final JSpreadHeaderResizeListener resizeListener;
	/** モード。SELECTかRESIZEかのいずれか。*/
	int mode = SELECT;	// inv mode == SELECT || mode == RESIZE;

	JSpreadHeaderListener(JSpread spread, JSpreadHeaderPane pane) {
		assert spread != null;
		assert pane != null;		
		this.spread = spread;
		this.pane = pane;
		this.resizeListener = new JSpreadHeaderResizeListener(spread, pane);
	}
    /** コンポーネント上でマウスボタンが押されると呼び出されます。 */ 
	public void mousePressed(MouseEvent e) {
		logger.debug(e);
		// リサイズの位置ならリサイズを開始する。
		if (resizeListener.isSensable(e.getX(), e.getY())) {
			mode = RESIZE;
			resizeListener.mousePressed(e);
			return;
		}
		// それ以外の場所なら選択モードにする。
		JSpreadSheet sheet = spread.getSheet();
		CurrentFocus prev = sheet.getCurrentFocus();
		int startRow;
		int startCol;
		switch (pane.orientation) {
		case JSpread.ROW:
			startRow = 0;
			mode = SELECT;
			startCol = 0;
			int row = sheet.rowHeader.getViewPositionAtPoint(e.getY());
			if (e.getButton() == MouseEvent.BUTTON1) {
				if (e.isControlDown()) {
					// Ctrl+左ボタンのとき、
					sheet.setSelection(sheet.focusRow, sheet.focusCol, sheet.curRow, sheet.curCol, true);
				}
				else {
					sheet.setSelectionAll(false);
					sheet.setHeaderSelectionAll(JSpread.ROW, false);
					sheet.setHeaderSelectionAll(JSpread.COLUMN, false);
					sheet.setCornerSelection(false);
				}
				if (row != -1 ) {
					if (e.isShiftDown()) {
						sheet.curRow = row;
						sheet.curCol = -1;
						CurrentFocus next = sheet.getCurrentFocus();
						if (! prev.equals(next)) {
							spread.fireSelectionListener(new JSpreadSelectionEvent(this, prev, next));
						}
					} else {
						sheet.focusRow = sheet.curRow = row;
						sheet.focusCol = startCol;
						sheet.curCol = -1;
						CurrentFocus next = sheet.getCurrentFocus();
						if (! prev.equals(next)) {
							spread.fireSelectionListener(new JSpreadSelectionEvent(this, prev, next));
						}
					}
				}
				spread.再描画();
			}
			break;
		case JSpread.COLUMN:
			startRow = 0;
			startCol = 0;
			mode = SELECT;
			int col = sheet.colHeader.getViewPositionAtPoint(e.getX());
			if (e.getButton() == 1) {
				if (e.isControlDown()) {
					sheet.setSelection(sheet.focusRow, sheet.focusCol, sheet.curRow, sheet.curCol, true);
				}
				else {
					sheet.setSelectionAll(false);
					sheet.setHeaderSelectionAll(JSpread.ROW, false);
					sheet.setHeaderSelectionAll(JSpread.COLUMN, false);
					sheet.setCornerSelection(false);
				}
				if (col != -1 ) {
					if (e.isShiftDown()) {
						sheet.curRow = -1;
						sheet.curCol = col;
						CurrentFocus next = sheet.getCurrentFocus();
						if (! prev.equals(next)) {
							spread.fireSelectionListener(new JSpreadSelectionEvent(this, prev, next));
						}
					}
					else {
						sheet.focusCol = sheet.curCol = col;
						sheet.focusRow = startRow;
						sheet.curRow = -1;
						CurrentFocus next = sheet.getCurrentFocus();
						if (! prev.equals(next)) {
							spread.fireSelectionListener(new JSpreadSelectionEvent(this, prev, next));
						}
					}
				}
				spread.再描画();
			}
			break;
		case JSpread.CORNER:
			// すべてを選択
			mode = SELECT;
			sheet.setSelectionAll(true);
			sheet.setHeaderSelectionAll(JSpread.ROW, true);
			sheet.setHeaderSelectionAll(JSpread.COLUMN, true);
			sheet.cornerSelection = true;
			sheet.focusRow = 0;
			sheet.focusCol = 0;
			sheet.curRow = sheet.getHeader(JSpread.ROW).getViewCount() - 1;
			sheet.curCol = sheet.getHeader(JSpread.COLUMN).getViewCount() - 1;
			CurrentFocus next = sheet.getCurrentFocus();
			if (! prev.equals(next)) {
				spread.fireSelectionListener(new JSpreadSelectionEvent(this, prev, next));
			}
			spread.再描画();
			break;
		default:	assert false;
		}
	}
	/** コンポーネント上でマウスのボタンを押してドラッグすると呼び出されます。 */
	public void mouseDragged(MouseEvent e) {
		logger.debug(e);
		JSpreadSheet sheet = spread.getSheet();
		if (mode == SELECT) {
			CurrentFocus prev = sheet.getCurrentFocus();
			switch (pane.orientation) {
			case JSpread.ROW:
				int row = sheet.rowHeader.getViewPositionAtPoint(e.getY());
				if (row != -1 ) {
					sheet.curRow = row;
					sheet.curCol = -1;
				}
				CurrentFocus next = sheet.getCurrentFocus();
				if (! prev.equals(next)) {
					spread.fireSelectionListener(new JSpreadSelectionEvent(this, prev, next));
				}
				spread.再描画();
				break;
			case JSpread.COLUMN:
				int col = sheet.colHeader.getViewPositionAtPoint(e.getX());
				if (col != -1 ) {
					sheet.curRow = -1;
					sheet.curCol = col;
				}
				next = sheet.getCurrentFocus();
				if (! prev.equals(next)) {
					spread.fireSelectionListener(new JSpreadSelectionEvent(this, prev, next));
				}
				spread.再描画();
				break;
			case JSpread.CORNER:
				break;
			default:	assert false;
			}
		}
		else {
			resizeListener.mouseDragged(e);
		}
	}
	
	public void mouseReleased(MouseEvent e) {
		if (mode == RESIZE) {
			resizeListener.mouseReleased(e);
		}
	}
	public void mouseMoved(MouseEvent e) {
		if (resizeListener.isSensable(e.getX(), e.getY())) {
			resizeListener.mouseMoved(e);
		} else {
			pane.setCursor(Cursor.getDefaultCursor());  
		}
	}
    /** コンポーネント上でマウスボタンをクリック (押してから離す) したときに呼び出されます。*/ 
	public void mouseClicked(MouseEvent e) {
		if (resizeListener.isSensable(e.getX(), e.getY())) {
			resizeListener.mouseClicked(e);
		}
	}

}
