package hiro.yoshioka.sql.util;

import hiro.yoshioka.sql.resource.IDBColumn;
import hiro.yoshioka.sql.resource.IDBTable;
import hiro.yoshioka.util.StringUtil;

import java.util.ArrayList;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

public class FunctionInputDialog extends TitleAreaDialog {
	public static String[] COLUMN_PROPERTIES = {
			Messages.getString("FunctionInputDialog.Num"), Messages.getString("FunctionInputDialog.Elements"), Messages.getString("FunctionInputDialog.Type"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			Messages.getString("FunctionInputDialog.Value") }; //$NON-NLS-1$
	private boolean isCellEditing;
	TableViewer viewer;
	private CellEditor[] cellEditor;

	IDBTable dbTable;

	ArrayList<MyItem> defaultList = new ArrayList<MyItem>();

	public FunctionInputDialog(Shell shell, IDBTable table) {
		super(shell);
		dbTable = table;
	}

	protected Button createButton(Composite parent, int id, String label,
			boolean defaultButton) {
		if (id == IDialogConstants.OK_ID) {
			label = Messages.getString("FunctionInputDialog.Execute"); //$NON-NLS-1$
		}
		return super.createButton(parent, id, label, defaultButton);
	}

	@Override
	public void create() {
		super.create();
		getShell().setText(Messages.getString("FunctionInputDialog.TITLE")); // //$NON-NLS-1$
	}

	protected Control createDialogArea(Composite parent) {

		Composite composite = (Composite) super.createDialogArea(parent);
		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
		composite.setSize(500, 150);

		Table table = new Table(composite, SWT.MULTI | SWT.FULL_SELECTION
				| SWT.BORDER);
		table.setLayoutData(new GridData(GridData.FILL_BOTH));
		viewer = new TableViewer(table);

		Composite tail = new Composite(composite, SWT.NONE);
		tail.setLayout(new FormLayout());
		tail.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		// Button btn = new Button(tail, SWT.PUSH);

		// FormData buttonData = new FormData();
		// buttonData.top = new FormAttachment(0, 0);
		// buttonData.right = new FormAttachment(100, 0);
		// btn.setLayoutData(buttonData);
		//
		// FormData textData = new FormData();
		// textData.top = new FormAttachment(0, 0);
		// textData.left = new FormAttachment(0, 0);
		// textData.right = new FormAttachment(btn, 0);

		table.setLinesVisible(true);

		table.setHeaderVisible(true);

		for (int i = 0; i < COLUMN_PROPERTIES.length; i++) {
			TableColumn column = new TableColumn(table, SWT.NONE);
			column.setText(COLUMN_PROPERTIES[i]);
		}
		String[] properties = COLUMN_PROPERTIES;

		viewer.setColumnProperties(properties);

		cellEditor = new CellEditor[] { new MyTextCellEditor(table),
				new MyTextCellEditor(table), new MyTextCellEditor(table),
				new MyTextCellEditor(table) };

		viewer.setCellEditors(cellEditor);

		viewer.setContentProvider(new ArrayContentProvider());
		viewer.setLabelProvider(new MyLabelProvider());

		IDBColumn[] inputs = dbTable.getColumns();
		for (int i = 0; i < inputs.length; i++) {
			if (inputs[i].isColumnIn() || inputs[i].isColumnInOut()) {
				MyItem itemm = new MyItem(inputs[i]);
				// itemm.load(getPreferenceStore());
				defaultList.add(itemm);
			}
		}
		viewer.setInput(defaultList);
		viewer.setCellModifier(new MyCellModifier(viewer));

		table.getColumn(0).setWidth(26);
		table.getColumn(1).setWidth(100);
		table.getColumn(2).setWidth(80);
		table.getColumn(3).setWidth(140);

		if (inputs.length > 0) {
			setMessage(
					Messages.getString("FunctionInputDialog.InputAnyValues"), IMessageProvider.INFORMATION); //$NON-NLS-1$
		} else {
			setMessage(
					Messages.getString("FunctionInputDialog.PushButton"), IMessageProvider.INFORMATION); //$NON-NLS-1$
		}

		return composite;
	}

	public String[] getInputValues() {
		String[] ret = new String[defaultList.size()];
		for (int i = 0; i < defaultList.size(); i++) {
			ret[i] = defaultList.get(i).getValue();
		}
		return ret;
	}

	void validate() {
		Button okButton = getButton(IDialogConstants.OK_ID);
		boolean buttonEnabled = false;
		if (isCellEditing) {
			setErrorMessage(Messages
					.getString("FunctionInputDialog.CellEditorIsActivatingPressEnterInCellEditor")); //$NON-NLS-1$
		} else {
			setErrorMessage(null);
			buttonEnabled = true;
		}
		if (dbTable.getColumns().length > 0) {
			boolean showInfo = false;
			for (int i = 0; i < defaultList.size(); i++) {
				if (StringUtil.isEmpty(defaultList.get(i).getValue())) {
					showInfo = true;
					break;
				}
			}
			if (showInfo) {
				setMessage(
						Messages.getString("FunctionInputDialog.InputAnyValues"), IMessageProvider.INFORMATION); //$NON-NLS-1$
			} else {
				setMessage(
						Messages.getString("FunctionInputDialog.PushButton"), IMessageProvider.INFORMATION); //$NON-NLS-1$
			}
		}
		if (okButton != null) {
			okButton.setEnabled(buttonEnabled);
		}
	}

	// ---------------------------------------------------------------

	@Override
	protected void okPressed() {
		for (CellEditor editor : cellEditor) {
			if (editor.isActivated()) {
				editor.deactivate();
			}
		}

		super.okPressed();
	}

	class MyTextCellEditor extends TextCellEditor {

		public MyTextCellEditor(Table table) {
			super(table);
		}

		@Override
		public void activate() {
			super.activate();
			isCellEditing = true;
			validate();
		}

		@Override
		public void deactivate() {
			isCellEditing = false;
			super.deactivate();
			validate();
		}
	}

	class MyItem {
		IDBColumn fBindInfo;

		StringBuffer value = new StringBuffer();

		public MyItem(IDBColumn info) {
			this.fBindInfo = info;
		}

		public String getValue() {
			return value.toString();
		}
	}

	class MyLabelProvider extends LabelProvider implements ITableLabelProvider {

		public Image getColumnImage(Object element, int columnIndex) {
			return null;
		}

		public String getColumnText(Object element, int columnIndex) {
			MyItem item = (MyItem) element;
			String result = StringUtil.EMPTY_STRING;
			switch (columnIndex) {
			case 0:
				result = String.valueOf(defaultList.indexOf(element) + 1);
				break;
			case 1:
				result = item.fBindInfo.getName();
				break;
			case 2:
				result = item.fBindInfo.getDataTypeString();
				break;
			case 3:
				result = item.getValue();
				break;
			default:
				break;
			}

			return result;
		}
	}

	class MyCellModifier implements ICellModifier {
		private TableViewer viewer;

		public MyCellModifier(TableViewer viewer) {
			this.viewer = viewer;
		}

		public boolean canModify(Object element, String property) {
			if (property.equals(FunctionInputDialog.COLUMN_PROPERTIES[3])) {
				return true;
			}
			return false;
		}

		public Object getValue(Object element, String property) {
			MyItem item = (MyItem) element;
			if (property == FunctionInputDialog.COLUMN_PROPERTIES[3]) {
				return item.getValue();
			}
			return null;
		}

		public void modify(Object element, String property, Object value) {
			if (element instanceof Item) {
				element = ((Item) element).getData();
			}
			MyItem item = (MyItem) element;
			if (property == FunctionInputDialog.COLUMN_PROPERTIES[3]) {
				item.value.setLength(0);
				item.value.append(value);
			}
			viewer.update(element, null);
		}
	}
}