package de.ugoe.cs.quest.ui.swt;

import java.util.List;
import java.util.logging.Level;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;

import de.ugoe.cs.util.console.CommandExecuter;

/**
 * <p>
 * Main window of the SWT GUI.
 * </p>
 * 
 * @author Steffen Herbold
 * @version 1.0
 */
public class MainWindow {

    private List<String> startupCommands;
    
    private final Level traceLevel;

    protected Shell shlEventbenchConsole;

    protected TabItem consoleTab;
    protected TabItem sequencesTab;
    protected TabItem modelsTab;
    protected TabItem guiModelsTab;
    protected TabItem dataTab;
    protected ConsoleTabComposite consoleTabComposite;
    protected SequencesTabComposite sequencesTabComposite;
    protected ModelsTabComposite modelsTabComposite;
    protected GuiModelTabComposite guiModelTabComposite;
    protected DataTabComposite dataTabComposite;

    protected CommandHistoryDialog historyDialog;

    public MainWindow(List<String> startupCommands, Level traceLevel) {
        this.startupCommands = startupCommands;
        this.traceLevel = traceLevel;
    }

    /**
     * <p>
     * Open the window.
     * </p>
     * 
     * @wbp.parser.entryPoint
     */
    public void open() {
        Display display = Display.getDefault();
        createContents();
        new SWTConsole(consoleTabComposite.textConsoleOutput, traceLevel);
        historyDialog = new CommandHistoryDialog(shlEventbenchConsole, SWT.NONE);
        shlEventbenchConsole.open();
        shlEventbenchConsole.layout();
        for (String command : startupCommands) {
            CommandExecuter.getInstance().exec(command);
        }
        while (!shlEventbenchConsole.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }

    /**
     * <p>
     * Create contents of the window.
     * </p>
     */
    protected void createContents() {
        shlEventbenchConsole = new Shell();
        shlEventbenchConsole.setSize(800, 600);
        shlEventbenchConsole.setText("EventBench Console");
        shlEventbenchConsole.setLayout(new GridLayout(1, false));

        createMenu();
        createTabs();
    }

    /**
     * </p> Creates the menu of the window. </p>
     */
    private void createMenu() {
        Menu menu = new Menu(shlEventbenchConsole, SWT.BAR);
        shlEventbenchConsole.setMenuBar(menu);

        MenuItem mntmFile = new MenuItem(menu, SWT.CASCADE);
        mntmFile.setText("File");

        Menu menu_1 = new Menu(mntmFile);
        mntmFile.setMenu(menu_1);

        MenuItem mntmShowHistory = new MenuItem(menu_1, SWT.NONE);
        mntmShowHistory.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (!historyDialog.isOpen()) {
                    historyDialog.open();
                }
            }
        });
        mntmShowHistory.setText("Show History");

        MenuItem mntmExecBatchFile = new MenuItem(menu_1, SWT.NONE);
        mntmExecBatchFile.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                FileDialog fileDialog = new FileDialog(shlEventbenchConsole, SWT.OPEN);
                String filename = fileDialog.open();
                if (filename != null) {
                    String command = "exec '" + filename + "'";
                    CommandExecuter.getInstance().exec(command);
                }
            }
        });
        mntmExecBatchFile.setText("Exec. Batch File");

        new MenuItem(menu_1, SWT.SEPARATOR);

        MenuItem mntmLoad = new MenuItem(menu_1, SWT.NONE);
        mntmLoad.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                FileDialog fileDialog = new FileDialog(shlEventbenchConsole, SWT.OPEN);
                String filename = fileDialog.open();
                if (filename != null) {
                    String command = "load '" + filename + "'";
                    CommandExecuter.getInstance().exec(command);
                }
            }
        });
        mntmLoad.setText("Load...");

        MenuItem mntmSave = new MenuItem(menu_1, SWT.NONE);
        mntmSave.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                FileDialog fileDialog = new FileDialog(shlEventbenchConsole, SWT.SAVE);
                String filename = fileDialog.open();
                if (filename != null) {
                    String command = "save '" + filename + "'";
                    CommandExecuter.getInstance().exec(command);
                }
            }
        });
        mntmSave.setText("Save...");

        new MenuItem(menu_1, SWT.SEPARATOR);

        MenuItem mntmExit = new MenuItem(menu_1, SWT.NONE);
        mntmExit.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                shlEventbenchConsole.dispose();
            }
        });
        mntmExit.setText("Exit");

        MenuItem mntmHelp = new MenuItem(menu, SWT.CASCADE);
        mntmHelp.setText("Help");

        Menu menu_2 = new Menu(mntmHelp);
        mntmHelp.setMenu(menu_2);

        MenuItem mntmAbout = new MenuItem(menu_2, SWT.NONE);
        mntmAbout.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                AboutDialog aboutDialog = new AboutDialog(shlEventbenchConsole, SWT.NONE);
                aboutDialog.open();
            }
        });
        mntmAbout.setText("About");
    }

    /**
     * <p>
     * Creates the central TabFolder of the window.
     * </p>
     */
    private void createTabs() {
        TabFolder tabFolder = new TabFolder(shlEventbenchConsole, SWT.NONE);
        tabFolder.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (e.item == sequencesTab) {
                    sequencesTabComposite.updateSequenceList();
                }
                else if (e.item == modelsTab) {
                    modelsTabComposite.updateModelList();
                }
                else if (e.item == guiModelsTab) {
                    guiModelTabComposite.updateModelList();
                }
                else if (e.item == dataTab) {
                    dataTabComposite.updateDataList();
                }
            }
        });
        tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

        consoleTab = new TabItem(tabFolder, SWT.NONE);
        consoleTab.setText("Console");

        consoleTabComposite = new ConsoleTabComposite(tabFolder, SWT.NO_BACKGROUND);
        consoleTab.setControl(consoleTabComposite);

        sequencesTab = new TabItem(tabFolder, SWT.NONE);
        sequencesTab.setText("Sequences");

        sequencesTabComposite = new SequencesTabComposite(tabFolder, SWT.NO_BACKGROUND);
        sequencesTab.setControl(sequencesTabComposite);

        modelsTab = new TabItem(tabFolder, SWT.NONE);
        modelsTab.setText("Models");

        modelsTabComposite = new ModelsTabComposite(tabFolder, SWT.NO_BACKGROUND);
        modelsTab.setControl(modelsTabComposite);
        
        guiModelsTab = new TabItem(tabFolder, SWT.NONE);
        guiModelsTab.setText("GUI Models");

        guiModelTabComposite = new GuiModelTabComposite(tabFolder, SWT.NO_BACKGROUND);
        guiModelsTab.setControl(guiModelTabComposite);

        dataTab = new TabItem(tabFolder, SWT.NONE);
        dataTab.setText("Data");

        dataTabComposite = new DataTabComposite(tabFolder, SWT.NO_BACKGROUND);
        dataTab.setControl(dataTabComposite);
    }
}
