package semorg.gui.list;

import java.sql.SQLException;
import java.util.Vector;

import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Shell;

import semorg.gui.LecturerWindow;
import semorg.gui.MainWindow;
import semorg.gui.provider.PresentationTableProvider;
import semorg.gui.util.AssociationTabControl;
import semorg.gui.util.DBTableChangedListener;
import semorg.gui.util.ForeignKeyConstraintSelector;
import semorg.gui.util.Messages;
import semorg.sql.tables.Presentation;
import semorg.sql.tables.SimpleIDKey;
import semorg.sql.util.DBConstraint;
import semorg.sql.util.DistinctVector;
import semorg.sql.util.Utility;

/**
 * Provides the list window for presentation data records. This class can be
 * instantiated as normal list windows using the menu the {@link MainWindow} as
 * well as popup list windows by the controls {@link AssociationTabControl} and
 * {@link ForeignKeyConstraintSelector}.
 */
public class PresentationListWindow extends ListWindow {

    /** A static instance of the actual list window. */
    public static ListWindow instance;

    /** Instantiates a new list window. */
    private PresentationListWindow() {
	super(MainWindow.getInstance().getShell(), Presentation
		.getColumnsWithSemtype());

	mainTableViewer.setLabelProvider(new PresentationTableProvider());

	shell.setText(Messages
		.getString("GUIText.PresentationListWindowTitleText"));

	update();
    }

    /**
     * Instantiates a new list window as a popup.
     * 
     * @param caller
     *                the {@link AssociationTabControl} instance which wants to
     *                create this list window
     */
    public PresentationListWindow(AssociationTabControl caller) {
	super(caller.getShell(), Presentation.getColumnsWithSemtype(), caller);

	mainTableViewer.setLabelProvider(new PresentationTableProvider());

	shell.setText(Messages
		.getString("GUIText.PopUpPresentationListWindowTitleText"));

	update();
	shell.open();
    }

    /**
     * Instantiates a new list window as a popup.
     * 
     * @param caller
     *                the {@link ForeignKeyConstraintSelector} instance which
     *                wants to create this list window
     */
    public PresentationListWindow(ForeignKeyConstraintSelector caller) {
	super(caller.getShell(), Presentation.getColumnsWithSemtype(), caller);

	mainTableViewer.setLabelProvider(new PresentationTableProvider());

	shell.setText(Messages
		.getString("GUIText.PopUpPresentationListWindowTitleText"));

	update();
	shell.open();
    }

    /**
     * Method unused, because there is no PresentationWindow. It exists only,
     * because it is called by the super constructor.
     */
    protected void createSpecializedMainTableListener() {
	addUpdateListener(DBTableChangedListener.TYPE_PRESENTATION);
	// NOTHING, because there is no PresentationWindow
    }

    /**
     * Adds a listener to the mainTableViewer which inserts the doubleclicked
     * item into the calling {@link AssociationTabControl} instance.
     * 
     * @see semorg.gui.list.ListWindow#createSpecializedMainTableListener(semorg.gui.util.AssociationTabControl)
     */
    protected void createSpecializedMainTableListener(
	    final AssociationTabControl caller) {
	addUpdateListener(DBTableChangedListener.TYPE_PRESENTATION);

	mainTableViewer.addDoubleClickListener(new IDoubleClickListener() {

	    public void doubleClick(DoubleClickEvent event) {
		StructuredSelection selection = (StructuredSelection) event
			.getSelection();
		Presentation selectedItem = (Presentation) selection
			.getFirstElement();

		caller.addSelectedIds(new SimpleIDKey[] { selectedItem }, true);
		shell.close();
	    }
	});

    }

    /**
     * Adds a listener to the mainTableViewer which inserts the doubleclicked
     * item into the calling {@link ForeignKeyConstraintSelector} instance. *
     * 
     * @see semorg.gui.list.ListWindow#createSpecializedMainTableListener(semorg.gui.util.ForeignKeyConstraintSelector)
     */
    protected void createSpecializedMainTableListener(
	    final ForeignKeyConstraintSelector caller) {
	addUpdateListener(DBTableChangedListener.TYPE_PRESENTATION);

	mainTableViewer.addDoubleClickListener(new IDoubleClickListener() {

	    public void doubleClick(DoubleClickEvent event) {
		StructuredSelection selection = (StructuredSelection) event
			.getSelection();
		Presentation selectedItem = (Presentation) selection
			.getFirstElement();
		caller.setSelectedId(selectedItem.getId());
		shell.close();
	    }
	});
    }

    /**
     * Method unused, because there is no non-popup PresentationListWindow. It
     * exists only, because it is called by the super constructor.
     * 
     * @see semorg.gui.list.ListWindow#createSpecializedToolBarListeners()
     */
    protected void createSpecializedToolBarListeners() {
	// NOTHING, because there is no PresentationListWindow as non-popup
    }

    /** @see semorg.gui.list.ListWindow#createChooseButtonListener(semorg.gui.util.AssociationTabControl) */
    protected void createChooseButtonListener(final AssociationTabControl caller) {
	chooseButton.addSelectionListener(new SelectionAdapter() {
	    public void widgetSelected(SelectionEvent e) {
		StructuredSelection selection = (StructuredSelection) mainTableViewer
			.getSelection();
		if (!selection.isEmpty()) {

		    Object[] selectedItems = selection.toArray();
		    SimpleIDKey[] selectedElements = (SimpleIDKey[]) Utility
			    .castArray(selectedItems, SimpleIDKey.class);

		    caller.addSelectedIds(selectedElements, true);
		    shell.close();
		}
	    }
	});
    }

    /**
     * Adds a listener to the mainTableViewer which inserts the doubleclicked
     * item into the calling {@link ForeignKeyConstraintSelector} instance.
     * 
     * @see semorg.gui.list.ListWindow#createSpecializedMainTableListener(semorg.gui.util.ForeignKeyConstraintSelector)
     */
    protected void createChooseButtonListener(
	    final ForeignKeyConstraintSelector caller) {
	chooseButton.addSelectionListener(new SelectionAdapter() {
	    public void widgetSelected(SelectionEvent e) {
		StructuredSelection selection = (StructuredSelection) mainTableViewer
			.getSelection();
		if (!selection.isEmpty()) {
		    Presentation selectedItem = (Presentation) selection
			    .getFirstElement();
		    caller.setSelectedId(selectedItem.getId());
		    shell.close();
		}
	    }
	});
    }

    /** Opens the shell of the static list window instance. */
    public static void openList() {
	instance.shell.open();
    }

    /** @see semorg.gui.list.ListWindow#getTableInputFromDB() */
    protected Object getTableInputFromDB() {
	Vector<DBConstraint> constraints = null;

	// if active, read filter
	if (filterItem.getSelection()) {
	    try {
		constraints = filter.getConstraints();
	    } catch (Exception e) {
		// invalid filter value => switch off the filter
		filterItem.setSelection(false);
	    }
	}

	try {
	    return Presentation.getPresentationVectorFromDB(constraints,
		    sortString);
	} catch (SQLException e) {
	    e.printStackTrace();
	}
	return new DistinctVector<Presentation>();
    }

    /**
     * Creates the static list window instance.
     * 
     * @param parent
     *                the parent shell.
     */
    public static void createWindow(Shell parent) {
	instance = new PresentationListWindow();
    }

}
