/*
 *  Copyright (C) 2006-2012  Ronald Blankendaal
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
package org.dbgl.gui;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabFolder2Adapter;
import org.eclipse.swt.custom.CTabFolderEvent;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import swing2swt.layout.BorderLayout;
import org.eclipse.swt.widgets.*;
import org.apache.commons.lang3.StringUtils;
import org.dbgl.connect.Messaging;
import org.dbgl.db.Database;
import org.dbgl.model.DosboxVersion;
import org.dbgl.model.Filter;
import org.dbgl.model.OrderingVector;
import org.dbgl.model.Profile;
import org.dbgl.model.Template;
import org.dbgl.model.conf.Conf;
import org.dbgl.model.conf.SectionsWrapper;
import org.dbgl.model.conf.Settings;
import org.dbgl.swtdesigner.SWTImageManager;
import org.dbgl.util.FileUtils;
import org.dbgl.util.PlatformUtils;
import org.dbgl.util.StringRelatedUtils;


public final class MainWindow {

    public static final String PROGRAM_VERSION = "0.74";
    public static final String PROGRAM_NAME_FULL = "DOSBox Game Launcher";
    public static final String PROGRAM_NAME = PROGRAM_NAME_FULL + " v" + PROGRAM_VERSION;
    public static final int RO_COLUMN_NAMES = 10;
    public static final int EDIT_COLUMN_NAMES = 10;
    
    private static final String[] ICOS_DBGL = { "ico/016.png", "ico/024.png", "ico/032.png",
    	"ico/048.png", "ico/064.png", "ico/128.png", "ico/256.png" };
    
    static String[] columnNames;

    private Display display;
    private Shell shell;
    private OrderingVector orderingVector = null;
    private String filterClause = null;
    private java.util.List<Profile> profilesList;
    private java.util.List<DosboxVersion> dbversionsList;
    private java.util.List<Template> templatesList;
    private java.util.List<Filter> filtersList;
    private Database dbase = null;
    private Settings settings = null;
    private SectionsWrapper ssettings = null;
    private File currentThumbFile = null;
    private int thumbHeight;

    private int[] columnIds;
    private Table profile_table, dbversion_table, template_table;
    private CTabFolder filterFolder;
    private ToolItem setupToolItem;
    private Text notesField;
    private Composite thumbsToolBar;
    private Menu menu_thumb;
    private Link[] link;
    private Menu viewLinkSubMenu;
    private Listener paintListener, measureListener;
    
	
    public void open() {
        dbase = Database.getInstance();
        settings = Settings.getInstance();
        ssettings = settings.getSettings();

        if (PlatformUtils.IS_OSX) Display.setAppName("DBGL");
        display = Display.getDefault();
        createContents();

        Messaging mess = null;
        if (ssettings.getBooleanValue("communication", "port_enabled")) {
            mess = new Messaging(ssettings.getIntValue("communication", "port"), this);
            mess.start();
        }

        shell.open();
        shell.layout();

        profile_table.setSelection(ssettings.getIntValue("gui", "selectedprofile"));
        displayProfileInformation();

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        SWTImageManager.dispose();
        display.dispose();

        if (mess != null) {
            mess.close();
        }

        try {
        	settings.save();
        } catch (IOException e) {
            GeneralPurposeDialogs.warningMessage(shell, e);
        }
        try {
            dbase.shutdown();
        } catch (SQLException e) {
            // nothing we can do
        }
    }
  
    private void createContents() {
        initColumnIds();
        orderingVector = new OrderingVector(ssettings.getIntValues("gui", "sortcolumn"),
                ssettings.getBooleanValues("gui", "sortascending"));
        
        measureListener = new Listener() {
            public void handleEvent(Event event) {
                event.height = Math.max(event.height, ssettings.getIntValue("gui", "screenshotscolumnheight"));
            }
        };
        paintListener = new Listener() {
            public void handleEvent(Event event) {
                Table t = (Table)event.widget;
                Integer sc = (Integer)t.getData();
                if (sc != null && event.index == sc) {
                    File[] files = ((File)((TableItem)event.item).getData()).listFiles();
                    if (files != null && files.length > 0) {
                    	if (PlatformUtils.IS_LINUX) {
                    		Arrays.sort(files, new Comparator<File>() { public int compare(File f1, File f2) { return f1.getName().compareTo(f2.getName()); } });
                    	}
                    	if (FileUtils.isPicture(files[0].getName())) {
	                        Image image = SWTImageManager.getResizedImage(display, ssettings.getIntValue("gui", "screenshotscolumnheight"), files[0].getPath(), null);
	                        int columnWidth = t.getColumn(sc).getWidth();
	                        int offset = Math.max(0, (columnWidth - image.getBounds().width - 2) / 2);
	                        event.gc.drawImage(image, event.x + offset, event.y);
                    	}
                    }
                }
            }
        };

        shell = new Shell();
        shell.setImages(SWTImageManager.getResourceImages(display, ICOS_DBGL));
        
        try {
        	java.util.List<Profile> invalidProfiles = dbase.findInvalidProfiles();
			if (invalidProfiles.size() > 0) {
	        	java.util.List<String> titles = new ArrayList<String>();
	        	for (Profile p: invalidProfiles)
	        		titles.add(p.getTitle());
	        	if (GeneralPurposeDialogs.confirmMessage(shell, 
	        			settings.msg("dialog.main.confirm.removeinvalidprofiles", 
	        					new Object[] { invalidProfiles.size(), StringUtils.join(titles, ", ") }))) {
		        	for (Profile prof: invalidProfiles)
	                    dbase.removeProfile(prof.getId());
	        	}
	        }
			
            dbversionsList = dbase.readDosboxVersionsList();
            templatesList = dbase.readTemplatesList();
            filtersList = dbase.readFiltersList();
            filtersList.add(0, new Filter(-1, settings.msg("dialog.main.allprofiles"), null));
            filterClause = filtersList.get(ssettings.getIntValue("gui", "filtertab")).getFilter();
            profilesList = dbase.readProfilesList(orderingVector.toClause(), filterClause);
        } catch (SQLException e) {
            GeneralPurposeDialogs.warningMessage(shell, e);
        }
        shell.addControlListener(new ControlAdapter() {
            public void controlResized(final ControlEvent event) {
                boolean isMaximized = shell.getMaximized();
                if (!isMaximized) {
                    Rectangle rec = shell.getBounds();
                    ssettings.setIntValue("gui", "width", rec.width);
                    ssettings.setIntValue("gui", "height", rec.height);
                    ssettings.setIntValue("gui", "x", rec.x);
                    ssettings.setIntValue("gui", "y", rec.y);
                }
                ssettings.setBooleanValue("gui", "maximized", isMaximized);
            } });
        shell.addControlListener(new ControlAdapter() {
            public void controlMoved(final ControlEvent event) {
                if (!shell.getMaximized()) {
                    Rectangle rec = shell.getBounds();
                    ssettings.setIntValue("gui", "x", rec.x);
                    ssettings.setIntValue("gui", "y", rec.y);
                }
            } });
        shell.setLayout(new BorderLayout(0, 0));
        shell.setLocation(ssettings.getIntValue("gui", "x"), ssettings.getIntValue("gui", "y"));
        if (ssettings.getBooleanValue("gui", "maximized")) {
            shell.setMaximized(true);
        } else {
            shell.setSize(ssettings.getIntValue("gui", "width"), ssettings.getIntValue("gui", "height"));
        }
        shell.setText(settings.msg("main.title", new Object[] {PROGRAM_VERSION}));

        createFileMenu();
        final TabFolder tabFolder = new TabFolder(shell, SWT.NONE);
        createProfilesTab(tabFolder);
        createDosboxVersionsTab(tabFolder);
        createTemplatesTab(tabFolder);
        
        shell.addShellListener(new ShellListener() {
			public void shellIconified(ShellEvent arg0) {}
			public void shellDeiconified(ShellEvent arg0) {}
			public void shellDeactivated(ShellEvent arg0) {}
			public void shellClosed(ShellEvent arg0) {}
			public void shellActivated(ShellEvent arg0) {
				if (tabFolder.getSelectionIndex() == 0) {
					profile_table.setFocus();
					displayProfileInformation();
				}
			}
		});
        
        // init values
        for (Profile prof: profilesList) {
            addProfileToTable(prof);
        }
        for (DosboxVersion dbversion: dbversionsList) {
            addDosboxVersionToTable(dbversion);
        }
        for (Template template: templatesList) {
            addTemplateToTable(template);
        }

        profile_table.setSortColumn(profile_table.getColumn(findColumnById(ssettings.getIntValues("gui", "sortcolumn")[0])));
        profile_table.setSortDirection(ssettings.getBooleanValues("gui", "sortascending")[0]? SWT.UP: SWT.DOWN);
        profile_table.setColumnOrder(ssettings.getIntValues("gui", "columnorder"));
        profile_table.setFocus();
    }

    private void doReorderProfiles(final int columnId, final SelectionEvent event) {
        TableColumn sortColumn = profile_table.getSortColumn();
        TableColumn currentColumn = (TableColumn) event.widget;
        int dir = profile_table.getSortDirection();
        if (sortColumn.equals(currentColumn)) {
            dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
        } else {
            profile_table.setSortColumn(currentColumn);
            dir = SWT.UP;
        }
        Set<Integer> selectedProfiles = getSelectedProfileIds();
        try {
            orderingVector.addOrdering(columnIds[columnId], dir == SWT.UP);
            profilesList = dbase.readProfilesList(orderingVector.toClause(), filterClause);
        } catch (SQLException e) {
            GeneralPurposeDialogs.warningMessage(shell, e);
        }
        for (int i = 0; i < profilesList.size(); i++) {
            setTableItem(profile_table.getItem(i), profilesList.get(i));
        }
        profile_table.setSortDirection(dir);
		profile_table.setSelection(getIndicesByIds(selectedProfiles));
        ssettings.setIntValues("gui", "sortcolumn", orderingVector.getColumns());
        ssettings.setBooleanValues("gui", "sortascending", orderingVector.getAscendings());
    }

    private void displayLinks(final String[] p_link, final String[] p_linkTitle) {
        for (int i = 0; i < link.length; i++) {
            if (p_link[i] == null || "".equals(p_link[i])) {
                link[i].setText("");
                link[i].setToolTipText(null);
                ((GridData)link[i].getLayoutData()).exclude = true;
                link[i].pack();
                
            } else {
                String url = p_link[i];
                String tag = p_link[i];
                if (url.indexOf("://") == -1) {
                    url = "file://" + FileUtils.canonicalToData(url).getPath();
                    tag = FileUtils.makeRelativeToDosroot(FileUtils.canonicalToData(tag)).getPath();
                }
                if (p_linkTitle[i] != null && !"".equals(p_linkTitle[i]))
                    tag = p_linkTitle[i];
                StringBuffer text = new StringBuffer("<a href=\"").append(url).append("\">").append(tag).append("</a>");
                link[i].setText(text.toString());
                link[i].setToolTipText(url);
                ((GridData)link[i].getLayoutData()).exclude = false;
            }
        }
        link[0].getParent().layout();
        link[0].getParent().getParent().layout();
    }

    private void displayScreenshots(final Profile prof) {
        for (Control c: thumbsToolBar.getChildren()) {
            c.setMenu(null);
            c.dispose();
        }
        thumbsToolBar.pack();
        if (prof != null) {
            File path = prof.getCanonicalCaptures();
            File[] files = path.listFiles();
            if (files != null) {
            	if (PlatformUtils.IS_LINUX) {
            		Arrays.sort(files, new Comparator<File>() { public int compare(File f1, File f2) { return f1.getName().compareTo(f2.getName()); } });
            	}
                for (File file: files) {
                    String label = file.getName().toLowerCase();
                    if (FileUtils.isPicture(label)) {
                        if (ssettings.getBooleanValue("gui", "screenshotsfilename")) {
                            label = ' ' + label.substring(0, label.lastIndexOf('.')) + ' ';
                        } else {
                            label = null;
                        }
                        final Button buttonItem = new Button(thumbsToolBar, SWT.FLAT);
                        buttonItem.setToolTipText(file.getPath());
                        buttonItem.setImage(SWTImageManager.getResizedImage(display, thumbHeight, file.getPath(), label));
                        buttonItem.pack();
                        buttonItem.addSelectionListener(new SelectionAdapter() {
                            public void widgetSelected(final SelectionEvent event) {
                                final Thumb thumbDialog = new Thumb(shell);
                                thumbDialog.setThumb(buttonItem.getToolTipText());
                                thumbDialog.open();
                            }
                        });
                        buttonItem.addMouseListener(new MouseAdapter() {
                            public void mouseDown(MouseEvent arg0) {
                                currentThumbFile = new File(buttonItem.getToolTipText());
                            }
                        });
                        buttonItem.setMenu(menu_thumb);
                    }
                }
            }
        }
        thumbsToolBar.setVisible(thumbsToolBar.getChildren().length != 0);
        thumbsToolBar.pack();
    }

    private void doAddProfile() {
        doAddProfile(null);
    }

    private void doAddProfile(final String filename) {
        if (checkDefaultDBVersion() == null) {
            return;
        }
        if (filename == null || FileUtils.isBooterImage(filename) || FileUtils.isExecutable(filename)
                || FileUtils.isConfFile(filename)) {
            EditProfileDialog addProfileDialog = new EditProfileDialog(shell);
            if (filename != null) addProfileDialog.sendToProfile(filename);
            updateWithAddedProfile((Profile) addProfileDialog.open());
        } else if (FileUtils.isArchive(filename)) {
            ImportDialog importDialog = new ImportDialog(shell, dbversionsList, new File(filename));
            Boolean updateCustomFields = (Boolean)importDialog.open();
            if (updateCustomFields != null) {
            	if (updateCustomFields) {
            		rebuildProfilesTable();
            	} else {
            		updateProfilesList(getSelectedProfileIds());
            	}
                displayProfileInformation();
            }
        } else {
            GeneralPurposeDialogs.warningMessage(shell, settings.msg("general.error.cannotimportunknownfile"));
        }
    }

    public void addProfile(final String file) {
        display.syncExec(new Runnable() {
            public void run() {
                doAddProfile(file);
            }
        });
    }

    private void doAddDosboxVersion() {
        final EditDosboxVersionDialog addVersionDialog = new EditDosboxVersionDialog(shell);
        DosboxVersion dbversion = (DosboxVersion)addVersionDialog.open();
        if (dbversion != null) {
            updateDosboxVersionList(dbversion);
        }
    }

    private void doAddTemplate() {
        if (checkDefaultDBVersion() == null) {
            return;
        }
        final EditTemplateDialog addTemplateDialog = new EditTemplateDialog(shell);
        Template template = (Template)addTemplateDialog.open();
        if (template != null) {
            updateTemplateList(template);
        }
    }

    private void doAddFilter() {
        final EditFilterDialog addFilterDialog = new EditFilterDialog(shell);
        if (profile_table.getSelectionCount() > 1)
        	addFilterDialog.setIds(getSelectedProfileIds());
        Filter filter = (Filter)addFilterDialog.open();
        if (filter != null) {
        	filtersList.add(filter);
        	addFilterTab(filter);
        	filterFolder.setSelection(filterFolder.getItemCount() - 1);
        	updateProfilesAfterTabAction();
        }
    }

    private void doToggleFavoriteProfile() {
        int index = profile_table.getSelectionIndex();
        if (index != -1) {
            Profile profile = profilesList.get(index);
            try {
                dbase.toggleFavorite(profile.getId());
            } catch (SQLException e) {
                GeneralPurposeDialogs.warningMessage(shell, e);
            }
            profile.toggleDefault();
            profilesList.set(index, profile);
            setTableItem(profile_table.getItem(index), profile);
        }
    }

    private void doToggleDefaultVersion() {
        int index = dbversion_table.getSelectionIndex();
        if (index != -1) {
            DosboxVersion ver = dbversionsList.get(index);
            ver.toggleDefault();
            try {
                dbase.addOrEditDosboxVersion(ver.getTitle(), ver.getPath(), ver.getConf(), ver.isMultiConfig(), ver.isUsingCurses(), 
                		ver.isDefault(), ver.getParameters(), ver.getVersion(), ver.getId());
            } catch (SQLException e) {
                GeneralPurposeDialogs.warningMessage(shell, e);
            }
            updateDosboxVersionList(ver);
        }
    }

    private void doToggleDefaultTemplate() {
        int index = template_table.getSelectionIndex();
        if (index != -1) {
            Template temp = templatesList.get(index);
            temp.toggleDefault();
            try {
                dbase.addOrEditTemplate(temp.getTitle(), temp.getDbversionId(), temp.isDefault(), temp.getId());
            } catch (SQLException e) {
                GeneralPurposeDialogs.warningMessage(shell, e);
            }
            updateTemplateList(temp);
        }
    }

    private void doEditProfile() {
        doEditProfile(false);
    }

    private void doEditProfile(final boolean focusTitle) {
        int index = profile_table.getSelectionIndex();
        if (index != -1) {
            if (profile_table.getSelectionCount() > 1) {
                ProfileLoader pLoader = new ProfileLoader(shell, getSelectedProfiles(), true);
                if (pLoader.open() != null) {
                	final EditProfileDialog editMultiProfileDialog = new EditProfileDialog(shell);
	                editMultiProfileDialog.setConfigurables(pLoader.getResultAsConfigurables());
	                editMultiProfileDialog.setMultiProfileCombined(pLoader.getMultiProfileCombined());
	                if (editMultiProfileDialog.open() != null) {
	                    updateProfilesList(getSelectedProfileIds());
	                    displayProfileInformation();
	                }
                }
            } else {
                final EditProfileDialog editProfileDialog = new EditProfileDialog(shell);
                editProfileDialog.setProfile(profilesList.get(index));
                if (focusTitle) {
                    editProfileDialog.focusTitle();
                }
                Profile profile = (Profile)editProfileDialog.open();
                if (profile != null) {
                    boolean quickUpdate = true;
                    if (ssettings.getBooleanValue("gui", "autosortonupdate") || (filterFolder.getSelectionIndex() > 0)) {
                        try {
                            profilesList = dbase.readProfilesList(orderingVector.toClause(), filterClause);
                            if (index != Profile.findIndexById(profilesList, profile.getId())) {
                                quickUpdate = false;
                            }
                        } catch (SQLException e) {
                            GeneralPurposeDialogs.warningMessage(shell, e);
                        }
                    }
                    if (quickUpdate) {
                        profilesList.set(index, profile);
                        setTableItem(profile_table.getItem(index), profile);
                    } else {
                        updateProfilesList(new HashSet<Integer>(Arrays.asList(profile.getId())));
                    }
                    displayProfileInformation();
                }
            }
        }
    }

    private void doDuplicateProfile() {
        int index = profile_table.getSelectionIndex();
        if (index != -1) {
            Profile orgProf = profilesList.get(index);
            updateWithAddedProfile(EditProfileDialog.duplicateProfile(orgProf, dbversionsList, dbase, shell));
        }
    }

    private void updateWithAddedProfile(final Profile profile) {
        if (profile != null) {
            if (ssettings.getBooleanValue("gui", "autosortonupdate") || (filterFolder.getSelectionIndex() > 0)) {
                updateProfilesList(new HashSet<Integer>(Arrays.asList(profile.getId())));
            } else {
                profilesList.add(profile);
                addProfileToTable(profile);
                profile_table.setSelection(profile_table.getItemCount() - 1);
                profile_table.setFocus();
            }
            displayProfileInformation();
        }
    }

    private void doEditDosboxVersion() {
        int index = dbversion_table.getSelectionIndex();
        if (index != -1) {
            final EditDosboxVersionDialog editVersionDialog = new EditDosboxVersionDialog(shell);
            editVersionDialog.setDosboxVersion(dbversionsList.get(index));
            DosboxVersion dbversion = (DosboxVersion)editVersionDialog.open();
            if (dbversion != null) {
                updateDosboxVersionList(dbversion);
            }
        }
    }

    private void doEditFilter() {
        int index = filterFolder.getSelectionIndex();
        if (index > 0) {
            final EditFilterDialog editFilterDialog = new EditFilterDialog(shell);
            editFilterDialog.setFilter(filtersList.get(index));
            Filter filter = (Filter)editFilterDialog.open();
            if (filter != null) {
            	filtersList.set(index, filter);
            	filterFolder.getSelection().setText("    " + filter.getTitle() + "    ");
            	updateProfilesAfterTabAction();
            }
        }
    }

    private void updateProfilesList(final Set<Integer> profileIds) {
        try {
            profilesList = dbase.readProfilesList(orderingVector.toClause(), filterClause);
        } catch (SQLException e) {
            GeneralPurposeDialogs.warningMessage(shell, e);
        }
        profile_table.setRedraw(false);
        profile_table.removeAll();
        for (Profile prof: profilesList) {
            addProfileToTable(prof);
        }
       	profile_table.setSelection(getIndicesByIds(profileIds));
        profile_table.setRedraw(true);
        profile_table.setFocus();
    }

    private void updateDosboxVersionList(final DosboxVersion dbversion) {
        try {
            dbversionsList = dbase.readDosboxVersionsList();
        } catch (SQLException e) {
            GeneralPurposeDialogs.warningMessage(shell, e);
        }
        dbversion_table.removeAll();
        for (DosboxVersion version: dbversionsList) {
            addDosboxVersionToTable(version);
        }
        dbversion_table.setSelection(DosboxVersion.findIndexById(dbversionsList, dbversion.getId()));
        dbversion_table.setFocus();
    }

    private void updateTemplateList(final Template template) {
        try {
            templatesList = dbase.readTemplatesList();
        } catch (SQLException e) {
            GeneralPurposeDialogs.warningMessage(shell, e);
        }
        template_table.removeAll();
        for (Template temp: templatesList) {
            addTemplateToTable(temp);
        }
        template_table.setSelection(Template.findIndexById(templatesList, template.getId()));
        template_table.setFocus();
    }

    private void doEditTemplate() {
        int index = template_table.getSelectionIndex();
        if (index != -1) {
            final EditTemplateDialog editTemplDialog = new EditTemplateDialog(shell);
            editTemplDialog.setTemplate(templatesList.get(index));
            Template template = (Template)editTemplDialog.open();
            if (template != null) {
                updateTemplateList(template);
            }
        }
    }

    private void doRemoveProfile() {
        int index = profile_table.getSelectionIndex();
        if ((index != -1)) {
        	DeleteProfilesDialog dpDialog = new DeleteProfilesDialog(shell);
    		dpDialog.setProfilesToBeDeleted(getSelectedProfiles(), dbversionsList);
    		if (dpDialog.open() != null) {
    			int[] idxs = profile_table.getSelectionIndices();
    			Arrays.sort(idxs);
    			for (int i = idxs.length - 1; i >= 0; i--) {
    				profile_table.remove(idxs[i]);
    				profilesList.remove(idxs[i]);
    			}
    			if (idxs[0] > 0)
    				profile_table.setSelection(idxs[0] - 1);
    			displayProfileInformation();
    			SWTImageManager.dispose();
    		}
        }
    }

    private void doRemoveDosboxVersion() {
        int index = dbversion_table.getSelectionIndex();
        if ((index != -1) && GeneralPurposeDialogs.confirmMessage(shell, settings.msg("dialog.main.confirm.removedosboxversion"))) {
            try {
                dbase.removeDosboxVersion((dbversionsList.get(index)).getId());
                dbversion_table.remove(index);
                dbversionsList.remove(index);
            } catch (SQLException e) {
                GeneralPurposeDialogs.warningMessage(shell, e);
            }
        }
    }

    private void doRemoveTemplate() {
        int index = template_table.getSelectionIndex();
        if ((index != -1) && GeneralPurposeDialogs.confirmMessage(shell, settings.msg("dialog.main.confirm.removetemplate"))) {
            int templateId = (templatesList.get(index)).getId();
            try {
                dbase.removeTemplate(templateId);
                template_table.remove(index);
                templatesList.remove(index);
                File conffile = FileUtils.constructCanonicalTemplateFileLocation(templateId);
                if (GeneralPurposeDialogs.confirmMessage(shell, settings.msg("dialog.main.confirm.removetemplateconf", new Object[] {conffile}))) {
                    FileUtils.removeFile(conffile);
                }
            } catch (SQLException e) {
                GeneralPurposeDialogs.warningMessage(shell, e);
            }
        }
    }

    private void addProfileToTable(final Profile prof) {
        final TableItem newItemTableItem = new TableItem(profile_table, SWT.BORDER); 
        setTableItem(newItemTableItem, prof);
    }

    private void addDosboxVersionToTable(final DosboxVersion dbversion) {
        final TableItem newItemTableItem = new TableItem(dbversion_table, SWT.BORDER); 
        setTableItem(newItemTableItem, dbversion);
    }

    private void addTemplateToTable(final Template template) {
        final TableItem newItemTableItem = new TableItem(template_table, SWT.BORDER); 
        setTableItem(newItemTableItem, template);
    }

    private void setTableItem(final TableItem newItemTableItem, final Profile prof) {
        for (int i = 0; i < columnIds.length; i++) {
            String value;
            switch (columnIds[i]) {
                case 0: value = prof.getTitle(); break;
                case 1: value = prof.hasSetupString(); break;
                case 2: value = prof.getDeveloperName(); break;
                case 3: value = prof.getPublisherName(); break;
                case 4: value = prof.getGenre(); break;
                case 5: value = prof.getYear(); break;
                case 6: value = prof.getStatus(); break;
                case 7: value = prof.isDefaultString(); break;
                case 8: value = String.valueOf(prof.getId()); break;
                case 9: value = String.valueOf(prof.getDbversionId()); break;
                case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17:
                    value = prof.getCustomString(columnIds[i] - RO_COLUMN_NAMES); break;
                case 18:value = prof.getCustomInt(0) + " %"; break;
                case 19:value = String.valueOf(prof.getCustomInt(1)); break;
                case 21: value = DosboxVersion.findById(dbversionsList, prof.getDbversionId()).getTitle(); break;
                default:value = "";
            }
            if (columnIds[i] == 20) {
                newItemTableItem.setData(prof.getCanonicalCaptures());
            } else {
                newItemTableItem.setText(i, value);
            }
        }
    }

    private void setTableItem(final TableItem newItemTableItem, final DosboxVersion dbversion) {
        newItemTableItem.setText(0, dbversion.getTitle());
        newItemTableItem.setText(1, dbversion.getVersion());
        newItemTableItem.setText(2, dbversion.getPath());
        newItemTableItem.setText(3, dbversion.isDefaultString());
        newItemTableItem.setText(4, String.valueOf(dbversion.getId()));
    }

    private void setTableItem(final TableItem newItemTableItem, final Template template) {
        newItemTableItem.setText(0, template.getTitle());
        newItemTableItem.setText(1, template.isDefaultString());
    }

    private void doRunProfile(final int setup, final boolean prepareOnly) {
        int index = profile_table.getSelectionIndex();
        if (index != -1) {
            Profile prof = profilesList.get(index);
            if (setup == -1 || prof.hasSetup(setup)) {
                try {
                    FileUtils.doRunProfile(prof, dbversionsList, getEnv(ssettings), setup, prepareOnly);
                } catch (IOException e) {
                    GeneralPurposeDialogs.warningMessage(shell, e);
                }
            }
        }
    }

    private void doRunDosbox() {
        int index = dbversion_table.getSelectionIndex();
        if (index != -1) {
            try {
                FileUtils.doRunDosbox(dbversionsList.get(index), getEnv(ssettings));
            } catch (IOException e) {
                GeneralPurposeDialogs.warningMessage(shell, e);
            }
        }
    }

    private void doRunTemplate() {
        int index = template_table.getSelectionIndex();
        if (index != -1) {
            Template template = templatesList.get(index);
            try {
                FileUtils.doRunTemplate(template, dbversionsList, getEnv(ssettings));
            } catch (IOException e) {
                GeneralPurposeDialogs.warningMessage(shell, e);
            }
        }
    }

    private DosboxVersion checkDefaultDBVersion() {
        DosboxVersion dbv = DosboxVersion.findDefault(dbversionsList);
        if (dbv == null) {
            GeneralPurposeDialogs.infoMessage(shell,settings.msg("dialog.main.required.defaultdosboxversion"));
        }
        return dbv;
    }

    private void doDFendImport() {
        DosboxVersion defaultDbversion = checkDefaultDBVersion();
        if (defaultDbversion == null) {
            return;
        }

        if (ssettings.getIntValue("profiledefaults", "confpath") == 1) {
            GeneralPurposeDialogs.infoMessage(shell, settings.msg("dialog.main.notice.dfendimportconflocation",
                    new Object[] {SettingsDialog.confLocations[0]}));
        }

        DFendImportDialog importDialog = new DFendImportDialog(shell);
        importDialog.setDefaultDosboxVersion(defaultDbversion);
        if (importDialog.open() != null) {
            try {
                profilesList = dbase.readProfilesList(orderingVector.toClause(), filterClause);
                profile_table.removeAll();
                for (Profile prof: profilesList) {
                    addProfileToTable(prof);
                }
            } catch (SQLException e) {
                GeneralPurposeDialogs.warningMessage(shell, e);
            }
        }
    }

    private void doMigrate() {
        GeneralPurposeDialogs.infoMessage(shell, settings.msg("dialog.main.notice.premigration"));
        String from = (String) new MigrateDialog(shell).open();
        if (from != null) {
            GeneralPurposeDialogs.infoMessage(shell, settings.msg("dialog.main.notice.postmigration",
                    new Object[] {from, FileUtils.getDosRoot()}));
        }
    }

    private void displayProfileInformation() {
        int index = profile_table.getSelectionIndex();
        if (index == -1) {
            displayScreenshots(null);
            notesField.setText("");
            displayLinks(new String[] {null, null, null, null, null, null, null, null}, new String[] {null, null, null, null, null, null, null, null});
            updateViewLinkSubmenu(null);
        } else {
            ssettings.setIntValue("gui", "selectedprofile", index);
            Profile prof = profilesList.get(index);
            displayScreenshots(prof);
            notesField.setText(prof.getNotes());
            displayLinks(prof.getLinks(), prof.getLinkTitles());
            updateViewLinkSubmenu(prof);
            setupToolItem.setEnabled(profilesList.get(profile_table.getSelectionIndex()).hasSetup(0));
        }
    }

    private void doRemoveThumb() {
        if (GeneralPurposeDialogs.confirmMessage(shell, settings.msg("dialog.main.confirm.removethumb", new Object[] {currentThumbFile}))) {
            FileUtils.removeFile(currentThumbFile);
            displayProfileInformation();
        }
        currentThumbFile = null;
    }

    private void doCreateShortcut() {
        int[] selectedProfiles = profile_table.getSelectionIndices();
        for (int i = 0; i < selectedProfiles.length; i++) {
            try {
				PlatformUtils.createShortcut(profilesList.get(selectedProfiles[i]), dbversionsList);
			} catch (IOException e) {
				GeneralPurposeDialogs.warningMessage(shell, e);
			}
        }
    }

    private void addProfileColumn(final String title, final int colIndex) {
        final String width = "column" + (columnIds[colIndex] + 1) + "width";
        final TableColumn column = new TableColumn(profile_table, SWT.NONE);
        column.setWidth(ssettings.getIntValue("gui", width));
        column.setMoveable(true);
        column.setText(title);
        if ((columnIds[colIndex] == 8) || (columnIds[colIndex] == 9) ||
                (columnIds[colIndex] == 18) || (columnIds[colIndex] == 19)) { // numeric values
            column.setAlignment(SWT.RIGHT);
        }
        if ((columnIds[colIndex] == 20)) { // screenshot
            column.setAlignment(SWT.CENTER);
            profile_table.setData(colIndex);
            profile_table.addListener(SWT.MeasureItem, measureListener);
            profile_table.addListener(SWT.PaintItem, paintListener);
        }
        column.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
                doReorderProfiles(colIndex, event);
            }
        });
        column.addControlListener(new ControlAdapter() {
            public void controlResized(final ControlEvent event) {
                ssettings.setIntValue("gui", width, column.getWidth());
            }
            public void controlMoved(final ControlEvent event) {
            	if (event.time != 0) // workaround for buggy SWT behavior in GTK
            		ssettings.setIntValues("gui", "columnorder", profile_table.getColumnOrder());
            }
        });
    }

    private void addDBColumn(final String title, final int colIndex) {
        final String width = "column2_" + (colIndex + 1) + "width";
        final TableColumn column = new TableColumn(dbversion_table, SWT.NONE);
        column.setWidth(ssettings.getIntValue("gui", width));
        column.setText(title);
        column.addControlListener(new ControlAdapter() {
            public void controlResized(final ControlEvent event) {
                ssettings.setIntValue("gui", width, column.getWidth());
            }
        });
    }

    private void addTemplateColumn(final String title, final int colIndex) {
        final String width = "column3_" + (colIndex + 1) + "width";
        final TableColumn column = new TableColumn(template_table, SWT.NONE);
        column.setWidth(ssettings.getIntValue("gui", width));
        column.setText(title);
        column.addControlListener(new ControlAdapter() {
            public void controlResized(final ControlEvent event) {
                ssettings.setIntValue("gui", width, column.getWidth());
            }
        });
    }

    private void doOpenSettingsDialog() {
        SettingsDialog sDialog = new SettingsDialog(shell);
        if (((Boolean)sDialog.open())) {
            rebuildProfilesTable();
        }
        notesField.setFont(GeneralPurposeGUI.stringToFont(display, notesField.getFont(), ssettings.getValues("gui", "notesfont")));
    }

	private void rebuildProfilesTable() {
		// first, store current table properties
		Set<Integer> selectedProfiles = getSelectedProfileIds();
		int nrColumns = profile_table.getColumnCount();
		String order = ssettings.getValue("gui", "columnorder");

		// then clean the table, reset column order and dispose all columns
		profile_table.removeAll();
		StringBuffer cols = new StringBuffer();
		for (int i = 0; i < nrColumns; i++) {
		    cols.append(i).append(' ');
		}
		profile_table.setColumnOrder(StringRelatedUtils.stringToIntArray(cols.toString()));
		for (int i = nrColumns - 1; i >= 0; i--) {
		    profile_table.getColumn(i).dispose();
		}
		profile_table.setData(null);
		profile_table.removeListener(SWT.MeasureItem, measureListener);
		profile_table.removeListener(SWT.PaintItem, paintListener);

		// next, recreate column ids and add selected columns to table
		initColumnIds();
		for (int i = 0; i < columnIds.length; i++) {
		    addProfileColumn(columnNames[columnIds[i]], i);
		}

		// redefine sort column in table
		profile_table.setSortColumn(profile_table.getColumn(findColumnById(ssettings.getIntValues("gui", "sortcolumn")[0])));
		profile_table.setSortDirection(ssettings.getBooleanValues("gui", "sortascending")[0]? SWT.UP: SWT.DOWN);

		// restore saved columnorder since disposing and adding columns invalidates that
		ssettings.setValue("gui", "columnorder", order);

		// also reset orderingvector
		orderingVector = new OrderingVector(ssettings.getIntValues("gui", "sortcolumn"),
		        ssettings.getBooleanValues("gui", "sortascending"));
		
		// finally, refill table with data
		updateProfilesList(selectedProfiles);
	}

    private void doImportConfigfile() {
        FileDialog dialog = new FileDialog (shell, SWT.OPEN);
        dialog.setFilterNames (new String [] { settings.msg("filetype.conf"),
                settings.msg("filetype.exe") + ", " + settings.msg("filetype.booterimage"), FileUtils.ALL_FILTER});
        dialog.setFilterExtensions (new String [] {FileUtils.CNF_FILTER, 
                FileUtils.EXE_FILTER + ";" + FileUtils.BTR_FILTER, FileUtils.ALL_FILTER});
        String result = dialog.open();
        if (result != null) {
            doAddProfile(result);
        }
    }

    private void initColumnIds() {
        columnNames = new String[RO_COLUMN_NAMES + EDIT_COLUMN_NAMES + 2];
        columnNames[0] = settings.msg("dialog.main.profiles.column.title");
        columnNames[1] = settings.msg("dialog.main.profiles.column.setup");
        columnNames[2] = settings.msg("dialog.main.profiles.column.developer");
        columnNames[3] = settings.msg("dialog.main.profiles.column.publisher");
        columnNames[4] = settings.msg("dialog.main.profiles.column.genre");
        columnNames[5] = settings.msg("dialog.main.profiles.column.year");
        columnNames[6] = settings.msg("dialog.main.profiles.column.status");
        columnNames[7] = settings.msg("dialog.main.profiles.column.favorite");
        columnNames[8] = settings.msg("dialog.main.profiles.column.id");
        columnNames[9] = settings.msg("dialog.main.profiles.column.dosboxversionid");
        for (int i = 0; i < EDIT_COLUMN_NAMES; i++) {
            columnNames[i + RO_COLUMN_NAMES] = ssettings.getValue("gui", "custom" + (i + 1));
        }
        columnNames[RO_COLUMN_NAMES + EDIT_COLUMN_NAMES] = settings.msg("dialog.main.profiles.column.screenshot");
        columnNames[RO_COLUMN_NAMES + EDIT_COLUMN_NAMES + 1] = settings.msg("dialog.main.profiles.column.dosboxversiontitle");
        
        int amount = 0;
        for (int i = 0; i < columnNames.length; i++) {
            if (ssettings.getBooleanValue("gui", "column" + (i + 1) + "visible")) {
                amount++;
            }
        }

        int cNr = 0;
        columnIds = new int[amount];
        for (int i = 0; i < columnNames.length; i++) {
            if (ssettings.getBooleanValue("gui", "column" + (i + 1) + "visible")) {
                columnIds[cNr++] = i;
            }
        }
    }

    private int findColumnById(final int id) {
        for (int i = 0; i < columnIds.length; i++) {
            if (columnIds[i] == id) {
                return i;
            }
        }
        return -1;
    }

    private Menu createDosboxVersionsSubmenu(final Menu parent, final int setup, final boolean prepareOnly) {
    	final Menu dosboxVersionsSubMenu = new Menu(parent);
        for (int i = 0; i < dbversionsList.size(); i++) {
            final MenuItem menuItem = new MenuItem(dosboxVersionsSubMenu, SWT.NONE);
            menuItem.setText(dbversionsList.get(i).getTitle());
            menuItem.addSelectionListener(new SelectionAdapter() {
                public void widgetSelected(final SelectionEvent event) {
                    int index = profile_table.getSelectionIndex();
                    if (index != -1) {
                        Profile prof = profilesList.get(index);
                        DosboxVersion dbversion = dbversionsList.get(dosboxVersionsSubMenu.indexOf(menuItem));
                        try {
                            FileUtils.doRunProfile(prof, dbversion, getEnv(ssettings), setup, prepareOnly);
                        } catch (IOException e) {
                            GeneralPurposeDialogs.warningMessage(shell, e);
                        }
                    }
                }
            });
        }
        return dosboxVersionsSubMenu;
    }
    
    private void updateViewLinkSubmenu(final Profile prof) {
        MenuItem parent = viewLinkSubMenu.getParentItem();
        viewLinkSubMenu.dispose();
        viewLinkSubMenu = new Menu(parent);
        parent.setMenu(viewLinkSubMenu);
        
        if (prof != null) {
            for (int i = 0; i < prof.getLinks().length; i++) {
                String link = prof.getLink(i);
                if (link.length() > 0) {
                    final MenuItem linkMenuItem = new MenuItem(viewLinkSubMenu, SWT.NONE);
                    String url = link;
                    String tag = link;
                    if (url.indexOf("://") == -1) {
                        url = "file://" + FileUtils.canonicalToData(url).getPath();
                        tag = FileUtils.makeRelativeToDosroot(FileUtils.canonicalToData(tag)).getPath();
                    }
                    String title = prof.getLinkTitle(i);
                    if (title != null && !"".equals(title))
                        tag = title;
                    linkMenuItem.setData(url);
                    linkMenuItem.setText(StringUtils.abbreviateMiddle(tag, "....", 80));
                    linkMenuItem.addSelectionListener(new SelectionAdapter() {
                        public void widgetSelected(final SelectionEvent event) {
                            PlatformUtils.openForBrowsing((String)linkMenuItem.getData());
                        }
                    });
                }
            }
            final MenuItem linkMenuItem = new MenuItem(viewLinkSubMenu, SWT.NONE);
            linkMenuItem.setText(settings.msg("dialog.main.profile.view.conf"));
            linkMenuItem.addSelectionListener(new SelectionAdapter() {
                public void widgetSelected(final SelectionEvent event) {
                    PlatformUtils.openForEditing(prof.getCanonicalConfFile());
                }
            });
        }
    }
    
    private void doExportProfilesList() {
        new ExportListDialog(shell, dbversionsList, profilesList).open();
    }
    
    private void createProfilesTab(TabFolder tabFolder) {
    	final TabItem profilesTabItem = new TabItem(tabFolder, SWT.NONE);
        profilesTabItem.setText(settings.msg("dialog.main.profiles"));

        final Composite composite = new Composite(tabFolder, SWT.NONE);
        composite.setLayout(new BorderLayout(0, 0));
        profilesTabItem.setControl(composite);

        final ToolBar toolBar = new ToolBar(composite, SWT.HORIZONTAL);
        toolBar.setLayoutData(BorderLayout.NORTH);

        final SelectionAdapter addProfAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doAddProfile(); } };
        final SelectionAdapter editProfAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doEditProfile(); } };
        final SelectionAdapter removeProfAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doRemoveProfile(); } };
        final SelectionAdapter setupProfAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doRunProfile(0, false); } };
        final SelectionAdapter addWizardAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doStartGameWizard(); } };
        final SelectionAdapter runProfAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doRunProfile(-1, false); } };
        final SelectionAdapter prepareProfAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doRunProfile(-1, true); } };
        final SelectionAdapter selectProfAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { displayProfileInformation(); } };
        final SelectionAdapter duplicateProfAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doDuplicateProfile(); } };
        final SelectionAdapter toggleProfAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doToggleFavoriteProfile(); } };
        final SelectionAdapter shortcutProfAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doCreateShortcut(); } };
        final SelectionAdapter openProfAdapter = new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
                int index = profile_table.getSelectionIndex();
                if (index != -1) {
                    Profile prof = profilesList.get(index);
                    try {
						Conf c = new Conf(prof, DosboxVersion.findById(dbversionsList, prof.getDbversionId()), System.err);
						PlatformUtils.openDirForViewing(c.getAutoexec().getCanonicalMainDir());
					} catch (IOException e) {
						GeneralPurposeDialogs.warningMessage(shell, e);
					}
                }
            }
        };
        MouseAdapter mouseAdapter = new MouseAdapter() { public void mouseDoubleClick(final MouseEvent event) { doRunProfile(-1, false); } };
        MouseAdapter filterMouseAdapter = new MouseAdapter() { public void mouseDoubleClick(final MouseEvent event) { doEditFilter(); } };
        KeyAdapter keyAdapter = new KeyAdapter() {
            public void keyPressed(final KeyEvent event) {
                if (event.keyCode == SWT.DEL) {
                    doRemoveProfile();
                } else if (event.keyCode == SWT.INSERT) {
                    doAddProfile();
                } else if (event.keyCode == SWT.F2) {
                    doEditProfile(true);
                } else if (event.stateMask == SWT.CTRL && (Character.toLowerCase(event.keyCode) == 'm')) {
                    doToggleFavoriteProfile();
                } else if (event.stateMask == SWT.CTRL && (Character.toLowerCase(event.keyCode) == 'd')) {
                    doDuplicateProfile();
                } else if (event.stateMask == SWT.CTRL && (Character.toLowerCase(event.keyCode) == 'a')) {
                    profile_table.selectAll();
                } else if (event.stateMask == SWT.CTRL && (Character.toLowerCase(event.keyCode) == 'f')) {
                    doAddFilter();
                } else if (event.stateMask == SWT.CTRL && (Character.toLowerCase(event.keyCode) == 'c')) {
                	doViewProfileConf();
                } else if (event.stateMask == SWT.CTRL && (Character.toLowerCase(event.keyCode) == 'w')) {
                	doStartGameWizard();
                }
            }
        };
        TraverseListener travListener = new TraverseListener() {
            public void keyTraversed(final TraverseEvent event) {
                if ((event.stateMask == SWT.CTRL) && (event.detail == SWT.TRAVERSE_RETURN)) {
                    doEditProfile();
                } else if ((event.stateMask == SWT.SHIFT) && (event.detail == SWT.TRAVERSE_RETURN)) {
                    doRunProfile(0, false);
                } else if (event.detail == SWT.TRAVERSE_RETURN) {
                    doRunProfile(-1, false);
                } 
            }
        };

        GeneralPurposeGUI.createIconToolItem(toolBar, settings, settings.msg("dialog.main.addprofile"), SWTImageManager.IMG_TB_NEW, addProfAdapter);
        GeneralPurposeGUI.createIconToolItem(toolBar, settings, settings.msg("dialog.main.editprofile"), SWTImageManager.IMG_TB_EDIT, editProfAdapter);
        GeneralPurposeGUI.createIconToolItem(toolBar, settings, settings.msg("dialog.main.removeprofile"), SWTImageManager.IMG_TB_DELETE, removeProfAdapter);
        GeneralPurposeGUI.createIconToolItem(toolBar, settings, settings.msg("dialog.main.runprofile"), SWTImageManager.IMG_TB_RUN, runProfAdapter);
        setupToolItem = GeneralPurposeGUI.createIconToolItem(toolBar, settings, settings.msg("dialog.main.runprofilesetup"), SWTImageManager.IMG_TB_SETUP, setupProfAdapter);
        GeneralPurposeGUI.createSeparatorToolItem(toolBar, 40);
        GeneralPurposeGUI.createIconToolItem(toolBar, settings, settings.msg("dialog.main.addwizard"), SWTImageManager.IMG_TB_ADDGAMEWIZARD, addWizardAdapter);

        final SashForm sashForm = new SashForm(composite, SWT.NONE);
        ControlAdapter sashResizeAdapter = new ControlAdapter() { public void controlResized(final ControlEvent event) { ssettings.setIntValues("gui", "sashweights", sashForm.getWeights()); } };
        SelectionAdapter linkAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { PlatformUtils.openForBrowsing(event.text); } };

        filterFolder = new CTabFolder(sashForm, SWT.BORDER);
        filterFolder.setLayoutData(BorderLayout.WEST);
        filterFolder.setUnselectedCloseVisible(true);
        filterFolder.addSelectionListener(new SelectionAdapter() {
        	public void widgetSelected(final SelectionEvent event) {
        		updateProfilesAfterTabAction();
        	}
        });
        filterFolder.addCTabFolder2Listener(new CTabFolder2Adapter() {
    		public void close(final CTabFolderEvent event) {
    			if (GeneralPurposeDialogs.confirmMessage(shell, settings.msg("dialog.main.confirm.removefilter", new Object[] {((CTabItem)event.item).getText().trim()}))) {
	    			boolean currentTabToBeClosed = (event.item == filterFolder.getSelection());
	    			try {
	    				int filterId = (Integer)event.item.getData();
						dbase.removeFilter(filterId);
						filtersList.remove(Filter.findIndexById(filtersList, filterId));
					} catch (SQLException e) {
						GeneralPurposeDialogs.warningMessage(shell, e);
					}
					if (currentTabToBeClosed) {
						filterFolder.setSelection(0);
						updateProfilesAfterTabAction();
					}
    			} else {
    				event.doit = false;
    			}
    		}
    	});
        filterFolder.addMouseListener(filterMouseAdapter);

        profile_table = new Table(filterFolder, SWT.FULL_SELECTION | SWT.MULTI | SWT.BORDER);
        profile_table.setLinesVisible(true);
        profile_table.setHeaderVisible(true);
        for (int i = 0; i < columnIds.length; i++) {
            addProfileColumn(columnNames[columnIds[i]], i);
        }
        
        profile_table.addMouseListener(mouseAdapter);
        profile_table.addKeyListener(keyAdapter);
        profile_table.addTraverseListener(travListener);
        profile_table.addSelectionListener(selectProfAdapter);
        
        for (Filter filter: filtersList) {
    		addFilterTab(filter);
    	}
    	filterFolder.setSelection(ssettings.getIntValue("gui", "filtertab"));
    	filterFolder.getSelection().setToolTipText(settings.msg("dialog.filter.notice.results", new Object[] {profilesList.size()}));

        final Menu menu = new Menu(profile_table);
        profile_table.setMenu(menu);

        new MenuItem(menu, SWT.SEPARATOR);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.profile.openfolder"), SWTImageManager.IMG_FOLDER, openProfAdapter);
        
        final MenuItem viewLinkMenuItem = GeneralPurposeGUI.createIconMenuItem(menu, SWT.CASCADE, settings, settings.msg("dialog.main.profile.view"), SWTImageManager.IMG_ZOOM, null);
        viewLinkSubMenu = new Menu(viewLinkMenuItem);
        viewLinkMenuItem.setMenu(viewLinkSubMenu);

        new MenuItem(menu, SWT.SEPARATOR);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.profile.add"), SWTImageManager.IMG_NEW, addProfAdapter);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.profile.edit"), SWTImageManager.IMG_EDIT, editProfAdapter);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.profile.duplicate"), SWTImageManager.IMG_DUPLICATE, duplicateProfAdapter);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.profile.remove"), SWTImageManager.IMG_DELETE, removeProfAdapter);
        new MenuItem(menu, SWT.SEPARATOR);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.profile.togglefavorite"), SWTImageManager.IMG_FAVORITE, toggleProfAdapter);
        if (PlatformUtils.IS_WINDOWS || PlatformUtils.IS_LINUX) {
            new MenuItem(menu, SWT.SEPARATOR);
            GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.profile.createshortcut"), SWTImageManager.IMG_SHORTCUT, shortcutProfAdapter);
        }
        
        menu.addMenuListener(new MenuAdapter() {
            public void menuShown(final MenuEvent event) {
                if (profile_table.getSelectionIndex() != -1) {
                	Profile prof = profilesList.get(profile_table.getSelectionIndex());

                	for (MenuItem it: menu.getItems()) {
                		if (it.getStyle() == SWT.SEPARATOR) break;
                		it.dispose();
                	}

                	if (dbversionsList.size() > 1) {
                    	final MenuItem prepareWithMenuItem = GeneralPurposeGUI.createIconTopMenuItem(menu, SWT.CASCADE, settings, settings.msg("dialog.main.profile.startmanuallywith"), null, null);
                    	prepareWithMenuItem.setMenu(createDosboxVersionsSubmenu(menu, -1, true));
                	}
                	GeneralPurposeGUI.createIconTopMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.profile.startmanually"), null, prepareProfAdapter);

                	if (prof.hasSetup(2)) {
                		if (dbversionsList.size() > 1) {
	                		final MenuItem alt2WithMenuItem = GeneralPurposeGUI.createIconTopMenuItem(menu, SWT.CASCADE, settings, new File(prof.getSetup(2)).getName(), null, null);
	                    	alt2WithMenuItem.setMenu(createDosboxVersionsSubmenu(menu, 2, false));
                		}
                    	GeneralPurposeGUI.createIconTopMenuItem(menu, SWT.NONE, settings, new File(prof.getSetup(2)).getName(), null,
                    			new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doRunProfile(2, false); } });
                    }

                	if (prof.hasSetup(1)) {
                		if (dbversionsList.size() > 1) {
                			final MenuItem alt1WithMenuItem = GeneralPurposeGUI.createIconTopMenuItem(menu, SWT.CASCADE, settings, new File(prof.getSetup(1)).getName(), null, null);
                			alt1WithMenuItem.setMenu(createDosboxVersionsSubmenu(menu, 1, false));
                		}
                    	GeneralPurposeGUI.createIconTopMenuItem(menu, SWT.NONE, settings, new File(prof.getSetup(1)).getName(), null,
                    			new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doRunProfile(1, false); } });
                    }

                    boolean hasSetup = prof.hasSetup(0);
                    setupToolItem.setEnabled(hasSetup);
                    if (hasSetup) {
                    	if (dbversionsList.size() > 1) {
	                    	final MenuItem setupWithMenuItem = GeneralPurposeGUI.createIconTopMenuItem(menu, SWT.CASCADE, settings, settings.msg("dialog.main.profile.setupwith"), null, null);
	                    	setupWithMenuItem.setMenu(createDosboxVersionsSubmenu(menu, 0, false));
                    	}
                    	GeneralPurposeGUI.createIconTopMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.profile.setup"), SWTImageManager.IMG_SETUP, setupProfAdapter);
                    }

                    if (dbversionsList.size() > 1) {
                    	final MenuItem runWithMenuItem = GeneralPurposeGUI.createIconTopMenuItem(menu, SWT.CASCADE, settings, settings.msg("dialog.main.profile.runwith"), null, null);
                    	runWithMenuItem.setMenu(createDosboxVersionsSubmenu(menu, -1, false));
                    }
                    GeneralPurposeGUI.createIconTopMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.profile.run"), SWTImageManager.IMG_RUN, runProfAdapter);
                }
            }
        });
        
        final Composite informationGroup = new Composite(sashForm, SWT.NONE);
        GridLayout gl = new GridLayout();
        gl.horizontalSpacing = 0;
        gl.verticalSpacing = 0;
        gl.marginWidth = 0;
        gl.marginHeight = 0;
        informationGroup.setLayout(gl);
        informationGroup.addControlListener(sashResizeAdapter);
        notesField = new Text(informationGroup, SWT.V_SCROLL | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.WRAP);
        notesField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        notesField.setFont(GeneralPurposeGUI.stringToFont(display, notesField.getFont(), ssettings.getValues("gui", "notesfont")));
        
        sashForm.setWeights(ssettings.getIntValues("gui", "sashweights"));

        final Composite linksComposite = new Composite(informationGroup, SWT.NONE);
        final GridLayout gridLayout = new GridLayout();
        gridLayout.marginWidth = 0;
        gridLayout.marginHeight = 1;
        gridLayout.verticalSpacing = 2;
        linksComposite.setLayout(gridLayout);
        linksComposite.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
        link = new Link[EditProfileDialog.AMOUNT_OF_LINKS];
        for (int i = 0; i < link.length; i++) {
            link[i] = new Link(linksComposite, SWT.NONE);
            link[i].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
            link[i].addSelectionListener(linkAdapter);
        }
        
    	thumbHeight = ssettings.getIntValue("gui", "screenshotsheight");
        ScrolledComposite scrolledComposite = new ScrolledComposite(composite, SWT.BORDER | SWT.H_SCROLL);
        scrolledComposite.setMinHeight(thumbHeight + 20);
        scrolledComposite.setLayoutData(BorderLayout.SOUTH);
        
        thumbsToolBar = new Composite(scrolledComposite, SWT.NONE);
        thumbsToolBar.setLayout(new RowLayout(SWT.HORIZONTAL));
        scrolledComposite.setContent(thumbsToolBar);
        scrolledComposite.getHorizontalBar().setPageIncrement(300);
        scrolledComposite.getHorizontalBar().setIncrement(50);

        menu_thumb = new Menu(thumbsToolBar);
        
        SelectionAdapter removeThumbAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doRemoveThumb(); } };
        SelectionAdapter openThumbsAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { PlatformUtils.openDirForViewing(currentThumbFile.getParentFile()); } };
        SelectionAdapter refreshThumbsAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { SWTImageManager.dispose(); displayProfileInformation(); } };
        
        GeneralPurposeGUI.createIconMenuItem(menu_thumb, SWT.NONE, settings, settings.msg("dialog.main.thumb.remove"), SWTImageManager.IMG_DELETE, removeThumbAdapter);
        new MenuItem(menu_thumb, SWT.SEPARATOR);
        GeneralPurposeGUI.createIconMenuItem(menu_thumb, SWT.NONE, settings, settings.msg("dialog.main.thumb.openfolder"), SWTImageManager.IMG_FOLDER, openThumbsAdapter);
        GeneralPurposeGUI.createIconMenuItem(menu_thumb, SWT.NONE, settings, settings.msg("dialog.main.thumb.refresh"), SWTImageManager.IMG_REFRESH, refreshThumbsAdapter);
    }

	protected void doStartGameWizard() {
		updateWithAddedProfile((Profile)new AddGameWizardDialog(shell, SWT.NONE).open());
	}

	private void addFilterTab(Filter filter) {
		CTabItem item = new CTabItem(filterFolder, filter.getFilter() == null? SWT.NONE: SWT.CLOSE);
		item.setText("    " + filter.getTitle() + "    ");
		item.setData(filter.getId());
		item.setControl(profile_table);
	}

    private void createDosboxVersionsTab(TabFolder tabFolder) {
    	final TabItem dosboxTabItem = new TabItem(tabFolder, SWT.NONE);
        dosboxTabItem.setText(settings.msg("dialog.main.dosboxversions"));

        final Composite composite = new Composite(tabFolder, SWT.NONE);
        composite.setLayout(new BorderLayout(0, 0));
        dosboxTabItem.setControl(composite);

        final ToolBar toolBar = new ToolBar(composite, SWT.NONE);
        toolBar.setLayoutData(BorderLayout.NORTH);

        SelectionAdapter addDosboxAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doAddDosboxVersion(); } };
        SelectionAdapter editDosboxAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doEditDosboxVersion(); } };
        SelectionAdapter removeDosboxAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doRemoveDosboxVersion(); } };
        SelectionAdapter runDosboxAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doRunDosbox(); } };
        SelectionAdapter toggleDosboxAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doToggleDefaultVersion(); } };
        SelectionAdapter openDosboxAdapter = new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
                int index = dbversion_table.getSelectionIndex();
                if (index != -1) {
                    PlatformUtils.openDirForViewing(dbversionsList.get(index).getCanonicalConfFile().getParentFile());
                }
            }
        };
        MouseAdapter mouseAdapter = new MouseAdapter() { public void mouseDoubleClick(final MouseEvent event) { doRunDosbox(); } };
        KeyAdapter keyAdapter = new KeyAdapter() {
            public void keyPressed(final KeyEvent event) {
                if (event.keyCode == SWT.DEL) {
                    doRemoveDosboxVersion();
                } else if (event.keyCode == SWT.INSERT) {
                    doAddDosboxVersion();
                } else if (event.stateMask == SWT.CTRL && (Character.toLowerCase(event.keyCode) == 'm')) {
                    doToggleDefaultVersion();
                }
            }
        };
        TraverseListener travListener = new TraverseListener() {
            public void keyTraversed(final TraverseEvent event) {
                if ((event.stateMask == SWT.CTRL) && (event.detail == SWT.TRAVERSE_RETURN)) {
                    doEditDosboxVersion();
                } else if (event.detail == SWT.TRAVERSE_RETURN) {
                    doRunDosbox();
                }
            }
        };

        GeneralPurposeGUI.createIconToolItem(toolBar, settings, settings.msg("dialog.main.addversion"), SWTImageManager.IMG_TB_NEW, addDosboxAdapter);
        GeneralPurposeGUI.createIconToolItem(toolBar, settings, settings.msg("dialog.main.editversion"), SWTImageManager.IMG_TB_EDIT, editDosboxAdapter);
        GeneralPurposeGUI.createIconToolItem(toolBar, settings, settings.msg("dialog.main.removeversion"), SWTImageManager.IMG_TB_DELETE, removeDosboxAdapter);
        GeneralPurposeGUI.createIconToolItem(toolBar, settings, settings.msg("dialog.main.runversion"), SWTImageManager.IMG_TB_RUN, runDosboxAdapter);

        dbversion_table = new Table(composite, SWT.FULL_SELECTION | SWT.BORDER);
        dbversion_table.setLinesVisible(true);
        dbversion_table.setHeaderVisible(true);
        addDBColumn(settings.msg("dialog.main.dosboxversions.column.title"), 0);
        addDBColumn(settings.msg("dialog.main.dosboxversions.column.version"), 1);
        addDBColumn(settings.msg("dialog.main.dosboxversions.column.path"), 2);
        addDBColumn(settings.msg("dialog.main.dosboxversions.column.default"), 3);
        addDBColumn(settings.msg("dialog.main.dosboxversions.column.id"), 4);

        final Menu menu = new Menu(dbversion_table);
        dbversion_table.setMenu(menu);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.dosboxversion.run"), SWTImageManager.IMG_RUN, runDosboxAdapter);
        new MenuItem(menu, SWT.SEPARATOR);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.dosboxversion.add"), SWTImageManager.IMG_NEW, addDosboxAdapter);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.dosboxversion.edit"), SWTImageManager.IMG_EDIT, editDosboxAdapter);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.dosboxversion.remove"), SWTImageManager.IMG_DELETE, removeDosboxAdapter);
        new MenuItem(menu, SWT.SEPARATOR);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.dosboxversion.toggledefault"), SWTImageManager.IMG_HOME, toggleDosboxAdapter);
        new MenuItem(menu, SWT.SEPARATOR);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.dosboxversion.openfolder"), SWTImageManager.IMG_FOLDER, openDosboxAdapter);
        
        dbversion_table.addKeyListener(keyAdapter);
        dbversion_table.addTraverseListener(travListener);
        dbversion_table.addMouseListener(mouseAdapter);
    }
    
    private void createTemplatesTab(TabFolder tabFolder) {
    	final TabItem templatesTabItem = new TabItem(tabFolder, SWT.NONE);
        templatesTabItem.setText(settings.msg("dialog.main.templates"));

        final Composite composite = new Composite(tabFolder, SWT.NONE);
        composite.setLayout(new BorderLayout(0, 0));
        templatesTabItem.setControl(composite);

        final ToolBar toolBar = new ToolBar(composite, SWT.NONE);
        toolBar.setLayoutData(BorderLayout.NORTH);

        SelectionAdapter addTemplAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doAddTemplate(); } };
        SelectionAdapter editTemplAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doEditTemplate(); } };
        SelectionAdapter removeTemplAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doRemoveTemplate(); } };
        SelectionAdapter runTemplAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doRunTemplate(); } };
        SelectionAdapter toggleTemplAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doToggleDefaultTemplate(); } };
        MouseAdapter mouseAdapter = new MouseAdapter() { public void mouseDoubleClick(final MouseEvent event) { doRunTemplate(); } };
        KeyAdapter keyAdapter = new KeyAdapter() {
            public void keyPressed(final KeyEvent event) {
                if (event.keyCode == SWT.DEL) {
                    doRemoveTemplate();
                } else if (event.keyCode == SWT.INSERT) {
                    doAddTemplate();
                } else if (event.stateMask == SWT.CTRL && (Character.toLowerCase(event.keyCode) == 'm')) {
                    doToggleDefaultTemplate();
                }
            }
        };
        TraverseListener travListener = new TraverseListener() {
            public void keyTraversed(final TraverseEvent event) {
                if ((event.stateMask == SWT.CTRL) && (event.detail == SWT.TRAVERSE_RETURN)) {
                    doEditTemplate();
                } else if (event.detail == SWT.TRAVERSE_RETURN) {
                    doRunTemplate();
                } 
            }
        };
        
        GeneralPurposeGUI.createIconToolItem(toolBar, settings, settings.msg("dialog.main.addtemplate"), SWTImageManager.IMG_TB_NEW, addTemplAdapter);
        GeneralPurposeGUI.createIconToolItem(toolBar, settings, settings.msg("dialog.main.edittemplate"), SWTImageManager.IMG_TB_EDIT, editTemplAdapter);
        GeneralPurposeGUI.createIconToolItem(toolBar, settings, settings.msg("dialog.main.removetemplate"), SWTImageManager.IMG_TB_DELETE, removeTemplAdapter);
        GeneralPurposeGUI.createIconToolItem(toolBar, settings, settings.msg("dialog.main.runtemplate"), SWTImageManager.IMG_TB_RUN, runTemplAdapter);

        template_table = new Table(composite, SWT.FULL_SELECTION | SWT.BORDER);
        template_table.setLinesVisible(true);
        template_table.setHeaderVisible(true);
        addTemplateColumn(settings.msg("dialog.main.templates.column.title"), 0);
        addTemplateColumn(settings.msg("dialog.main.templates.column.default"), 1);

        final Menu menu = new Menu(template_table);
        template_table.setMenu(menu);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.template.run"), SWTImageManager.IMG_RUN, runTemplAdapter);
        new MenuItem(menu, SWT.SEPARATOR);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.template.add"), SWTImageManager.IMG_NEW, addTemplAdapter);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.template.edit"), SWTImageManager.IMG_EDIT, editTemplAdapter);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.template.remove"), SWTImageManager.IMG_DELETE, removeTemplAdapter);
        new MenuItem(menu, SWT.SEPARATOR);
        GeneralPurposeGUI.createIconMenuItem(menu, SWT.NONE, settings, settings.msg("dialog.main.template.toggledefault"), SWTImageManager.IMG_HOME, toggleTemplAdapter);
        
        template_table.addKeyListener(keyAdapter);
        template_table.addTraverseListener(travListener);
        template_table.addMouseListener(mouseAdapter);
    }
    
    private void doOpenAbout() {
    	new AboutDialog(shell, SWT.NONE).open();
    }

    private void createFileMenu() {
    	final Menu menu = new Menu(shell, SWT.BAR);
        shell.setMenuBar(menu);

        final MenuItem fileMenuItem = new MenuItem(menu, SWT.CASCADE);
        fileMenuItem.setText(settings.msg("dialog.main.menu.file"));
        final Menu fileMenu = new Menu(fileMenuItem);
        fileMenuItem.setMenu(fileMenu);

        final MenuItem filterMenuItem = new MenuItem(menu, SWT.CASCADE);
        filterMenuItem.setText(settings.msg("dialog.main.menu.filter"));
        final Menu filterMenu = new Menu(filterMenuItem);
        filterMenuItem.setMenu(filterMenu);

        final MenuItem helpMenuItem = new MenuItem(menu, SWT.CASCADE);
        helpMenuItem.setText(settings.msg("dialog.main.menu.help"));
        final Menu helpMenu = new Menu(helpMenuItem);
        helpMenuItem.setMenu(helpMenu);

        SelectionAdapter dfendAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doDFendImport(); } };
        SelectionAdapter migrateAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doMigrate(); } };
        SelectionAdapter exportListAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doExportProfilesList(); } };
        SelectionAdapter importConfAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doImportConfigfile(); } };
        SelectionAdapter exportAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doExportProfiles(); } };
        SelectionAdapter importAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doImportProfiles(); } };
        SelectionAdapter cleanupAdapter = new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
                try {
                    if (GeneralPurposeDialogs.confirmMessage(shell, settings.msg("dialog.main.confirm.databasecleanup"))) {
                        int itemsRemoved = dbase.cleanup();
                        GeneralPurposeDialogs.infoMessage(shell, settings.msg("dialog.main.notice.databasecleanupok", new Object[] {itemsRemoved}));
                    }
                } catch (SQLException e) {
                    GeneralPurposeDialogs.warningMessage(shell, e);
                }
            }
        };
        SelectionAdapter settingsAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doOpenSettingsDialog(); } };
        SelectionAdapter exitAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { shell.close(); } };
        
        if (PlatformUtils.IS_WINDOWS) {
            GeneralPurposeGUI.createIconMenuItem(fileMenu, SWT.NONE, settings, settings.msg("dialog.main.menu.importdfendprofiles"), SWTImageManager.IMG_DFEND, dfendAdapter);
            new MenuItem(fileMenu, SWT.SEPARATOR);
        }
        GeneralPurposeGUI.createIconMenuItem(fileMenu, SWT.NONE, settings, settings.msg("dialog.main.menu.migrateprofiles"), SWTImageManager.IMG_MIGRATE, migrateAdapter);
        GeneralPurposeGUI.createIconMenuItem(fileMenu, SWT.NONE, settings, settings.msg("dialog.main.menu.exportprofileslist"), SWTImageManager.IMG_TABLEEXPORT, exportListAdapter);
        GeneralPurposeGUI.createIconMenuItem(fileMenu, SWT.NONE, settings, settings.msg("dialog.main.menu.importprofile"), SWTImageManager.IMG_IMPORT, importConfAdapter);
        new MenuItem(fileMenu, SWT.SEPARATOR);
        
        GeneralPurposeGUI.createIconMenuItem(fileMenu, SWT.NONE, settings, settings.msg("dialog.main.menu.export"), SWTImageManager.IMG_TABLEEXPORT, exportAdapter);
        GeneralPurposeGUI.createIconMenuItem(fileMenu, SWT.NONE, settings, settings.msg("dialog.main.menu.import"), SWTImageManager.IMG_IMPORT, importAdapter);
        new MenuItem(fileMenu, SWT.SEPARATOR);
        
        GeneralPurposeGUI.createIconMenuItem(fileMenu, SWT.NONE, settings, settings.msg("dialog.main.menu.databasecleanup"), SWTImageManager.IMG_CLEAN, cleanupAdapter);
        new MenuItem(fileMenu, SWT.SEPARATOR);
        GeneralPurposeGUI.createIconMenuItem(fileMenu, SWT.NONE, settings, settings.msg("dialog.main.menu.adjustsettings"), SWTImageManager.IMG_SETTINGS, settingsAdapter);
        GeneralPurposeGUI.createIconMenuItem(fileMenu, SWT.NONE, settings, settings.msg("dialog.main.menu.exit"), SWTImageManager.IMG_EXIT, exitAdapter);

        SelectionAdapter addFilterAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doAddFilter(); } };
        SelectionAdapter editFilterAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doEditFilter(); } };
        GeneralPurposeGUI.createIconMenuItem(filterMenu, SWT.NONE, settings, settings.msg("dialog.main.menu.addfilter"), null, addFilterAdapter);
        GeneralPurposeGUI.createIconMenuItem(filterMenu, SWT.NONE, settings, settings.msg("dialog.main.menu.editfilter"), null, editFilterAdapter);

        SelectionAdapter openAboutAdapter = new SelectionAdapter() { public void widgetSelected(final SelectionEvent event) { doOpenAbout(); } };
        GeneralPurposeGUI.createIconMenuItem(helpMenu, SWT.NONE, settings, settings.msg("dialog.main.menu.about"), null, openAboutAdapter);
    }
    
	private void doExportProfiles() {
        if (profile_table.getSelectionIndex() != -1) {
            ProfileLoader pLoader = new ProfileLoader(shell, getSelectedProfiles(), false);
            if (pLoader.open() != null) {
            	new ExportDialog(shell, dbversionsList, pLoader.getResult()).open();
            }
        }
    }
    
    private void doImportProfiles() {
        FileDialog dialog = new FileDialog(shell, SWT.OPEN);
        dialog.setFilterNames(new String[] { "GamePack Archives", "DOSBox configuration files",
                "Executables, Booter Disk Images", FileUtils.ALL_FILTER });
        dialog.setFilterExtensions(new String[] { FileUtils.ARC_FILTER, FileUtils.CNF_FILTER,
                FileUtils.EXE_FILTER + ";" + FileUtils.BTR_FILTER, FileUtils.ALL_FILTER });
        String result = dialog.open();
        if (result != null)
            doAddProfile(result);
    }
    
    private static Map<String, String> getEnv(SectionsWrapper settings) {
    	if (settings.getBooleanValue("environment", "use")) {
    		return StringRelatedUtils.stringArrayToMap(settings.getValues("environment", "value"));
    	}
    	return null;
    }

    private void updateProfilesAfterTabAction() {
    	int tabIndex = filterFolder.getSelectionIndex();
    	ssettings.setValue("gui", "filtertab", String.valueOf(tabIndex));
    	filterClause = filtersList.get(tabIndex).getFilter();
    	updateProfilesList(getSelectedProfileIds());
    	for (CTabItem tab: filterFolder.getItems()) tab.setToolTipText(null);
    	filterFolder.getSelection().setToolTipText(settings.msg("dialog.filter.notice.results", new Object[] {profilesList.size()}));
    	displayProfileInformation();
    }

    private void doViewProfileConf() {
        int index = profile_table.getSelectionIndex();
        if (index != -1) {
            PlatformUtils.openForEditing(profilesList.get(index).getCanonicalConfFile());
        }
    }

    private Set<Integer> getSelectedProfileIds() {
    	int[] selection = profile_table.getSelectionIndices();
        Set<Integer> profileIds = new HashSet<Integer>();
        for (int i: selection) {
            profileIds.add(profilesList.get(i).getId());
        }
        return profileIds;
    }

    private java.util.List<Profile> getSelectedProfiles() {
		int[] selection = profile_table.getSelectionIndices();
		java.util.List<Profile> profiles = new ArrayList<Profile>();
		for (int i: selection) {
		    profiles.add(profilesList.get(i));
		}
		return profiles;
	}

    private int[] getIndicesByIds(final Set<Integer> profileIds) {
    	java.util.List<Integer> tableIdxsList = new ArrayList<Integer>();
        for (int i = 0; i < profilesList.size(); i++) {
        	if (profileIds.contains(profilesList.get(i).getId())) {
        		tableIdxsList.add(i);
        	}
        }
        int[] tableIdxsArray = new int[tableIdxsList.size()];
        for (int i = 0; i < tableIdxsList.size(); i++) {
        	tableIdxsArray[i] = tableIdxsList.get(i);
        }
        return tableIdxsArray;
    }
    
    public static void openSendToProfileDialog(final String file) {
        Database dbase = Database.getInstance();

        Shell shell = new Shell();
        shell.setMinimized(true);
        shell.open();

        try {
            java.util.List<DosboxVersion> dbversionsList = dbase.readDosboxVersionsList();
            if (DosboxVersion.findDefault(dbversionsList) == null) {
                GeneralPurposeDialogs.infoMessage(shell, Settings.getInstance().msg("dialog.main.required.defaultdosboxversion"));
                try {
                    dbase.shutdown();
                } catch (SQLException e) {
                    // nothing we can do
                }
                return;
            }

            if (FileUtils.isGamePackArchiveFile(file)) {
                ImportDialog importDialog = new ImportDialog(shell, dbversionsList, new File(file));
                importDialog.open();
            } else {
	            EditProfileDialog editProfDialog = new EditProfileDialog(shell);
	            editProfDialog.sendToProfile(file);
	            editProfDialog.open();
            }
        } catch (SQLException e) {
            GeneralPurposeDialogs.warningMessage(shell, e);
        }

        try {
            dbase.shutdown();
        } catch (SQLException e) {
            // nothing we can do
        }
    }
}
