package hiro.yoshioka.sql.util;

import hiro.yoshioka.sql.params.ConnectionProperties;
import hiro.yoshioka.sql.params.PropetiesChangeType;
import hiro.yoshioka.sql.util.DBConfigDialog.MODE;
import hiro.yoshioka.util.ImageUtil;
import hiro.yoshioka.util.StringUtil;

import java.io.File;
import java.util.AbstractCollection;

import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

public class DBDefineTableEditor implements SelectionListener {

	TableViewer tableViewer;

	Button addButton;

	Button editButton;

	Button cloneButton;

	Button delButton;

	ConnectionSettingDialog dialog;
	private static String[] HEADER = {
			StringUtil.HALF_SPACE__STRING,
			Messages.getString("DBDefineTableEditor.display"), //$NON-NLS-1$
			Messages.getString("DBDefineTableEditor.host"), //$NON-NLS-1$
			Messages.getString("DBDefineTableEditor.user"), //$NON-NLS-1$
			Messages.getString("DBDefineTableEditor.url"),
			Messages.getString("DBDefineTableEditor.ElapsedTime"), "JDBC Lib" };
	private static int[] HEADER_WIDTH = { 25, 120, 60, 55, 160, 75, 100 };

	private Button createButton(Composite parent, String text, int style) {
		Button ret = new Button(parent, style);
		ret.setText(text);
		return ret;
	}

	public void doEdit(Shell shell) {

		ConnectionProperties p = (ConnectionProperties) ((IStructuredSelection) tableViewer
				.getSelection()).getFirstElement();
		if (p == null) {
			return;
		}
		DBConfigDialog dialog2 = new DBConfigDialog(shell, dialog.listFiles(),
				p, MODE.EDIT);
		if (dialog2.open() == dialog2.OK) {
			dialog.connectionSet.add(dialog2.getConnectionProperties());
			dialog.changedType = PropetiesChangeType.CHANGE;
			refreshTable();
		}

	}

	protected DBDefineTableEditor(ConnectionSettingDialog c_dialog,
			Composite parent) {
		this.dialog = c_dialog;

		tableViewer = getTableViewer(parent);
		if (this.dialog.fConnectionSettingBean != null) {
			Composite btnComposite = new Composite(parent, SWT.NONE);
			btnComposite.setLayout(new RowLayout(SWT.VERTICAL));

			addButton = createButton(btnComposite,
					Messages.getString("DBDefineTableEditor.add"), SWT.NONE); //$NON-NLS-1$
			addButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					DBConfigDialog dialog2 = new DBConfigDialog(e.display
							.getActiveShell(), dialog.listFiles(),
							new ConnectionProperties(), MODE.ADD);
					if (dialog2.open() == dialog2.OK) {
						dialog.getConnectionSet().add(
								dialog2.getConnectionProperties());
						dialog.changedType = PropetiesChangeType.ADD;
						refreshTable();
					}
				}
			});
			editButton = createButton(btnComposite,
					Messages.getString("DBDefineTableEditor.edit"), SWT.NONE); //$NON-NLS-1$
			editButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					doEdit(e.display.getActiveShell());
				}
			});

			cloneButton = createButton(btnComposite,
					Messages.getString("DBDefineTableEditor.clone"), SWT.NONE); //$NON-NLS-1$
			cloneButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					ConnectionProperties p = (ConnectionProperties) ((IStructuredSelection) tableViewer
							.getSelection()).getFirstElement();
					if (p == null) {
						return;
					}
					DBConfigDialog dialog2 = new DBConfigDialog(e.display
							.getActiveShell(), dialog.listFiles(),
							(ConnectionProperties) p.cloneWithoutDBRoot(),
							MODE.CLONE);
					if (dialog2.open() == dialog2.OK) {
						dialog.connectionSet.add(dialog2
								.getConnectionProperties());
						dialog.changedType = PropetiesChangeType.ADD;
						refreshTable();
					}
				}
			});
			delButton = createButton(btnComposite,
					Messages.getString("DBDefineTableEditor.del"), SWT.NONE); //$NON-NLS-1$
			delButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					int delIndex = tableViewer.getTable().getSelectionIndex();
					if (delIndex >= 0) {
						ConnectionProperties con_prop = (ConnectionProperties) tableViewer
								.getTable().getItem(delIndex).getData();
						dialog.changedType = PropetiesChangeType.DELETE;
						dialog.connectionSet.remove(con_prop);
					}
					refreshTable();
				}
			});

		}
	}

	public TableViewer getTableViewer(Composite parent) {

		Table table = new Table(parent, SWT.SINGLE | SWT.H_SCROLL
				| SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);

		tableViewer = new TableViewer(table);

		GridData td = new GridData(GridData.FILL_BOTH);

		table.setLayoutData(td);

		table.setLinesVisible(true);
		table.setHeaderVisible(true);
		table.addSelectionListener(this);

		for (int i = 0; i < HEADER.length; i++) {
			TableColumn column = new TableColumn(table, SWT.NONE);
			column.setText(HEADER[i]);
			column.setWidth(HEADER_WIDTH[i]);
		}
		tableViewer.setColumnProperties(HEADER);
		tableViewer.setContentProvider(new MyTableContentsProvider());
		tableViewer.setLabelProvider(new MyLabelProvider());
		tableViewer.setInput(dialog.connectionSet);

		// TableColumn[] columns = table.getColumns();
		// for (int i = 0; i < columns.length; i++) {
		// columns[i].pack();
		// }

		return tableViewer;
	}

	private void refreshTable() {
		tableViewer.setInput(dialog.connectionSet);
		tableViewer.refresh();
	}

	public void select(ConnectionProperties connectionProperties) {
		tableViewer.setSelection(new StructuredSelection(connectionProperties));
		resetButtonEnabled();
	}

	public void widgetDefaultSelected(SelectionEvent e) {

	}

	private void resetButtonEnabled() {
		if (this.dialog.fConnectionSettingBean != null) {
			int index = tableViewer.getTable().getSelectionIndex();
			int size = tableViewer.getTable().getItemCount();
			boolean en = index >= 0 && size > 0;
			editButton.setEnabled(en);
			cloneButton.setEnabled(en);
			delButton.setEnabled(en);
		}
	}

	public void widgetSelected(SelectionEvent e) {

		if (this.dialog.fConnectionSettingBean == null) {
			Object o = ((IStructuredSelection) tableViewer.getSelection())
					.getFirstElement();
			this.dialog.setSelection((ConnectionProperties) o);
		} else {
			resetButtonEnabled();
		}
		// editButton.setEnabled(index >= 0 && size > 0);
	}

	class MyTableContentsProvider implements IStructuredContentProvider {
		public Object[] getElements(Object element) {
			AbstractCollection<ConnectionProperties> set = (AbstractCollection<ConnectionProperties>) element;
			return (ConnectionProperties[]) set
					.toArray(new ConnectionProperties[set.size()]);
		}

		public void dispose() {
		}

		public void inputChanged(Viewer viewer, Object old_object,
				Object new_object) {
		}
	}

	class MyLabelProvider extends LabelProvider implements ITableLabelProvider {

		public Image getColumnImage(Object element, int columnIndex) {
			ConnectionProperties item = (ConnectionProperties) element;
			String result = StringUtil.EMPTY_STRING;
			switch (columnIndex) {
			case 0:
				if (item.isConnected()) {
					return ImageUtil.getImage(ImageUtil.ACTION_32_CONNECT);
				} else {
					return ImageUtil.getImage(ImageUtil.ACTION_33_DISCONNECT);
				}
			}
			return null;
		}

		public String getColumnText(Object element, int columnIndex) {
			ConnectionProperties item = (ConnectionProperties) element;
			String result = StringUtil.EMPTY_STRING;
			switch (columnIndex) {
			case 0:
				result = StringUtil.HALF_SPACE__STRING;
				break;
			case 1:
				result = item.getDisplayString();
				break;
			case 2:
				result = item.getHost();
				break;
			case 3:
				result = item.getAuthenticate().user;
				break;
			case 4:
				result = item.getURLString();
				break;
			case 5:
				if (item.isConnected()) {
					result = String.format("%,3d(sec)", //$NON-NLS-1$
							item.getElapsedTime() / 1000);
				}
				break;
			case 6:
				if (!item.getDatabaseType().isInternalJar()) {
					if (item.isExistsDriverFile()) {
						result = new File(item.getDriverFilePath()).getName();
					} else {
						result = "<File Not Found>";
					}
				}
				break;
			default:
				break;
			}

			return result;
		}
	}

}
