package semorg.gui;

import java.sql.SQLException;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;

import semorg.gui.provider.EnumDlg;
import semorg.gui.util.Messages;
import semorg.sql.tables.Enumeration;
import semorg.sql.util.DistinctVector;
import semorg.sql.util.Utility;

/** Provides a window to manage the enumerations such as salutations or titles. */
public class EnumerationWindow {

    /** The window itself. */
    private Shell shell;

    /** The list containing all type of enumerations. */
    private List typeList;

    /**
     * The list containing all values of a specific enumeration type (e.g.
     * salutation).
     */
    private ListViewer valueListViewer;

    /**
     * Creats a new {@link EnumerationWindow} instance using the given
     * parameters.
     * 
     * @param parent
     *                the parent shell of the {@link EnumerationWindow} instance
     */
    public EnumerationWindow(Shell parent) {
	shell = new Shell(parent, SWT.TITLE | SWT.CLOSE | SWT.PRIMARY_MODAL);
	shell.setSize(400, 320);
	shell.setText(Messages.getString("GUIText.EnumerationWindowTitleText"));

	shell.setLayout(new GridLayout(1, false));
	Composite mainComposite = new Composite(shell, SWT.NULL);
	mainComposite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
		| GridData.GRAB_HORIZONTAL));
	mainComposite.setLayout(new GridLayout(2, true));

	Group controlGroup = new Group(mainComposite, SWT.NULL);
	controlGroup.setText(Messages
		.getString("GUIText.ControlGroupEnumerationText"));
	controlGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
		| GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL
		| GridData.GRAB_VERTICAL));
	Group enumGroup = new Group(mainComposite, SWT.NULL);
	enumGroup.setText(Messages
		.getString("GUIText.EnumerationGroupConstantsText"));
	enumGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
		| GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL
		| GridData.GRAB_VERTICAL));
	FillLayout controlLayout = new FillLayout();
	controlLayout.marginHeight = 5;
	controlLayout.marginWidth = 5;
	controlGroup.setLayout(controlLayout);
	typeList = new List(controlGroup, SWT.BORDER | SWT.V_SCROLL);
	typeList.add(Messages.getString("GUIText.TypeListEntrySalutationText"));
	typeList.add(Messages.getString("GUIText.TypeListEntryTitleText"));
	typeList.add(Messages.getString("GUIText.TypeListEntryCountryText"));
	typeList.add(Messages.getString("GUIText.TypeListEntryAnnexText"));

	typeList.addSelectionListener(new SelectionAdapter() {

	    public void widgetSelected(SelectionEvent e) {
		if (typeList.getSelectionIndex() >= 0)
		    ;
		try {
		    valueListViewer.setInput(Enumeration
			    .getVectorFromDB(typeList.getSelectionIndex()));
		} catch (SQLException e1) {
		    e1.printStackTrace();
		}

	    }
	});

	enumGroup.setLayout(new GridLayout(1, false));
	valueListViewer = new ListViewer(enumGroup, SWT.BORDER | SWT.V_SCROLL);
	valueListViewer.setContentProvider(new ArrayContentProvider());
	valueListViewer.setLabelProvider(new LabelProvider() {
	    public String getText(Object element) {
		return ((Enumeration) element).getValue();
	    }
	});
	GridData valueListGridData = new GridData(GridData.FILL_HORIZONTAL);
	valueListGridData.heightHint = 180;
	valueListViewer.getList().setLayoutData(valueListGridData);
	valueListViewer.addDoubleClickListener(new IDoubleClickListener() {

	    public void doubleClick(DoubleClickEvent evt) {
		Enumeration value = (Enumeration) ((StructuredSelection) (valueListViewer
			.getSelection())).getFirstElement();
		onEdit(value);
	    }
	});

	ToolBar buttonToolBar = new ToolBar(enumGroup, SWT.FLAT);
	GridData toolBarGridData = new GridData(GridData.FILL_HORIZONTAL);
	toolBarGridData.horizontalAlignment = GridData.CENTER;
	buttonToolBar.setLayoutData(toolBarGridData);

	ToolItem newItem = new ToolItem(buttonToolBar, SWT.PUSH);
	newItem.setImage(Utility.getImage("new.png"));
	newItem.setData(Utility.ATOSJ_COMPONENT_NAME_KEY, "NewItem");
	newItem.setToolTipText(Messages
		.getString("GUIText.AddNewItemButtonToolTip"));
	newItem.addSelectionListener(new SelectionAdapter() {

	    public void widgetSelected(SelectionEvent event) {
		onNew();
	    }
	});

	ToolItem editItem = new ToolItem(buttonToolBar, SWT.PUSH);
	editItem.setImage(Utility.getImage("edit.png"));
	editItem.setData(Utility.ATOSJ_COMPONENT_NAME_KEY, "EditItem");
	editItem.setToolTipText(Messages
		.getString("GUIText.EditItemButtonToolTip"));
	editItem.addSelectionListener(new SelectionAdapter() {

	    public void widgetSelected(SelectionEvent event) {
		if (!valueListViewer.getSelection().isEmpty()) {
		    Enumeration value = (Enumeration) ((StructuredSelection) (valueListViewer
			    .getSelection())).getFirstElement();
		    onEdit(value);
		}
	    }
	});

	ToolItem deleteItem = new ToolItem(buttonToolBar, SWT.PUSH);
	deleteItem.setImage(Utility.getImage("delete.png"));
	deleteItem.setData(Utility.ATOSJ_COMPONENT_NAME_KEY, "DeleteItem");
	deleteItem.setToolTipText(Messages
		.getString("GUIText.EditItemButtonToolTip"));
	deleteItem.addSelectionListener(new SelectionAdapter() {

	    public void widgetSelected(SelectionEvent event) {
		if (!valueListViewer.getSelection().isEmpty()) {
		    Enumeration value = (Enumeration) ((StructuredSelection) (valueListViewer
			    .getSelection())).getFirstElement();
		    onDelete(value);
		}
	    }
	});

	Button doneButton = new Button(shell, SWT.PUSH);
	GridData doneButtonlayoutData = new GridData();
	doneButtonlayoutData.horizontalIndent = 170;
	doneButton.setLayoutData(doneButtonlayoutData);
	doneButton.setText(Messages.getString("GUIText.DoneButtonText"));
	doneButton.addSelectionListener(new SelectionAdapter() {

	    public void widgetSelected(SelectionEvent event) {
		shell.close();
	    }
	});

	shell.open();
    }

    /**
     * This method is called if a value of a {@link Enumeration} type should be
     * deleted. It also creates a dialog to confirm the deleting.
     * 
     * @param value
     *                the value to delete
     */
    protected void onDelete(Enumeration value) {
	try {
	    if (value.removeFromDB()) {
		DistinctVector<Enumeration> input = (DistinctVector<Enumeration>) valueListViewer
			.getInput();
		input.remove(value);
		valueListViewer.refresh();
	    } else
		MessageDialog
			.openInformation(
				null,
				Messages
					.getString("GUIText.ErrorMessageDialogWindowTitle"),
				Messages
					.getString("GUIText.ErrorMessageDialogUndeletableObjectText"));
	} catch (SQLException e) {
	    e.printStackTrace();
	}
    }

    /**
     * This method gets invoked for creating a new {@link Enumeration}. If an
     * error occurs a error dialog is created to inform the user.
     */
    protected void onNew() {
	if (typeList.getSelectionIndex() >= 0) {

	    EnumDlg dlg = new EnumDlg(shell, null);

	    if (dlg.open() == IDialogConstants.OK_ID) {

		String newValue = dlg.getNewValue();
		try {
		    Enumeration newEnum = Enumeration.createNewEnumInDB(
			    typeList.getSelectionIndex(), newValue);
		    DistinctVector<Enumeration> input = (DistinctVector<Enumeration>) valueListViewer
			    .getInput();
		    input.add(newEnum);
		    valueListViewer.refresh();
		} catch (SQLException e) {
		    MessageDialog
			    .openInformation(
				    null,
				    Messages
					    .getString("GUIText.ErrorMessageDialogWindowTitle"),
				    Messages
					    .getString("GUIText.ErrorMessageDialogUncreatableObjectText"));
		}
	    }
	}

    }

    /**
     * This method gets invoked to change the value of an existing
     * {@link Enumeration}.
     * 
     * @param value the {@link Enumeration} to change.
     */
    protected void onEdit(Enumeration value) {
	String oldValue = value.getValue();

	EnumDlg dlg = new EnumDlg(shell, oldValue);

	if (dlg.open() == IDialogConstants.OK_ID) {

	    String newValue = dlg.getNewValue();

	    try {
		value.setValueInDB(newValue);
		valueListViewer.refresh();
	    } catch (SQLException e) {
		MessageDialog
			.openInformation(
				null,
				Messages
					.getString("GUIText.ErrorMessageDialogWindowTitle"),
				Messages
					.getString("GUIText.ErrorMessageDialogUneditableObjectText"));
	    }
	}

    }

}
