package hiro.yoshioka.sql.util;

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

import java.io.File;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
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.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;

public class ConnectionSettingDialog extends Dialog {
	Label messageLabel;
	ConnectionSettingBean fConnectionSettingBean;
	Collection<ConnectionProperties> connectionSet;
	PropetiesChangeType changedType;
	ConnectionProperties selectedConnectionProperties;
	private boolean doOpenDBConfigDialog;
	public static final int MODE_NORMAL = 0;
	public static final int MODE_CONNECT_DISCONNECT_STOP = 1;
	public static final int MODE_COMMIT_ROLLBACK = 2;
	int mode = MODE_NORMAL;
	public static final int CONNECT_BUTTON_ID = 200;
	public static final int DIS_CONNECT_BUTTON_ID = 300;
	public static final int REQUEST_CANSEL_BUTTON_ID = 400;
	public static final int COMMIT_BUTTON_ID = 500;
	public static final int ROLLBACK_BUTTON_ID = 600;
	public static final String CONNECT_BUTTON_LABEL = Messages
			.getString("ConnectionSettingDialog.Connect"); //$NON-NLS-1$
	public static final String DIS_CONNECT_BUTTON_LABEL = Messages
			.getString("ConnectionSettingDialog.DisConnect"); //$NON-NLS-1$
	public static final String REQUEST_CANSEL_BUTTON_LABEL = Messages
			.getString("ConnectionSettingDialog.CanselRequest"); //$NON-NLS-1$
	public static final String COMMIT_BUTTON_LABEL = Messages
			.getString("ConnectionSettingDialog.Commit"); //$NON-NLS-1$
	public static final String ROLLBACK_BUTTON_LABEL = Messages
			.getString("ConnectionSettingDialog.Rollback"); //$NON-NLS-1$

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

	public ConnectionSettingDialog(Shell shell,
			ConnectionSettingBean connectionSetBean,
			ConnectionProperties defaultConnection, int mode) {
		super(shell);
		this.mode = mode;
		this.fConnectionSettingBean = connectionSetBean;
		this.selectedConnectionProperties = defaultConnection;
		this.connectionSet = connectionSetBean.getCloneConnectionSet();
		this.myJDBCDriverSet = new LinkedHashSet<String>(
				fConnectionSettingBean.getJdbcDriverFilePathSet());
	}

	public ConnectionSettingDialog(Shell shell,
			Collection<ConnectionProperties> connectionSet,
			ConnectionProperties defaultConnection, int mode) {
		super(shell);
		this.mode = mode;
		this.selectedConnectionProperties = defaultConnection;
		this.connectionSet = connectionSet;
	}

	public void setDoOpenDBConfigDialog(boolean doOpenDBConfigDialog) {
		this.doOpenDBConfigDialog = doOpenDBConfigDialog;
	}

	TableViewer fJarTableViewer;
	Set<String> myJDBCDriverSet;

	DBDefineTableEditor fTableEditor;

	public static String[] COLUMN_PROPERTIES = {
			Messages.getString("ConnectionSettingDialog.0"), Messages.getString("ConnectionSettingDialog.1") }; //$NON-NLS-1$ //$NON-NLS-2$

	boolean createdEditors;

	Spinner fQueryTimeOut;

	Spinner fPort;

	private void createJDBCDriverGroup(Composite inner) {
		Group gr = new Group(inner, SWT.SHADOW_ETCHED_OUT);
		GridLayout gl = new GridLayout(2, false);
		gl.marginHeight = 0;
		gl.marginWidth = 0;
		gl.horizontalSpacing = 0;
		gr.setLayout(gl);
		gr.setText(Messages.getString("ConnectionSettingDialog.2")); //$NON-NLS-1$
		fJarTableViewer = new TableViewer(gr, SWT.SINGLE | SWT.BORDER
				| SWT.V_SCROLL);
		fJarTableViewer.getControl().setLayoutData(
				new GridData(GridData.FILL_BOTH));
		fJarTableViewer.setContentProvider(new IStructuredContentProvider() {
			@Override
			public void inputChanged(Viewer viewer, Object oldInput,
					Object newInput) {
			}

			@Override
			public void dispose() {
			}

			@Override
			public Object[] getElements(Object inputElement) {
				if (inputElement == myJDBCDriverSet) {
					return myJDBCDriverSet.toArray(new String[myJDBCDriverSet
							.size()]);
				}
				return null;
			}
		});
		fJarTableViewer.setInput(myJDBCDriverSet);
		fJarTableViewer.setLabelProvider(new LabelProvider() {
			@Override
			public Image getImage(Object element) {
				if (StringUtil.isEmpty(element)) {
					return null;
				}
				String path = (String) element;
				File f = new File(path);
				System.out.println("path:" + path + "///" + f.exists());
				if (!f.exists()) {
					return ImageUtil.getImage(ImageUtil.ACTION_82_ERROR);
				}
				return super.getImage(element);
			}

			@Override
			public String getText(Object element) {
				return super.getText(element);
			}
		});

		Composite rightCmp = new Composite(gr, SWT.NONE);
		rightCmp.setLayout(new RowLayout(SWT.VERTICAL));
		rightCmp.setLayoutData(new GridData(GridData.FILL_VERTICAL));

		final FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
		Button addButton = new Button(rightCmp, SWT.NONE);
		addButton.setText(Messages.getString("ConnectionSettingDialog.4")); //$NON-NLS-1$
		addButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				String openFile = dialog.open();
				if (openFile != null) {
					myJDBCDriverSet.add(openFile);
					fJarTableViewer.refresh();
				}
			}
		});

		Button delButton = new Button(rightCmp, SWT.NONE);
		delButton.setText(Messages.getString("ConnectionSettingDialog.5")); //$NON-NLS-1$
		delButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				Object o = ((IStructuredSelection) fJarTableViewer
						.getSelection()).getFirstElement();
				if (o != null) {
					myJDBCDriverSet.remove(o);
					fJarTableViewer.refresh();
				}
			}
		});
	}

	@Override
	protected Point getInitialSize() {
		Point p = super.getInitialSize();
		if (p.y < 200) {
			p.y = 200;
		}
		if (p.x < 600) {
			p.x = 600;
		}
		return p;
	}

	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		if (mode == MODE_NORMAL) {
			super.createButtonsForButtonBar(parent);
			if (this.fConnectionSettingBean == null) {
				Button bt = getButton(IDialogConstants.OK_ID);
				if (bt != null) {
					bt.setEnabled(false);
				}
			}
		} else if (mode == MODE_CONNECT_DISCONNECT_STOP) {
			GridLayout layout = (GridLayout) parent.getLayout();
			layout.makeColumnsEqualWidth = false;
			layout.marginWidth = 4;
			layout.marginHeight = 4;
			Button bt = createButton(parent, CONNECT_BUTTON_ID,
					CONNECT_BUTTON_LABEL, false);
			if (bt != null) {
				bt.setImage(ImageUtil.getImage(ImageUtil.ACTION_32_CONNECT));
				bt.setEnabled(false);
			}
			bt = createButton(parent, DIS_CONNECT_BUTTON_ID,
					DIS_CONNECT_BUTTON_LABEL, false);
			if (bt != null) {
				bt.setImage(ImageUtil.getImage(ImageUtil.ACTION_33_DISCONNECT));
				bt.setEnabled(false);
			}
			bt = createButton(parent, REQUEST_CANSEL_BUTTON_ID,
					REQUEST_CANSEL_BUTTON_LABEL, false);
			if (bt != null) {
				bt.setImage(ImageUtil.getImage(ImageUtil.ACTION_39_CANSEL));
				bt.setEnabled(false);
			}
			createButton(parent, IDialogConstants.CANCEL_ID,
					IDialogConstants.CANCEL_LABEL, false);
		} else if (mode == MODE_COMMIT_ROLLBACK) {
			Button bt = createButton(parent, COMMIT_BUTTON_ID,
					COMMIT_BUTTON_LABEL, false);
			if (bt != null) {
				bt.setImage(ImageUtil.getImage(ImageUtil.ACTION_43_GO));
				bt.setEnabled(false);
			}
			bt = createButton(parent, ROLLBACK_BUTTON_ID,
					ROLLBACK_BUTTON_LABEL, false);
			if (bt != null) {
				bt.setImage(ImageUtil.getImage(ImageUtil.ACTION_42_BACK));
				bt.setEnabled(false);
			}
			createButton(parent, IDialogConstants.CANCEL_ID,
					IDialogConstants.CANCEL_LABEL, false);
		}
	}

	@Override
	public void create() {
		super.create();
		resetButtonEnabled();
		if (this.doOpenDBConfigDialog) {
			this.doOpenDBConfigDialog = false;
			fTableEditor.doEdit(getShell());
		}
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		try {
			messageLabel = new Label(parent, SWT.NONE);
			messageLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL)
					.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			if (this.fConnectionSettingBean == null) {
				parent.getShell().setText(
						Messages.getString("ConnectionSettingDialog.6")); //$NON-NLS-1$
			} else {
				parent.getShell().setText(
						Messages.getString("ConnectionSettingDialog.7")); //$NON-NLS-1$
				Composite inner = new Composite(parent, SWT.NONE);
				inner.setLayout(new FillLayout());
				GridData gd3 = new GridData(GridData.FILL_HORIZONTAL);
				inner.setLayoutData(gd3);
				createJDBCDriverGroup(inner);
			}
			// --------------------------------------------------------------
			Group gr = new Group(parent, SWT.SHADOW_ETCHED_OUT);
			gr.setLayoutData(new GridData(GridData.FILL_BOTH));
			GridLayout gl = new GridLayout(2, false);
			gl.marginHeight = 0;
			gl.marginWidth = 0;
			gl.horizontalSpacing = 0;
			gr.setLayout(gl);
			gr.setText(Messages.getString("ConnectionSettingDialog.8")); //$NON-NLS-1$
			fTableEditor = new DBDefineTableEditor(this, gr);
			if (this.selectedConnectionProperties != null) {
				fTableEditor.select(this.selectedConnectionProperties);
			}

			return parent;
		} catch (RuntimeException e) {
			e.printStackTrace();
		}
		return null;
	}

	public String[] listFiles() {
		return myJDBCDriverSet.toArray(new String[myJDBCDriverSet.size()]);
	}

	@Override
	public void okPressed() {
		if (fConnectionSettingBean == null) {
		} else {
			fConnectionSettingBean.setJdbcDriverFilePathSet(listFiles());
		}
		super.okPressed();
	}

	protected void buttonPressed(int buttonId) {
		if (IDialogConstants.OK_ID == buttonId) {

			okPressed();
		} else if (IDialogConstants.CANCEL_ID == buttonId) {
			super.cancelPressed();
		} else {
			setReturnCode(buttonId);
			close();
		}
	}

	public Collection<ConnectionProperties> getConnectionSet() {
		return connectionSet;
	}

	public PropetiesChangeType getChangeType() {
		return changedType;
	}

	public ConnectionProperties getSelectedConnectionProperties() {
		return selectedConnectionProperties;
	}

	public void setSelection(ConnectionProperties connectionProperties) {
		this.selectedConnectionProperties = connectionProperties;
		resetButtonEnabled();
	}

	private void resetButtonEnabled() {
		if (mode == MODE_NORMAL) {
			getButton(IDialogConstants.OK_ID).setEnabled(true);
		} else if (mode == MODE_CONNECT_DISCONNECT_STOP) {
			getButton(DIS_CONNECT_BUTTON_ID).setEnabled(true);
			if (this.selectedConnectionProperties != null) {
				getButton(CONNECT_BUTTON_ID).setEnabled(
						!this.selectedConnectionProperties.isConnected());
				getButton(REQUEST_CANSEL_BUTTON_ID).setEnabled(
						this.selectedConnectionProperties.isConnected());
			}
		} else if (mode == MODE_COMMIT_ROLLBACK) {
			if (this.selectedConnectionProperties != null) {
				if (this.selectedConnectionProperties.isAutoCommit()) {
					setMessage(ImageUtil.getImage(ImageUtil.ACTION_81_WARNING),
							"Now Auto commit mode.");
					getButton(COMMIT_BUTTON_ID).setEnabled(false);
					getButton(ROLLBACK_BUTTON_ID).setEnabled(false);
				} else {
					getButton(COMMIT_BUTTON_ID).setEnabled(
							this.selectedConnectionProperties.isConnected());
					getButton(ROLLBACK_BUTTON_ID).setEnabled(
							this.selectedConnectionProperties.isConnected());
				}
			}
		}
	}

	private void setMessage(Image image, String message) {
		if (image != null) {
			messageLabel.setImage(image);
		}
		messageLabel.setText(message);
	}
}