/*
 * 著作権: Copyright (c) 2007−2008 ZIGEN
 * ライセンス：Eclipse Public License - v 1.0
 * 原文：http://www.eclipse.org/legal/epl-v10.html
 */

package zigen.plugin.db.ext.s2jdbc.wizards;

import java.util.StringTokenizer;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;

import zigen.plugin.db.DbPlugin;
import zigen.plugin.db.DbPluginConstant;
import zigen.plugin.db.core.ClipboardUtils;
import zigen.plugin.db.core.TabTokenizer;
import zigen.plugin.db.core.TableColumn;

/**
 * 
 * TableKeyAdapterクラス.
 * 
 * @author ZIGEN
 * @version 1.0
 * @since JDK1.4 history Symbol Date Person Note [1] 2006/02/08 ZIGEN create.
 * 
 */
public class TableKeyAdapter2 implements KeyListener, TraverseListener {
	
	private TableKeyEventHandler2 handler;
	
	// private ITableViewEditor editor;
	
	// TableColumn[] columns;
	
	// int columnCount;
	
	// TableElement headerTableElement;
	
	Table table;
	
	/**
	 * コンストラクタ
	 * 
	 */
	public TableKeyAdapter2(TableKeyEventHandler2 handler) {
		this.handler = handler;
		// this.editor = handler.editor;
		this.table = handler.table;
		
		// this.headerTableElement = handler.getHeaderTableElement();
		// if (this.headerTableElement != null) {
		// this.columns = headerTableElement.getColumns();
		// this.columnCount = columns.length;
		// }
		
	}
	
	// CCCombo用 Traversed文字
	// private char keyTraversedChar;
	

	public void keyTraversed(TraverseEvent e) {
		System.out.println("public void keyTraversed(TraverseEvent e)");
		
		// keyTraversedChar = e.character;
		
		int row = handler.getSelectedRow(); // 行（先頭は0から)
		int col = handler.getSelectedCellEditorIndex(); // 現在のカラム
		
		if (e.character == SWT.TAB) {
			if ((e.stateMask & SWT.SHIFT) != 0) {
				if (handler.validate(row, col)) {
					int prevCol = handler.getEditablePrevColumn(col);
					handler.editTableElement(row, prevCol);
				}
			} else {
				if (handler.validate(row, col)) {
					int nextCol = handler.getEditableNextColumn(col);
					handler.editTableElement(row, nextCol);
				}
			}
			e.doit = false; // TABは常にfalse
		}
	}
	
	/**
	 * Enterイベント
	 * 
	 * @param e
	 * @throws Exception
	 */
	private void enterEvent(KeyEvent e) throws Exception {
		int row = handler.getSelectedRow(); // 行（先頭は0から)
		int col = handler.getSelectedCellEditorIndex(); // 現在のカラム
		
		FormProperty element = (FormProperty) handler.viewer.getElementAt(row);
		if (!handler.validate(row, col)) {
			e.doit = false;
		} else {
			// if (handler.updateDataBase(element)) {
			// // editor.changeColumnColor();
			// // handler.selectRow(row);// 更新後選択状態にする
			// // e.doit = true;
			// } else {
			// // // handler.editTableElement(row, col); // ここで編集すると、エラー箇所での編集が解除されてしまう。
			// // e.doit = false;
			// }
			handler.selectRow(row);// 更新後選択状態にする
			e.doit = true;
		}
		
	}
	
	/**
	 * 矢印イベント
	 * 
	 * @param e
	 * @param text
	 * @throws Exception
	 */
	private void arrowEvent(KeyEvent e, Text text) throws Exception {
		int row = handler.getSelectedRow(); // 行（先頭は0から)
		int col = handler.getSelectedCellEditorIndex(); // 現在のカラム
		int prevCol = handler.getEditablePrevColumn(col);
		int nextCol = handler.getEditableNextColumn(col);
		int maxRow = handler.table.getItemCount();
		int maxCol = handler.table.getColumnCount();
		int caretPostion = text.getCaretPosition();
		int carCount = text.getCharCount();
		int selectionCount = text.getSelectionCount();
		FormProperty element = (FormProperty) handler.viewer.getElementAt(row);
		switch (e.keyCode) {
			case SWT.ARROW_UP:
				// if (row > 0) {
				if (row >= 0) {
					if (handler.validate(row, col)) { // validateしないとisModifyが有効にならない
						// if (element.isNew() && !element.isModify()) {
						// //handler.removeRecord(element);
						// //handler.editTableElement(row - 1, col);
						// } else {
						// // if (handler.updateDataBase(element)) {
						// // editor.changeColumnColor();
						// //
						// // handler.editTableElement(row - 1, col);
						// // } else {
						// // handler.editTableElement(row, col);
						// // }
						// }
						
						handler.editTableElement(row - 1, col);
					}
					e.doit = false;
				}
				break;
			case SWT.ARROW_DOWN:
				if (row < maxRow - 1) {
					if (handler.validate(row, col)) {
						// if (handler.updateDataBase(element)) {
						// handler.editTableElement(row + 1, col);
						// } else {
						// handler.editTableElement(row, col);
						// }
						handler.editTableElement(row + 1, col);
					}
					e.doit = false;
				} else {
					if (handler.validate(row, col)) {
						// if (!element.isNew()) {
						// // if (handler.updateDataBase(element)) {
						// // if (editor instanceof QueryViewEditor2) {
						// // ;// 何もしない
						// // // handler.editTableElement(0, col); // 先頭へ
						// // } else {
						// // handler.createNewRecord();
						// // }
						// // } else {
						// // handler.editTableElement(row, col);
						// // }
						// } else {
						// // if (element.isModify()) {
						// // if (handler.updateDataBase(element)) {
						// // handler.createNewRecord();
						// // } else {
						// // handler.editTableElement(row, col);
						// // }
						// // }
						// }
						
						handler.createNewRecord();
					}
					e.doit = false;
				}
				break;
			case SWT.ARROW_LEFT:
				if (col == 1) {
					if (selectionCount == carCount) {
						e.doit = false;
						
					} else {
						e.doit = true;
					}
				} else if (col > 1) {
					if ((selectionCount == 0 && caretPostion == 0) || selectionCount == carCount) {
						handler.editTableElement(row, prevCol);
						e.doit = false;
					}
				} else {
					e.doit = false;
				}
				break;
			case SWT.ARROW_RIGHT:
				if (col == maxCol - 1) {
					if (selectionCount == carCount) {
						e.doit = false;
						
					} else {
						e.doit = true;
					}
				} else if (col < maxCol - 1) {
					if (selectionCount == carCount || caretPostion == carCount) {
						handler.editTableElement(row, nextCol);
						e.doit = false;
					}
				} else {
					e.doit = false;
				}
				break;
			default:
				break;
		}
		
	}
	
	public void keyReleased(KeyEvent e) {
		;
	}
	
	public void keyPressed(KeyEvent e) {
		System.out.println("public void keyPressed(KeyEvent e)");
		Text text = null;
		try {
			if (e.widget instanceof Text) {
				text = (Text) e.widget;
				
				// ENTER
				if (e.character == SWT.CR) {
					enterEvent(e);
					
					// F2
				} else if (e.keyCode == SWT.F2) {
					text.clearSelection();// 選択テキストを解除する
					
					// 矢印キーイベント
				} else if (e.keyCode == SWT.ARROW_UP || e.keyCode == SWT.ARROW_DOWN || e.keyCode == SWT.ARROW_LEFT || e.keyCode == SWT.ARROW_RIGHT) {
					arrowEvent(e, text);
				}
				
				/*
				 * } else if (e.stateMask == SWT.CTRL && e.keyCode == 97) { // CTL+A で文字選択 text.selectAll(); }
				 */

				// CTRL+V
				if (e.stateMask == SWT.CTRL && e.keyCode == 118) {
					// if (createNewElement()) {
					// e.doit = false;
					// }
				}
				
			} else if (e.widget instanceof Button) {
				if (e.keyCode == SWT.ARROW_UP || e.keyCode == SWT.ARROW_DOWN || e.keyCode == SWT.ARROW_LEFT || e.keyCode == SWT.ARROW_RIGHT) {
					arrowEvent(e);
				}
				

			} else if (e.widget instanceof CCombo) {
				// int row = handler.getSelectedRow(); // 行（先頭は0から)
				// int col = handler.getSelectedCellEditorIndex(); // 現在のカラム
				//
				// // e.characterではなく、keyTraversedCharを使用する(CComboでは取得できないため)
				// if (keyTraversedChar == SWT.TAB) {
				// if ((e.stateMask & SWT.SHIFT) != 0) {
				// if (handler.validate(row, col)) {
				// int prevCol = handler.getEditablePrevColumn(col);
				// handler.editTableElement(row, prevCol);
				// }
				// } else {
				// if (handler.validate(row, col)) {
				// int nextCol = handler.getEditableNextColumn(col);
				// handler.editTableElement(row, nextCol);
				// }
				// }
				// e.doit = false; // TABは常にfalse
				// }
				
			}
		} catch (Exception e1) {
			DbPlugin.getDefault().showErrorDialog(e1);
		}
	}
	
	private boolean isHeaderData(TableColumn[] colums, String[] items) {
		boolean isHeader = true;
		if (colums.length != items.length)
			return false;
		
		for (int i = 0; i < colums.length; i++) {
			TableColumn col = colums[i];
			
			if (!col.getColumnName().equals(items[i])) {
				isHeader = false;
			}
			
		}
		return isHeader;
		
	}
	
	private boolean isRecordData(String target, int columnCount) {
		
		if (target == null || "".equals(target))return false; //$NON-NLS-1$
			
		StringTokenizer tokenizer = new StringTokenizer(target, DbPluginConstant.LINE_SEP);
		while (tokenizer.hasMoreTokens()) {
			StringBuffer sb = new StringBuffer();
			// \t\tで終わる場合を考慮して改行を入れる
			sb.append(tokenizer.nextToken()).append(DbPluginConstant.LINE_SEP);
			TabTokenizer t = new TabTokenizer(sb.toString());
			if (columnCount != t.getTokenCount()) {
				return false;
			}
		}
		
		return true;
		
	}
	
	private String getCurrentClipboard() {
		String result = null;
		
		Clipboard cp = ClipboardUtils.getInstance();
		TextTransfer transfer = TextTransfer.getInstance();
		// RTFTransfer rtransfer = RTFTransfer.getInstance();
		String v[] = cp.getAvailableTypeNames();
		for (int i = 0; i < v.length; i++) {
			if (v[i].equals("CF_TEXT")) { //$NON-NLS-1$
				result = (String) cp.getContents(transfer);
				if (result != null)
					return result;
				
			}
		}
		return result;
	}
	
	private void arrowEvent(KeyEvent e) throws Exception {
		int row = handler.getSelectedRow(); // 行（先頭は0から)
		int col = handler.getSelectedCellEditorIndex(); // 現在のカラム
		int prevCol = handler.getEditablePrevColumn(col);
		int nextCol = handler.getEditableNextColumn(col);
		int maxRow = handler.table.getItemCount();
		int maxCol = handler.table.getColumnCount();
		FormProperty element = (FormProperty) handler.viewer.getElementAt(row);
		switch (e.keyCode) {
			case SWT.ARROW_UP:
				// if (row > 0) {
				if (row >= 0) {
					if (handler.validate(row, col)) { // validateしないとisModifyが有効にならない
						// if (element.isNew() && !element.isModify()) {
						// handler.removeRecord(element);
						// handler.editTableElement(row - 1, col);
						// } else {
						// // if (handler.updateDataBase(element)) {
						// // editor.changeColumnColor();
						// //
						// // handler.editTableElement(row - 1, col);
						// // } else {
						// // handler.editTableElement(row, col);
						// // }
						// }
					}
					e.doit = false;
				}
				break;
			case SWT.ARROW_DOWN:
				if (row < maxRow - 1) {
					if (handler.validate(row, col)) {
						// if (handler.updateDataBase(element)) {
						// handler.editTableElement(row + 1, col);
						// } else {
						// handler.editTableElement(row, col);
						// }
					}
					e.doit = false;
				} else {
					if (handler.validate(row, col)) {
						// if (!element.isNew()) {
						// if (handler.updateDataBase(element)) {
						// if (editor instanceof QueryViewEditor2) {
						// ;// 何もしない
						// // handler.editTableElement(0, col); // 先頭へ
						// } else {
						// handler.createNewRecord();
						// }
						// } else {
						// handler.editTableElement(row, col);
						// }
						// } else {
						// if (element.isModify()) {
						// if (handler.updateDataBase(element)) {
						// handler.createNewRecord();
						// } else {
						// handler.editTableElement(row, col);
						// }
						// }
						// }
					}
					e.doit = false;
				}
				break;
			case SWT.ARROW_LEFT:
				if (col == 1) {
					e.doit = true;
				} else if (col > 1) {
					handler.editTableElement(row, prevCol);
					e.doit = false;
				} else {
					e.doit = false;
				}
				break;
			case SWT.ARROW_RIGHT:
				if (col == maxCol - 1) {
					e.doit = true;
				} else if (col < maxCol - 1) {
					handler.editTableElement(row, nextCol);
					e.doit = false;
				} else {
					e.doit = false;
				}
				break;
			default:
				break;
		}
		
	}
	

}
