/*
 *  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.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.dbgl.db.Database;
import org.dbgl.interfaces.Configurable;
import org.dbgl.model.DosboxVersion;
import org.dbgl.model.ExpTemplate;
import org.dbgl.model.Mount;
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.util.FileUtils;
import swing2swt.layout.BorderLayout;


public class EditTemplateDialog extends Dialog {

    protected Text title;
    protected Button defaultButton;
    protected Combo dbversion;
    protected Button setButton, switchButton, reloadButton;
    protected Combo priority_active, priority_inactive;
    protected Button waitonerror, exit;
    protected Text language, captures, config_file;
    protected Combo output, frameskip;
    protected Combo scaler, pixelshader;
    protected Button fulldouble, fullscreen;
    protected Combo fullresolution, windowresolution;
    protected Button aspect;
    protected Text overscan;
    protected Combo svgachipset, videoram;
    protected Combo vsyncmode;
    protected Text vsyncrate;
    protected Button scaler_forced, glide;
    protected Text glideport;
    protected Combo lfbGlide;
    protected Combo machine, cpu_type, core;
    protected Combo cycles, cycles_up, cycles_down;
    protected Button timesynched;
    protected Combo memsize;
    protected Button xms;
    protected Combo ems, umb;
    protected Button nosound;
    protected Combo rate, blocksize, prebuffer, mpu401, midi_device;
    protected Text midi_config;
    protected Text mixer_config;
    protected Combo mt32rate;
    protected Combo sbtype, oplrate, oplmode, oplemu, sbbase, irq, dma, hdma;
    protected Button sbmixer;
    protected Button gus;
    protected Combo gusrate, gusbase, gusdma1, gusdma2, gusirq1, gusirq2;
    protected Text ultradir;
    protected Button pcspeaker;
    protected Combo pcrate;
    protected Combo tandy, tandyrate;
    protected Button disney;
    protected Button usescancodes;
    protected Text mapperfile;
    protected Combo keyboard_layout;
    protected Text keyb;
    protected Button autolock;
    protected Combo sensitivity;
    protected Combo joysticktype;
    protected Button timed, autofire, swap34, buttonwrap;
    protected Text serial1, serial2, serial3, serial4;
    protected Button ipx;
    protected Text ipxnet;
    protected List mountingpoints;
    protected ExpandItem booterExpandItem, dosExpandItem;
    protected Group memoryGroup, associationGroup, miscGroup, executeGroup;
    protected TabItem infoTabItem, generalTabItem, mountingTabItem;
    protected Button okButton, cancelButton;
    
    protected int dbversionIndex = -1;
    
    protected Shell shell;
    protected java.util.List<DosboxVersion> dbversionsList;
    protected Database dbase;
    protected java.util.List<Configurable> multiProfileList = new ArrayList<Configurable>();
    protected Settings settings;
    protected Object result;
    
    protected enum DosboxConfAction { SET, SWITCH, RELOAD, RELOAD_TEMPLATE };


    public EditTemplateDialog(final Shell parent) {
        super(parent, SWT.NONE);
    }

    public void setTemplate(final Template template) {
        this.result = template;
    }

    public Object open() {
        settings = Settings.getInstance();
        dbase = Database.getInstance();
        if (init()) { 
            createContents();
            shell.open();
            shell.layout();
            Display display = getParent().getDisplay();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch()) {
                    display.sleep();
                }
            }
        }
        return result;
    }

    protected boolean init() {
        try {
            dbversionsList = dbase.readDosboxVersionsList();
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            PrintStream ps = new PrintStream(bos);
            if (result == null) {
                dbversionIndex = DosboxVersion.indexOfDefault(dbversionsList);
                multiProfileList.add(new ExpTemplate(new Conf((Template)null, dbversionsList.get(dbversionIndex), ps)));
            } else {
                dbversionIndex = DosboxVersion.findIndexById(dbversionsList, ((Template)result).getDbversionId());
                multiProfileList.add(new ExpTemplate(new Conf((Template)result, dbversionsList.get(dbversionIndex), ps)));
            }
            if (bos.size() > 0) {
            	GeneralPurposeDialogs.warningMessage(getParent(), bos.toString());
            	bos.reset();
            }
            return true;
        } catch (Exception e) {
            GeneralPurposeDialogs.warningMessage(getParent(), e);
            return false;
        }
    }
    
    protected void createContents() {
        shell = new Shell(getParent(), SWT.TITLE | SWT.CLOSE | SWT.BORDER | SWT.RESIZE | SWT.APPLICATION_MODAL);
        shell.setLayout(new BorderLayout(0, 0));
        shell.addControlListener(new SizeControlAdapter(shell, "templatedialog"));
        if (result == null) {
            shell.setText(settings.msg("dialog.template.title.add"));
        } else {
            // meaning we are essentially editing an existing template
            shell.setText(settings.msg("dialog.template.title.edit", new Object[] {((Template)result).getTitle(), ((Template) result).getId()}));
        }

        final TabFolder tabFolder = new TabFolder(shell, SWT.NONE);
        createInfoTab(tabFolder);
        createGeneralTab(tabFolder);
        createDisplayTab(tabFolder);
        createMachineTab(tabFolder);
        createAudioTab(tabFolder);
        createIOTab(tabFolder);
        createMountingTab(tabFolder);

        createOkCancelButtons();
        okButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
                if (!isValid()) {
                    return;
                }
                try {
                    Conf conf = multiProfileList.get(0).getConf();
                    int templateId = dbase.addOrEditTemplate(title.getText(), conf.getDbversion().getId(),
                    		defaultButton.getSelection(), result == null ? -1: ((Template)result).getId());
                    updateConfigurationBySettings(conf);
                    result = new Template(templateId, title.getText(), conf.getDbversion().getId(), defaultButton.getSelection());
                    conf.injectOrUpdateTemplate((Template)result);
                    conf.save();
                } catch (Exception e) {
                    GeneralPurposeDialogs.warningMessage(shell, e);
                }
                shell.close();
            }
        });

        // init values
        for (DosboxVersion dbv : dbversionsList) {
            dbversion.add(dbv.getTitle());
        }
        dbversion.select(dbversionIndex);
        
        if (result == null) {
            title.setFocus();
        } else {
            // meaning we are essentially editing an existing template
            // so we need to set previous values
            title.setText(((Template)result).getTitle());
            defaultButton.setSelection(((Template)result).isDefault());
        }

        enableSettingsByConfiguration(multiProfileList.get(0).getConf().getDosboxSettings());
        selectSettingsByConfiguration(multiProfileList.get(0).getConf());
    }
    
    protected void createOkCancelButtons() {
        final Composite composite_7 = new Composite(shell, SWT.NONE);
        composite_7.setLayout(new GridLayout(2, true));
        composite_7.setLayoutData(BorderLayout.SOUTH);

        okButton = new Button(composite_7, SWT.NONE);
        shell.setDefaultButton(okButton);
        final GridData gridData = new GridData();
        gridData.horizontalAlignment = SWT.FILL;
        gridData.widthHint = 80;
        okButton.setLayoutData(gridData);
        okButton.setText(settings.msg("button.ok"));
        
        cancelButton = new Button(composite_7, SWT.NONE);
        final GridData gridData_1 = new GridData();
        gridData_1.horizontalAlignment = SWT.FILL;
        cancelButton.setLayoutData(gridData_1);
        cancelButton.setText(settings.msg("button.cancel"));
        cancelButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
                if (cancelButton.getText().equals(settings.msg("button.cancel"))) {
                    result = null;
                }
                shell.close();
            }
        });
    }

    protected void createMountingTab(final TabFolder tabFolder) {
        mountingTabItem = new TabItem(tabFolder, SWT.NONE);
        mountingTabItem.setText(settings.msg("dialog.template.tab.mounting"));

        final Composite composite = new Composite(tabFolder, SWT.NONE);
        composite.setLayout(new GridLayout());
        mountingTabItem.setControl(composite);

        createMountingGroup(composite);
        createExecuteGroup(composite);
    }

    protected void createExecuteGroup(final Composite composite) {
        executeGroup = new Group(composite, SWT.NONE);
        executeGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        executeGroup.setText(settings.msg("dialog.template.execute"));
        executeGroup.setLayout(new FillLayout());
        
        final ExpandBar bar = new ExpandBar(executeGroup, SWT.V_SCROLL);
    	
        Composite booterComposite = new Composite(bar, SWT.NONE);
        Composite dosComposite = new Composite(bar, SWT.NONE);
        
        createBooterComposite(booterComposite);
        createDosComposite(dosComposite);
        
        booterExpandItem = new ExpandItem(bar, SWT.NONE, 0);
        booterExpandItem.setText(settings.msg("dialog.template.booter"));
        booterExpandItem.setHeight(booterComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
        booterExpandItem.setControl(booterComposite);
        
        dosExpandItem = new ExpandItem(bar, SWT.NONE, 1);
        dosExpandItem.setText(settings.msg("dialog.template.dos"));
        dosExpandItem.setHeight(dosComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
        dosExpandItem.setControl(dosComposite);
        
        bar.addExpandListener(new ExpandAdapter() {
            public void itemCollapsed(final ExpandEvent e)
            {
            	bar.getItem((((ExpandItem)e.item).getText().equals(settings.msg("dialog.template.dos")))? 0: 1).setExpanded(true);
            	Display.getCurrent().asyncExec(new Runnable() { public void run() { composite.layout(); } });
            }
            public void itemExpanded(final ExpandEvent e)
            {
            	bar.getItem((((ExpandItem)e.item).getText().equals(settings.msg("dialog.template.dos")))? 0: 1).setExpanded(false);
            	Display.getCurrent().asyncExec(new Runnable() { public void run() { composite.layout(); } });
            }
        });
        
        if (isMultiEdit()) {
        	bar.setEnabled(false);
        }
    }
    
    protected void createBooterComposite(Composite booterComposite) {
		booterComposite.setLayout(new GridLayout());
		final Label image1Label = new Label(booterComposite, SWT.NONE);
        image1Label.setText(settings.msg("dialog.profile.booterimage1"));
	}

	protected void createDosComposite(Composite dosComposite) {
		dosComposite.setLayout(new GridLayout());
		final Label mainExeLabel = new Label(dosComposite, SWT.NONE);
        mainExeLabel.setText(settings.msg("dialog.profile.mainexe"));
	}

    protected void createMountingGroup(final Composite composite) {
        final Group mountGroup = new Group(composite, SWT.NONE);
        mountGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        mountGroup.setText(settings.msg("dialog.template.mountingoverview"));
        final GridLayout gridLayout_19 = new GridLayout();
        gridLayout_19.numColumns = 2;
        mountGroup.setLayout(gridLayout_19);

        mountingpoints = new List(mountGroup, SWT.V_SCROLL | SWT.BORDER);
        mountingpoints.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 3));
        mountingpoints.addMouseListener(new MouseAdapter() {
            public void mouseDoubleClick(final MouseEvent event) {
                if (mountingpoints.getSelectionIndex() == -1) {
                    doAddMount();
                } else {
                    doEditMount();
                }
            }
        });

        final Button addButton = new Button(mountGroup, SWT.NONE);
        addButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        addButton.setText(settings.msg("dialog.template.mount.add"));
        addButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
                doAddMount();
            }
        });

        final Button editButton = new Button(mountGroup, SWT.NONE);
        editButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        editButton.setText(settings.msg("dialog.template.mount.edit"));
        editButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
                doEditMount();
            }
        });

        final Button removeButton = new Button(mountGroup, SWT.NONE);
        removeButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        removeButton.setText(settings.msg("dialog.template.mount.remove"));
        removeButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
                doRemoveMount();
            }
        });
        
        if (isMultiEdit()) {
        	mountingpoints.setEnabled(false);
        	addButton.setEnabled(false);
        	editButton.setEnabled(false);
        	removeButton.setEnabled(false);
        }
    }

    protected void createIOTab(final TabFolder tabFolder) {
        final TabItem inputTabItem = new TabItem(tabFolder, SWT.NONE);
        inputTabItem.setText(settings.msg("dialog.template.tab.io"));

        final Composite composite_5 = new Composite(tabFolder, SWT.NONE);
        final GridLayout gridLayout_17 = new GridLayout();
        gridLayout_17.numColumns = 3;
        composite_5.setLayout(gridLayout_17);
        inputTabItem.setControl(composite_5);

        final Group mouseGroup = new Group(composite_5, SWT.NONE);
        mouseGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
        mouseGroup.setText(settings.msg("dialog.template.mouse"));
        final GridLayout gridLayout_13 = new GridLayout();
        gridLayout_13.numColumns = 2;
        mouseGroup.setLayout(gridLayout_13);

        final Label autolockLabel = new Label(mouseGroup, SWT.NONE);
        autolockLabel.setText(settings.msg("dialog.template.autolock"));
        autolock = new Button(mouseGroup, SWT.CHECK);
        autolock.setToolTipText(settings.msg("dialog.template.autolock.tooltip"));

        final Label sensitivityLabel = new Label(mouseGroup, SWT.NONE);
        sensitivityLabel.setText(settings.msg("dialog.template.sensitivity"));
        sensitivity = new Combo(mouseGroup, SWT.READ_ONLY);
        sensitivity.setItems(settings.getSettings().getValues("profile", "sensitivity"));
        sensitivity.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        sensitivity.setVisibleItemCount(20);
        sensitivity.setToolTipText(settings.msg("dialog.template.sensitivity.tooltip"));
        
        final Group keyboardGroup = new Group(composite_5, SWT.NONE);
        keyboardGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        keyboardGroup.setText(settings.msg("dialog.template.keyboard"));
        final GridLayout gridLayout_14 = new GridLayout();
        gridLayout_14.numColumns = 2;
        keyboardGroup.setLayout(gridLayout_14);

        final Label useScancodesLabel = new Label(keyboardGroup, SWT.NONE);
        useScancodesLabel.setText(settings.msg("dialog.template.usescancodes"));
        usescancodes = new Button(keyboardGroup, SWT.CHECK);
        usescancodes.setToolTipText(settings.msg("dialog.template.usescancodes.tooltip"));

        final Label mapperFileLabel = new Label(keyboardGroup, SWT.NONE);
        mapperFileLabel.setText(settings.msg("dialog.template.mapperfile"));
        mapperfile = new Text(keyboardGroup, SWT.BORDER);
        mapperfile.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        mapperfile.setToolTipText(settings.msg("dialog.template.mapperfile.tooltip"));

        final Label layoutLabel = new Label(keyboardGroup, SWT.NONE);
        layoutLabel.setText(settings.msg("dialog.template.keyboardlayout"));
        keyboard_layout = new Combo(keyboardGroup, SWT.NONE);
        keyboard_layout.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        keyboard_layout.setVisibleItemCount(15);
        keyboard_layout.setItems(settings.getSettings().getValues("profile", "keyboardlayout"));
        keyboard_layout.setToolTipText(settings.msg("dialog.template.keyboardlayout.tooltip"));
        
        final Label keybLabel = new Label(keyboardGroup, SWT.NONE);
        keybLabel.setText(settings.msg("dialog.template.keybcommand"));
        keyb = new Text(keyboardGroup, SWT.BORDER);
        keyb.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

        final Group joystickGroup = new Group(composite_5, SWT.NONE);
        joystickGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
        joystickGroup.setText(settings.msg("dialog.template.joystick"));
        final GridLayout gridLayout_15 = new GridLayout();
        gridLayout_15.numColumns = 2;
        joystickGroup.setLayout(gridLayout_15);

        final Label typeLabel_1 = new Label(joystickGroup, SWT.NONE);
        typeLabel_1.setText(settings.msg("dialog.template.joysticktype"));
        joysticktype = new Combo(joystickGroup, SWT.READ_ONLY);
        joysticktype.setItems(settings.getSettings().getValues("profile", "joysticktype"));
        joysticktype.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        joysticktype.setToolTipText(settings.msg("dialog.template.joysticktype.tooltip"));

        final Label timedLabel = new Label(joystickGroup, SWT.NONE);
        timedLabel.setText(settings.msg("dialog.template.timedemulation"));
        timed = new Button(joystickGroup, SWT.CHECK);
        timed.setToolTipText(settings.msg("dialog.template.timedemulation.tooltip"));

        final Label autofireLabel = new Label(joystickGroup, SWT.NONE);
        autofireLabel.setText(settings.msg("dialog.template.autofire"));
        autofire = new Button(joystickGroup, SWT.CHECK);
        autofire.setToolTipText(settings.msg("dialog.template.autofire.tooltip"));

        final Label swapAxes3Label = new Label(joystickGroup, SWT.NONE);
        swapAxes3Label.setText(settings.msg("dialog.template.swap34"));
        swap34 = new Button(joystickGroup, SWT.CHECK);
        swap34.setToolTipText(settings.msg("dialog.template.swap34.tooltip"));

        final Label buttonWrapLabel = new Label(joystickGroup, SWT.NONE);
        buttonWrapLabel.setText(settings.msg("dialog.template.buttonwrapping"));
        buttonwrap = new Button(joystickGroup, SWT.CHECK);
        buttonwrap.setToolTipText(settings.msg("dialog.template.buttonwrapping.tooltip"));

        final Group modemGroup = new Group(composite_5, SWT.NONE);
        modemGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
        modemGroup.setText(settings.msg("dialog.template.modem"));
        final GridLayout gridLayout_16 = new GridLayout();
        gridLayout_16.numColumns = 2;
        modemGroup.setLayout(gridLayout_16);

        final Label serial1Label = new Label(modemGroup, SWT.NONE);
        serial1Label.setText(settings.msg("dialog.template.serial1"));
        serial1 = new Text(modemGroup, SWT.BORDER);
        serial1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        serial1.setToolTipText(settings.msg("dialog.template.serial.tooltip"));

        final Label serial2Label = new Label(modemGroup, SWT.NONE);
        serial2Label.setText(settings.msg("dialog.template.serial2"));
        serial2 = new Text(modemGroup, SWT.BORDER);
        serial2.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        serial2.setToolTipText(settings.msg("dialog.template.serial.tooltip"));

        final Label serial3Label = new Label(modemGroup, SWT.NONE);
        serial3Label.setText(settings.msg("dialog.template.serial3"));
        serial3 = new Text(modemGroup, SWT.BORDER);
        serial3.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        serial3.setToolTipText(settings.msg("dialog.template.serial.tooltip"));

        final Label serial4Label = new Label(modemGroup, SWT.NONE);
        serial4Label.setText(settings.msg("dialog.template.serial4"));
        serial4 = new Text(modemGroup, SWT.BORDER);
        serial4.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        serial4.setToolTipText(settings.msg("dialog.template.serial.tooltip"));

        final Group networkGroup = new Group(composite_5, SWT.NONE);
        networkGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
        networkGroup.setText(settings.msg("dialog.template.network"));
        final GridLayout gridLayout_20 = new GridLayout();
        gridLayout_20.numColumns = 2;
        networkGroup.setLayout(gridLayout_20);

        final Label ipxLabel = new Label(networkGroup, SWT.NONE);
        ipxLabel.setText(settings.msg("dialog.template.enableipx"));
        ipx = new Button(networkGroup, SWT.CHECK);
        ipx.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
                ipxnet.setEnabled(ipx.getSelection());
            }
        });
        ipx.setToolTipText(settings.msg("dialog.template.enableipx.tooltip"));
        
        final Label ipxnetCommandLabel = new Label(networkGroup, SWT.NONE);
        ipxnetCommandLabel.setText(settings.msg("dialog.template.ipxnetcommand"));
        ipxnetCommandLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 2, 1));

        ipxnet = new Text(networkGroup, SWT.BORDER);
        ipxnet.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
    }

    protected void createAudioTab(final TabFolder tabFolder) {
        final TabItem audioTabItem = new TabItem(tabFolder, SWT.NONE);
        audioTabItem.setText(settings.msg("dialog.template.tab.audio"));

        final Composite composite_4 = new Composite(tabFolder, SWT.NONE);
        final GridLayout gridLayout_9 = new GridLayout();
        gridLayout_9.numColumns = 3;
        composite_4.setLayout(gridLayout_9);
        audioTabItem.setControl(composite_4);

        final Group generalGroup = new Group(composite_4, SWT.NONE);
        generalGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        final GridLayout gridLayout_6 = new GridLayout();
        gridLayout_6.numColumns = 2;
        generalGroup.setLayout(gridLayout_6);
        generalGroup.setText(settings.msg("dialog.template.general"));

        final Label silentModeLabel = new Label(generalGroup, SWT.NONE);
        silentModeLabel.setText(settings.msg("dialog.template.silentmode"));
        nosound = new Button(generalGroup, SWT.CHECK);
        nosound.setToolTipText(settings.msg("dialog.template.silentmode.tooltip"));

        final Label sampleRateLabel = new Label(generalGroup, SWT.NONE);
        sampleRateLabel.setText(settings.msg("dialog.template.samplerate"));
        rate = new Combo(generalGroup, SWT.READ_ONLY);
        rate.setVisibleItemCount(10);
        rate.setItems(settings.getSettings().getValues("profile", "rate"));
        rate.setLayoutData(new GridData());
        rate.setToolTipText(settings.msg("dialog.template.samplerate.tooltip"));

        final Label blockSizeLabel = new Label(generalGroup, SWT.NONE);
        blockSizeLabel.setText(settings.msg("dialog.template.blocksize"));
        blocksize = new Combo(generalGroup, SWT.READ_ONLY);
        blocksize.setItems(settings.getSettings().getValues("profile", "blocksize"));
        blocksize.setLayoutData(new GridData());
        blocksize.setToolTipText(settings.msg("dialog.template.blocksize.tooltip"));

        final Label prebufferLabel = new Label(generalGroup, SWT.NONE);
        prebufferLabel.setText(settings.msg("dialog.template.prebuffer"));
        prebuffer = new Combo(generalGroup, SWT.NONE);
        prebuffer.setItems(settings.getSettings().getValues("profile", "prebuffer"));
        prebuffer.setLayoutData(new GridData(70, SWT.DEFAULT));
        prebuffer.setToolTipText(settings.msg("dialog.template.prebuffer.tooltip"));

        final Label mpu401Label = new Label(generalGroup, SWT.NONE);
        mpu401Label.setText(settings.msg("dialog.template.mpu401"));
        mpu401 = new Combo(generalGroup, SWT.READ_ONLY);
        mpu401.setItems(settings.getSettings().getValues("profile", "mpu401"));
        mpu401.setLayoutData(new GridData());
        mpu401.setToolTipText(settings.msg("dialog.template.mpu401.tooltip"));

        final Label midiDeviceLabel = new Label(generalGroup, SWT.NONE);
        midiDeviceLabel.setText(settings.msg("dialog.template.mididevice"));
        midi_device = new Combo(generalGroup, SWT.READ_ONLY);
        midi_device.setVisibleItemCount(10);
        midi_device.setItems(settings.getSettings().getValues("profile", "device"));
        midi_device.setLayoutData(new GridData());
        midi_device.setToolTipText(settings.msg("dialog.template.mididevice.tooltip"));

        final Label configLabel = new Label(generalGroup, SWT.NONE);
        configLabel.setText(settings.msg("dialog.template.midiconfig"));
        midi_config = new Text(generalGroup, SWT.BORDER);
        midi_config.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        midi_config.setToolTipText(settings.msg("dialog.template.midiconfig.tooltip"));

        final Label mixerConfigLabel = new Label(generalGroup, SWT.NONE);
        mixerConfigLabel.setText(settings.msg("dialog.template.mixercommand"));

        final Composite mixerSettings = new Composite(generalGroup, SWT.NONE);
        mixerSettings.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
        GridLayout filler = new GridLayout();
        filler.numColumns = 2;
        filler.horizontalSpacing = 2;
        filler.marginWidth = 0;
        mixerSettings.setLayout(filler);
        
        mixer_config = new Text(mixerSettings, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
        GridData mixerConfigGridData = new GridData(SWT.FILL, SWT.CENTER, true, false);
        mixerConfigGridData.widthHint = 66;
        mixer_config.setLayoutData(mixerConfigGridData);
        Button mixerConfig = new Button(mixerSettings, SWT.NONE);
        mixerConfig.setText("...");
        mixerConfig.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
            	EditMixerDialog dialog = new EditMixerDialog(shell);
            	dialog.setMixerCommand(mixer_config.getText());
                String command = (String)dialog.open();
                if (command != null) {
                	mixer_config.setText(command);
                }
            }
        });

        final Group soundblasterGroup = new Group(composite_4, SWT.NONE);
        soundblasterGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
        soundblasterGroup.setText(settings.msg("dialog.template.soundblaster"));
        final GridLayout gridLayout_7 = new GridLayout();
        gridLayout_7.numColumns = 2;
        soundblasterGroup.setLayout(gridLayout_7);

        final Label typeLabel = new Label(soundblasterGroup, SWT.NONE);
        typeLabel.setText(settings.msg("dialog.template.sbtype"));
        sbtype = new Combo(soundblasterGroup, SWT.READ_ONLY);
        sbtype.setVisibleItemCount(10);
        sbtype.setItems(settings.getSettings().getValues("profile", "sbtype"));
        sbtype.setLayoutData(new GridData());
        sbtype.setToolTipText(settings.msg("dialog.template.sbtype.tooltip"));

        final Label oplRateLabel = new Label(soundblasterGroup, SWT.NONE);
        oplRateLabel.setText(settings.msg("dialog.template.sboplrate"));
        oplrate = new Combo(soundblasterGroup, SWT.READ_ONLY);
        oplrate.setVisibleItemCount(10);
        oplrate.setItems(settings.getSettings().getValues("profile", "oplrate"));
        oplrate.setLayoutData(new GridData());
        oplrate.setToolTipText(settings.msg("dialog.template.sboplrate.tooltip"));

        final Label oplModeLabel = new Label(soundblasterGroup, SWT.NONE);
        oplModeLabel.setLayoutData(new GridData());
        oplModeLabel.setText(settings.msg("dialog.template.sboplmode"));
        oplmode = new Combo(soundblasterGroup, SWT.READ_ONLY);
        oplmode.setItems(settings.getSettings().getValues("profile", "oplmode"));
        oplmode.setLayoutData(new GridData());
        oplmode.setToolTipText(settings.msg("dialog.template.sboplmode.tooltip"));
        
        final Label oplEmuLabel = new Label(soundblasterGroup, SWT.NONE);
        oplEmuLabel.setLayoutData(new GridData());
        oplEmuLabel.setText(settings.msg("dialog.template.sboplemu"));
        oplemu = new Combo(soundblasterGroup, SWT.READ_ONLY);
        oplemu.setItems(settings.getSettings().getValues("profile", "oplemu"));
        oplemu.setLayoutData(new GridData());
        oplemu.setToolTipText(settings.msg("dialog.template.sboplemu.tooltip"));

        final Label addressLabel = new Label(soundblasterGroup, SWT.NONE);
        addressLabel.setText(settings.msg("dialog.template.sbaddress"));
        sbbase = new Combo(soundblasterGroup, SWT.READ_ONLY);
        sbbase.setItems(settings.getSettings().getValues("profile", "sbbase"));
        sbbase.setLayoutData(new GridData());
        sbbase.setToolTipText(settings.msg("dialog.template.sbaddress.tooltip"));

        final Label irqLabel = new Label(soundblasterGroup, SWT.NONE);
        irqLabel.setText(settings.msg("dialog.template.sbirq"));
        irq = new Combo(soundblasterGroup, SWT.READ_ONLY);
        irq.setItems(settings.getSettings().getValues("profile", "irq"));
        irq.setLayoutData(new GridData());
        irq.setToolTipText(settings.msg("dialog.template.sbirq.tooltip"));

        final Label dmaLabel = new Label(soundblasterGroup, SWT.NONE);
        dmaLabel.setText(settings.msg("dialog.template.sbdma"));
        dma = new Combo(soundblasterGroup, SWT.READ_ONLY);
        dma.setItems(settings.getSettings().getValues("profile", "dma"));
        dma.setLayoutData(new GridData());
        dma.setToolTipText(settings.msg("dialog.template.sbdma.tooltip"));

        final Label hdmaLabel = new Label(soundblasterGroup, SWT.NONE);
        hdmaLabel.setLayoutData(new GridData());
        hdmaLabel.setText(settings.msg("dialog.template.sbhdma"));
        hdma = new Combo(soundblasterGroup, SWT.READ_ONLY);
        hdma.setItems(settings.getSettings().getValues("profile", "hdma"));
        hdma.setLayoutData(new GridData());
        hdma.setToolTipText(settings.msg("dialog.template.sbhdma.tooltip"));

        final Label mixerLabel = new Label(soundblasterGroup, SWT.NONE);
        mixerLabel.setText(settings.msg("dialog.template.mixer"));
        sbmixer = new Button(soundblasterGroup, SWT.CHECK);
        sbmixer.setToolTipText(settings.msg("dialog.template.mixer.tooltip"));

        final Group gusGroup = new Group(composite_4, SWT.NONE);
        gusGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        gusGroup.setText(settings.msg("dialog.template.gravisultrasound"));
        final GridLayout gridLayout_8 = new GridLayout();
        gridLayout_8.numColumns = 2;
        gusGroup.setLayout(gridLayout_8);

        final Label enableLabel_1 = new Label(gusGroup, SWT.NONE);
        enableLabel_1.setLayoutData(new GridData());
        enableLabel_1.setText(settings.msg("dialog.template.enablegus"));
        gus = new Button(gusGroup, SWT.CHECK);
        gus.setLayoutData(new GridData());
        gus.setToolTipText(settings.msg("dialog.template.enablegus.tooltip"));

        final Label sampleRateLabel_2 = new Label(gusGroup, SWT.NONE);
        sampleRateLabel_2.setText(settings.msg("dialog.template.gusrate"));
        gusrate = new Combo(gusGroup, SWT.READ_ONLY);
        gusrate.setVisibleItemCount(10);
        gusrate.setItems(settings.getSettings().getValues("profile", "gusrate"));
        gusrate.setLayoutData(new GridData());
        gusrate.setToolTipText(settings.msg("dialog.template.gusrate.tooltip"));

        final Label addressLabel_1 = new Label(gusGroup, SWT.NONE);
        addressLabel_1.setText(settings.msg("dialog.template.gusaddress"));
        gusbase = new Combo(gusGroup, SWT.READ_ONLY);
        gusbase.setItems(settings.getSettings().getValues("profile", "gusbase"));
        gusbase.setLayoutData(new GridData());
        gusbase.setToolTipText(settings.msg("dialog.template.gusaddress.tooltip"));

        final Label irqLabel_1 = new Label(gusGroup, SWT.NONE);
        irqLabel_1.setText(settings.msg("dialog.template.gusirq1"));
        gusirq1 = new Combo(gusGroup, SWT.READ_ONLY);
        gusirq1.setItems(settings.getSettings().getValues("profile", "irq1"));
        gusirq1.setLayoutData(new GridData());
        gusirq1.setToolTipText(settings.msg("dialog.template.gusirq1.tooltip"));

        final Label irq2Label = new Label(gusGroup, SWT.NONE);
        irq2Label.setText(settings.msg("dialog.template.gusirq2"));
        gusirq2 = new Combo(gusGroup, SWT.READ_ONLY);
        gusirq2.setItems(settings.getSettings().getValues("profile", "irq2"));
        gusirq2.setLayoutData(new GridData());

        final Label dmaLabel_1 = new Label(gusGroup, SWT.NONE);
        dmaLabel_1.setText(settings.msg("dialog.template.gusdma1"));
        gusdma1 = new Combo(gusGroup, SWT.READ_ONLY);
        gusdma1.setItems(settings.getSettings().getValues("profile", "dma1"));
        gusdma1.setLayoutData(new GridData());
        gusdma1.setToolTipText(settings.msg("dialog.template.gusdma1.tooltip"));

        final Label hdmaLabel_1 = new Label(gusGroup, SWT.NONE);
        hdmaLabel_1.setLayoutData(new GridData());
        hdmaLabel_1.setText(settings.msg("dialog.template.gusdma2"));
        gusdma2 = new Combo(gusGroup, SWT.READ_ONLY);
        gusdma2.setItems(settings.getSettings().getValues("profile", "dma2"));
        gusdma2.setLayoutData(new GridData());

        final Label ultradirLabel = new Label(gusGroup, SWT.NONE);
        ultradirLabel.setText(settings.msg("dialog.template.ultradir"));
        ultradir = new Text(gusGroup, SWT.BORDER);
        ultradir.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        ultradir.setToolTipText(settings.msg("dialog.template.ultradir.tooltip"));

        final Group speakerGroup = new Group(composite_4, SWT.NONE);
        speakerGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        speakerGroup.setText(settings.msg("dialog.template.pcspeaker"));
        final GridLayout gridLayout_10 = new GridLayout();
        gridLayout_10.numColumns = 2;
        speakerGroup.setLayout(gridLayout_10);

        final Label enableLabel = new Label(speakerGroup, SWT.NONE);
        enableLabel.setText(settings.msg("dialog.template.enablepcspeaker"));
        pcspeaker = new Button(speakerGroup, SWT.CHECK);
        pcspeaker.setToolTipText(settings.msg("dialog.template.enablepcspeaker.tooltip"));

        final Label sampleRateLabel_1 = new Label(speakerGroup, SWT.NONE);
        sampleRateLabel_1.setText(settings.msg("dialog.template.pcrate"));
        pcrate = new Combo(speakerGroup, SWT.READ_ONLY);
        pcrate.setVisibleItemCount(10);
        pcrate.setItems(settings.getSettings().getValues("profile", "pcrate"));
        pcrate.setLayoutData(new GridData());
        pcrate.setToolTipText(settings.msg("dialog.template.pcrate.tooltip"));

        final Group tandyGroup = new Group(composite_4, SWT.NONE);
        tandyGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
        tandyGroup.setText(settings.msg("dialog.template.tandy"));
        final GridLayout gridLayout_11 = new GridLayout();
        gridLayout_11.numColumns = 2;
        tandyGroup.setLayout(gridLayout_11);

        final Label enableLabel_2 = new Label(tandyGroup, SWT.NONE);
        enableLabel_2.setText(settings.msg("dialog.template.enabletandy"));
        tandy = new Combo(tandyGroup, SWT.READ_ONLY);
        tandy.setItems(settings.getSettings().getValues("profile", "tandy"));
        tandy.setLayoutData(new GridData());
        tandy.setToolTipText(settings.msg("dialog.template.enabletandy.tooltip"));

        final Label sampleLabel2 = new Label(tandyGroup, SWT.NONE);
        sampleLabel2.setText(settings.msg("dialog.template.tandyrate"));
        tandyrate = new Combo(tandyGroup, SWT.READ_ONLY);
        tandyrate.setVisibleItemCount(10);
        tandyrate.setItems(settings.getSettings().getValues("profile", "tandyrate"));
        tandyrate.setLayoutData(new GridData());
        tandyrate.setToolTipText(settings.msg("dialog.template.tandyrate.tooltip"));

        final Group disneyGroup = new Group(composite_4, SWT.NONE);
        disneyGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        disneyGroup.setText(settings.msg("dialog.template.miscellaneous"));
        final GridLayout gridLayout_12 = new GridLayout();
        gridLayout_12.numColumns = 2;
        disneyGroup.setLayout(gridLayout_12);

        final Label enableLabel_3 = new Label(disneyGroup, SWT.NONE);
        enableLabel_3.setText(settings.msg("dialog.template.enablesoundsource"));
        disney = new Button(disneyGroup, SWT.CHECK);
        disney.setToolTipText(settings.msg("dialog.template.enablesoundsource.tooltip"));
        
        final Composite composite2 = new Composite(disneyGroup, SWT.NONE);
        composite2.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
        final GridLayout gridLayout2 = new GridLayout();
        gridLayout2.marginHeight = 0;
        gridLayout2.marginWidth = 0;
        gridLayout2.numColumns = 2;
        composite2.setLayout(gridLayout2);
        
        final Label mt32RateLabel = new Label(composite2, SWT.NONE);
        mt32RateLabel.setText(settings.msg("dialog.template.mt32rate"));
        mt32rate = new Combo(composite2, SWT.READ_ONLY);
        mt32rate.setVisibleItemCount(10);
        mt32rate.setItems(settings.getSettings().getValues("profile", "mt32rate"));
    }

    protected void createMachineTab(final TabFolder tabFolder) {
        final TabItem machineTabItem = new TabItem(tabFolder, SWT.NONE);
        machineTabItem.setText(settings.msg("dialog.template.tab.machine"));

        final Composite composite_3 = new Composite(tabFolder, SWT.NONE);
        final GridLayout gridLayout_2 = new GridLayout();
        composite_3.setLayout(gridLayout_2);
        machineTabItem.setControl(composite_3);

        final Group cpuGroup = new Group(composite_3, SWT.NONE);
        cpuGroup.setText(settings.msg("dialog.template.cpu"));
        final GridLayout gridLayout_3 = new GridLayout();
        gridLayout_3.numColumns = 6;
        cpuGroup.setLayout(gridLayout_3);

        final Label machineLabel = new Label(cpuGroup, SWT.NONE);
        machineLabel.setText(settings.msg("dialog.template.machine"));
        machine = new Combo(cpuGroup, SWT.READ_ONLY);
        machine.setLayoutData(new GridData());
        machine.setVisibleItemCount(20);
        machine.setToolTipText(settings.msg("dialog.template.machine.tooltip"));
        
        final Label cputypeLabel = new Label(cpuGroup, SWT.NONE);
        cputypeLabel.setText(settings.msg("dialog.template.cputype"));
        cpu_type = new Combo(cpuGroup, SWT.READ_ONLY);
        cpu_type.setItems(settings.getSettings().getValues("profile", "cputype"));
        cpu_type.setLayoutData(new GridData());
        cpu_type.setVisibleItemCount(10);
        cpu_type.setToolTipText(settings.msg("dialog.template.cputype.tooltip"));
        new Label(cpuGroup, SWT.NONE);
        new Label(cpuGroup, SWT.NONE);

        final Label coreLabel = new Label(cpuGroup, SWT.NONE);
        coreLabel.setText(settings.msg("dialog.template.core"));
        core = new Combo(cpuGroup, SWT.READ_ONLY);
        core.setItems(settings.getSettings().getValues("profile", "core"));
        core.setLayoutData(new GridData());
        core.setToolTipText(settings.msg("dialog.template.core.tooltip"));
        new Label(cpuGroup, SWT.NONE);
        new Label(cpuGroup, SWT.NONE);
        new Label(cpuGroup, SWT.NONE);
        new Label(cpuGroup, SWT.NONE);

        final Label cyclesLabel = new Label(cpuGroup, SWT.NONE);
        cyclesLabel.setText(settings.msg("dialog.template.cycles"));
        cycles = new Combo(cpuGroup, SWT.NONE);
        cycles.setItems(settings.getSettings().getValues("profile", "cycles"));
        cycles.setLayoutData(new GridData(100, SWT.DEFAULT));
        cycles.setVisibleItemCount(15);
        cycles.setToolTipText(settings.msg("dialog.template.cycles.tooltip"));

        final Label upLabel = new Label(cpuGroup, SWT.NONE);
        upLabel.setLayoutData(new GridData());
        upLabel.setText(settings.msg("dialog.template.up"));
        cycles_up = new Combo(cpuGroup, SWT.NONE);
        cycles_up.setItems(settings.getSettings().getValues("profile", "cycles_up"));
        cycles_up.setLayoutData(new GridData(75, SWT.DEFAULT));
        cycles_up.setToolTipText(settings.msg("dialog.template.up.tooltip"));

        final Label downLabel = new Label(cpuGroup, SWT.NONE);
        downLabel.setLayoutData(new GridData());
        downLabel.setText(settings.msg("dialog.template.down"));
        cycles_down = new Combo(cpuGroup, SWT.NONE);
        cycles_down.setItems(settings.getSettings().getValues("profile", "cycles_down"));
        cycles_down.setLayoutData(new GridData(75, SWT.DEFAULT));
        cycles_down.setToolTipText(settings.msg("dialog.template.down.tooltip"));

        final Label timesynchedLabel = new Label(cpuGroup, SWT.NONE);
        timesynchedLabel.setText(settings.msg("dialog.template.timesynched"));
        timesynched = new Button(cpuGroup, SWT.CHECK);
        new Label(cpuGroup, SWT.NONE);
        new Label(cpuGroup, SWT.NONE);
        new Label(cpuGroup, SWT.NONE);
        new Label(cpuGroup, SWT.NONE);

        memoryGroup = new Group(composite_3, SWT.NONE);
        memoryGroup.setText(settings.msg("dialog.template.memory"));
        memoryGroup.setLayoutData(new GridData());
        final GridLayout gridLayout_4 = new GridLayout();
        gridLayout_4.numColumns = 4;
        memoryGroup.setLayout(gridLayout_4);

        final Label sizeLabel = new Label(memoryGroup, SWT.NONE);
        sizeLabel.setText(settings.msg("dialog.template.memorysize"));
        memsize = new Combo(memoryGroup, SWT.READ_ONLY);
        memsize.setItems(settings.getSettings().getValues("profile", "memsize"));
        memsize.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        memsize.setToolTipText(settings.msg("dialog.template.memorysize.tooltip"));
        new Label(memoryGroup, SWT.NONE);
        new Label(memoryGroup, SWT.NONE);

        final Label xmsLabel = new Label(memoryGroup, SWT.NONE);
        xmsLabel.setText(settings.msg("dialog.template.xms"));
        xms = new Button(memoryGroup, SWT.CHECK);
        xms.setToolTipText(settings.msg("dialog.template.xms.tooltip"));
        new Label(memoryGroup, SWT.NONE);
        new Label(memoryGroup, SWT.NONE);

        final Label emsLabel = new Label(memoryGroup, SWT.NONE);
        emsLabel.setText(settings.msg("dialog.template.ems"));
        ems = new Combo(memoryGroup, SWT.READ_ONLY);
        ems.setItems(settings.getSettings().getValues("profile", "ems"));
        ems.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        ems.setToolTipText(settings.msg("dialog.template.ems.tooltip"));
        new Label(memoryGroup, SWT.NONE);
        new Label(memoryGroup, SWT.NONE);

        final Label umbLabel = new Label(memoryGroup, SWT.NONE);
        umbLabel.setText(settings.msg("dialog.template.umb"));
        umb = new Combo(memoryGroup, SWT.READ_ONLY);
        umb.setItems(settings.getSettings().getValues("profile", "umb"));
        umb.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        umb.setToolTipText(settings.msg("dialog.template.umb.tooltip"));
        new Label(memoryGroup, SWT.NONE);
        new Label(memoryGroup, SWT.NONE);
    }

    protected void createDisplayTab(final TabFolder tabFolder) {
        final TabItem displayTabItem = new TabItem(tabFolder, SWT.NONE);
        displayTabItem.setText(settings.msg("dialog.template.tab.display"));

        final Composite composite_2 = new Composite(tabFolder, SWT.NONE);
        final GridLayout gridLayout_5 = new GridLayout();
        gridLayout_5.numColumns = 4;
        composite_2.setLayout(gridLayout_5);
        displayTabItem.setControl(composite_2);

        final Label outputLabel = new Label(composite_2, SWT.NONE);
        outputLabel.setText(settings.msg("dialog.template.output"));
        output = new Combo(composite_2, SWT.READ_ONLY);
        output.setItems(settings.getSettings().getValues("profile", "output"));
        output.setVisibleItemCount(10);
        output.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        output.setToolTipText(settings.msg("dialog.template.output.tooltip"));
        new Label(composite_2, SWT.NONE);
        new Label(composite_2, SWT.NONE);

        final Label frameskipLabel = new Label(composite_2, SWT.NONE);
        frameskipLabel.setText(settings.msg("dialog.template.frameskip"));
        frameskip = new Combo(composite_2, SWT.READ_ONLY);
        frameskip.setItems(settings.getSettings().getValues("profile", "frameskip"));
        frameskip.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        frameskip.setToolTipText(settings.msg("dialog.template.frameskip.tooltip"));
        new Label(composite_2, SWT.NONE);
        new Label(composite_2, SWT.NONE);

        final Label scalerLabel = new Label(composite_2, SWT.NONE);
        scalerLabel.setText(settings.msg("dialog.template.scaler"));
        scaler = new Combo(composite_2, SWT.READ_ONLY);
        scaler.setItems(settings.getSettings().getValues("profile", "scaler"));
        scaler.setVisibleItemCount(15);
        scaler.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        scaler.setToolTipText(settings.msg("dialog.template.scaler.tooltip"));

        final Label forcedLabel = new Label(composite_2, SWT.NONE);
        forcedLabel.setText(settings.msg("dialog.template.scalerforced"));
        scaler_forced = new Button(composite_2, SWT.CHECK);
        scaler_forced.setToolTipText(settings.msg("dialog.template.scalerforced.tooltip"));
        
        final Label fullscreenLabel = new Label(composite_2, SWT.NONE);
        fullscreenLabel.setText(settings.msg("dialog.template.fullscreen"));
        fullscreen = new Button(composite_2, SWT.CHECK);
        fullscreen.setToolTipText(settings.msg("dialog.template.fullscreen.tooltip"));
        new Label(composite_2, SWT.NONE);
        new Label(composite_2, SWT.NONE);

        final Label doubleBuffLabel = new Label(composite_2, SWT.NONE);
        doubleBuffLabel.setText(settings.msg("dialog.template.doublebuffering"));
        fulldouble = new Button(composite_2, SWT.CHECK);
        fulldouble.setToolTipText(settings.msg("dialog.template.doublebuffering.tooltip"));
        new Label(composite_2, SWT.NONE);
        new Label(composite_2, SWT.NONE);

        final Label resolutionLabel = new Label(composite_2, SWT.NONE);
        resolutionLabel.setText(settings.msg("dialog.template.fullscreenresolution"));
        fullresolution = new Combo(composite_2, SWT.READ_ONLY);
        fullresolution.setItems(settings.getSettings().getValues("profile", "fullresolution"));
        fullresolution.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        fullresolution.setVisibleItemCount(10);
        fullresolution.setToolTipText(settings.msg("dialog.template.fullscreenresolution.tooltip"));

        final Label windowResLabel = new Label(composite_2, SWT.NONE);
        windowResLabel.setText(settings.msg("dialog.template.windowresolution"));
        windowresolution = new Combo(composite_2, SWT.READ_ONLY);
        windowresolution.setItems(settings.getSettings().getValues("profile", "windowresolution"));
        windowresolution.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        windowresolution.setVisibleItemCount(10);
        windowresolution.setToolTipText(settings.msg("dialog.template.windowresolution.tooltip"));

        final Label aspectLabel = new Label(composite_2, SWT.NONE);
        aspectLabel.setText(settings.msg("dialog.template.aspectcorrection"));
        aspect = new Button(composite_2, SWT.CHECK);
        aspect.setToolTipText(settings.msg("dialog.template.aspectcorrection.tooltip"));
        new Label(composite_2, SWT.NONE);
        new Label(composite_2, SWT.NONE);
        
        final Label pixelshaderLabel = new Label(composite_2, SWT.NONE);
        pixelshaderLabel.setLayoutData(new GridData());
        pixelshaderLabel.setText(settings.msg("dialog.template.pixelshader"));
        pixelshader = new Combo(composite_2, SWT.READ_ONLY);
        pixelshader.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        pixelshader.setVisibleItemCount(15);
        pixelshader.setItems(settings.getSettings().getValues("profile", "pixelshader"));

        final Label overscanLabel = new Label(composite_2, SWT.NONE);
        overscanLabel.setText(settings.msg("dialog.template.overscan"));
        overscan = new Text(composite_2, SWT.BORDER);
        overscan.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

        final Label svgaChipsetLabel = new Label(composite_2, SWT.NONE);
        svgaChipsetLabel.setText(settings.msg("dialog.template.svgachipset"));
        svgachipset = new Combo(composite_2, SWT.READ_ONLY);
        svgachipset.setItems(settings.getSettings().getValues("profile", "svgachipset"));
        svgachipset.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

        final Label videoRamLabel = new Label(composite_2, SWT.NONE);
        videoRamLabel.setText(settings.msg("dialog.template.videoram"));
        videoram = new Combo(composite_2, SWT.READ_ONLY);
        videoram.setItems(settings.getSettings().getValues("profile", "videoram"));
        videoram.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

        final Label vsyncModeLabel = new Label(composite_2, SWT.NONE);
        vsyncModeLabel.setText(settings.msg("dialog.template.vsyncmode"));
        vsyncmode = new Combo(composite_2, SWT.READ_ONLY);
        vsyncmode.setItems(settings.getSettings().getValues("profile", "vsyncmode"));
        vsyncmode.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

        final Label vsyncRateLabel = new Label(composite_2, SWT.NONE);
        vsyncRateLabel.setLayoutData(new GridData());
        vsyncRateLabel.setText(settings.msg("dialog.template.vsyncrate"));
        vsyncrate = new Text(composite_2, SWT.BORDER);
        vsyncrate.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

        final Label glideLabel = new Label(composite_2, SWT.NONE);
        glideLabel.setText(settings.msg("dialog.template.glide"));
        glide = new Button(composite_2, SWT.CHECK);

        final Label glidePortLabel = new Label(composite_2, SWT.NONE);
        glidePortLabel.setText(settings.msg("dialog.template.glideport"));
        glideport = new Text(composite_2, SWT.BORDER);
        glideport.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

        new Label(composite_2, SWT.NONE);
        new Label(composite_2, SWT.NONE);
        final Label lfbGlideLabel = new Label(composite_2, SWT.NONE);
        lfbGlideLabel.setText(settings.msg("dialog.template.lfbglide"));
        lfbGlide = new Combo(composite_2, SWT.READ_ONLY);
        lfbGlide.setItems(settings.getSettings().getValues("profile", "lfbglide"));
        lfbGlide.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    }

    protected void createGeneralTab(final TabFolder tabFolder) {
        generalTabItem = new TabItem(tabFolder, SWT.NONE);
        generalTabItem.setText(settings.msg("dialog.template.tab.general"));

        final Composite composite_1 = new Composite(tabFolder, SWT.NONE);
        final GridLayout gridLayout_1 = new GridLayout();
        composite_1.setLayout(gridLayout_1);
        generalTabItem.setControl(composite_1);

        associationGroup = new Group(composite_1, SWT.NONE);
        associationGroup.setText(settings.msg("dialog.template.association"));
        associationGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        final GridLayout gridLayout_4 = new GridLayout();
        gridLayout_4.numColumns = 5;
        associationGroup.setLayout(gridLayout_4);
        
        final Label dbversionLabel = new Label(associationGroup, SWT.NONE);
        dbversionLabel.setText(settings.msg("dialog.template.dosboxversion"));
        dbversion = new Combo(associationGroup, SWT.READ_ONLY);
        dbversion.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        dbversion.setVisibleItemCount(20);

        setButton = new Button(associationGroup, SWT.NONE);
        setButton.setText(settings.msg("dialog.template.set"));
        setButton.setToolTipText(settings.msg("dialog.template.set.tooltip"));
        setButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
            	doPerformDosboxConfAction(DosboxConfAction.SET);
            }
        });

        switchButton = new Button(associationGroup, SWT.NONE);
        switchButton.setText(settings.msg("dialog.template.switch"));
        switchButton.setToolTipText(settings.msg("dialog.template.switch.tooltip"));
        switchButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
            	doPerformDosboxConfAction(DosboxConfAction.SWITCH);
            }
        });
        
        dbversion.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
                setButton.setEnabled(true);
                switchButton.setEnabled(true);
            }
        });

        reloadButton = new Button(associationGroup, SWT.NONE);
        reloadButton.setText(settings.msg("dialog.template.reloadsettings"));
        reloadButton.setToolTipText(settings.msg("dialog.template.reloadsettings.tooltip"));
        reloadButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent event) {
            	doPerformDosboxConfAction(DosboxConfAction.RELOAD);
            }
        });

        miscGroup = new Group(composite_1, SWT.NONE);
        miscGroup.setText(settings.msg("dialog.template.miscellaneous"));
        miscGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        final GridLayout gridLayout_5 = new GridLayout();
        gridLayout_5.numColumns = 3;
        miscGroup.setLayout(gridLayout_5);
        
        new Label(miscGroup, SWT.NONE);
        final Label activeLabel = new Label(miscGroup, SWT.NONE);
        activeLabel.setText(settings.msg("dialog.template.active"));
        final Label inactiveLabel = new Label(miscGroup, SWT.NONE);
        inactiveLabel.setText(settings.msg("dialog.template.inactive"));

        final Label priorityLabel = new Label(miscGroup, SWT.NONE);
        priorityLabel.setText(settings.msg("dialog.template.priority"));
        priority_active = new Combo(miscGroup, SWT.READ_ONLY);
        priority_active.setItems(settings.getSettings().getValues("profile", "priority_active"));
        priority_active.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
        priority_active.setToolTipText(settings.msg("dialog.template.priority.tooltip"));
        priority_inactive = new Combo(miscGroup, SWT.READ_ONLY);
        priority_inactive.setItems(settings.getSettings().getValues("profile", "priority_inactive"));
        priority_inactive.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
        priority_inactive.setToolTipText(settings.msg("dialog.template.priority.tooltip"));

        final Label waitOnErrorLabel = new Label(miscGroup, SWT.NONE);
        waitOnErrorLabel.setText(settings.msg("dialog.template.waitonerror"));
        waitonerror = new Button(miscGroup, SWT.CHECK);
        waitonerror.setToolTipText(settings.msg("dialog.template.waitonerror.tooltip"));
        new Label(miscGroup, SWT.NONE);

        final Label exitLabel = new Label(miscGroup, SWT.NONE);
        exitLabel.setText(settings.msg("dialog.template.exitafterwards"));
        exit = new Button(miscGroup, SWT.CHECK);
        new Label(miscGroup, SWT.NONE);

        final Label languageFileLabel = new Label(miscGroup, SWT.NONE);
        languageFileLabel.setLayoutData(new GridData());
        languageFileLabel.setText(settings.msg("dialog.template.languagefile"));
        language = new Text(miscGroup, SWT.BORDER);
        language.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
        language.setToolTipText(settings.msg("dialog.template.languagefile.tooltip"));
        
        final Label capturesLabel = new Label(miscGroup, SWT.NONE);
        capturesLabel.setLayoutData(new GridData());
        capturesLabel.setText(settings.msg("dialog.template.captures"));
        captures = new Text(miscGroup, SWT.BORDER);
        captures.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
        captures.setEditable(false);
        captures.setToolTipText(settings.msg("dialog.template.captures.tooltip"));
        
        final Label configFileLabel = new Label(miscGroup, SWT.NONE);
        configFileLabel.setText(settings.msg("dialog.profile.configfile"));
        config_file = new Text(miscGroup, SWT.BORDER);
        config_file.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));
        config_file.setEditable(false);
        config_file.setText(result instanceof Template ? 
        		FileUtils.constructCanonicalTemplateFileLocation(((Template)result).getId()).getPath(): SettingsDialog.confFilenames[0]);
    }

	protected void createInfoTab(final TabFolder tabFolder) {
        infoTabItem = new TabItem(tabFolder, SWT.NONE);
        infoTabItem.setText(settings.msg("dialog.template.tab.info"));

        final Composite composite = new Composite(tabFolder, SWT.NONE);
        final GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 2;
        composite.setLayout(gridLayout);
        infoTabItem.setControl(composite);

        final Label titleLabel = new Label(composite, SWT.NONE);
        titleLabel.setText(settings.msg("dialog.template.title"));
        title = new Text(composite, SWT.BORDER);
        title.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        
        final Label defaultLabel = new Label(composite, SWT.NONE);
        defaultLabel.setText(settings.msg("dialog.template.default"));
        defaultButton = new Button(composite, SWT.CHECK);
    }

    protected void selectSettingsByConfiguration(Conf conf) {
    	SectionsWrapper sections = conf.getSettings();
        setFieldIfEnabled(sections, "sdl", "priority", priority_active, priority_inactive);
        setFieldIfEnabled(sections, "sdl", "waitonerror", waitonerror);
        setFieldIfEnabled(sections, "dosbox", "language", language);
        setFieldIfEnabled(settings.msg("dialog.profile.automatic"), false, captures);
        setFieldIfEnabled(sections, "sdl", "output", output);
        setFieldIfEnabled(sections, "render", "frameskip", frameskip);
    	if (sections.isConflictingValue("render", "scaler")) {
    		setFieldIfEnabled(sections, "render", "scaler", scaler);
    		setFieldIfEnabled(null, true, scaler_forced);
    	} else {
    		String value = sections.getValue("render", "scaler");
    		if (value.endsWith(" forced")) {
    			setFieldIfEnabled(value.substring(0, value.length() - 7), false, scaler);
    			setFieldIfEnabled(String.valueOf(true), false, scaler_forced);
    		} else {
    			setFieldIfEnabled(value, false, scaler);
    			setFieldIfEnabled(String.valueOf(false), false, scaler_forced);
    		}
    	}
        setFieldIfEnabled(sections, "sdl", "pixelshader", pixelshader);
        setFieldIfEnabled(sections, "sdl", "fullscreen", fullscreen);
        setFieldIfEnabled(sections, "sdl", "fulldouble", fulldouble);
        setFieldIfEnabled(sections, "sdl", "fullresolution", fullresolution);
        setFieldIfEnabled(sections, "sdl", "windowresolution", windowresolution);
        setFieldIfEnabled(sections, "render", "aspect", aspect);
        setFieldIfEnabled(sections, "sdl", "overscan", overscan);
        setFieldIfEnabled(sections, "vga", "svgachipset", svgachipset);
        setFieldIfEnabled(sections, "vga", "videoram", videoram);
        setFieldIfEnabled(sections, "vsync", "vsyncmode", vsyncmode);
        setFieldIfEnabled(sections, "vsync", "vsyncrate", vsyncrate);
        setFieldIfEnabled(sections, "glide", "glide", glide);
        setFieldIfEnabled(sections, "glide", "port", "grport", glideport);
        setFieldIfEnabled(sections, "glide", "lfb", lfbGlide);
        setFieldIfEnabled(sections, "dosbox", "machine", machine);
        setFieldIfEnabled(sections, "cpu", "cputype", cpu_type);
        setFieldIfEnabled(sections, "cpu", "core", core);
        setFieldIfEnabled(sections, "cpu", "cycles", cycles);
        setFieldIfEnabled(sections, "cpu", "cycleup", cycles_up);
        setFieldIfEnabled(sections, "cpu", "cycledown", cycles_down);
        setFieldIfEnabled(sections, "cpu", "timesynched", timesynched);
        setFieldIfEnabled(sections, "dosbox", "memsize", memsize);
        setFieldIfEnabled(sections, "dos", "xms", xms);
        setFieldIfEnabled(sections, "dos", "ems", ems);
        setFieldIfEnabled(sections, "dos", "umb", umb);
        setFieldIfEnabled(sections, "mixer", "nosound", nosound);
        setFieldIfEnabled(sections, "mixer", "rate", rate);
        setFieldIfEnabled(sections, "midi", "mt32rate", mt32rate);
        setFieldIfEnabled(sections, "mixer", "blocksize", blocksize);
        setFieldIfEnabled(sections, "mixer", "prebuffer", prebuffer);
        if (sections.hasValue("midi", "intelligent")) {
        	if (sections.isConflictingValue("midi", "mpu401") || sections.isConflictingValue("midi", "intelligent")) {
        		setFieldIfEnabled(null, true, mpu401);
        	} else {
        		setFieldIfEnabled(sections.getBooleanValue("midi", "mpu401")? (sections.getBooleanValue("midi", "intelligent")? "intelligent": "uart"): "none", false, mpu401);
        	}
        } else {
        	setFieldIfEnabled(sections, "midi", "mpu401", mpu401);
        }
        setFieldIfEnabled(sections, "midi", "device", "mididevice", midi_device);
        setFieldIfEnabled(sections, "midi", "config", "midiconfig", midi_config);
        setFieldIfEnabled(sections, "sblaster", "type", "sbtype", sbtype);
        setFieldIfEnabled(sections, "sblaster", "oplmode", oplmode);
        setFieldIfEnabled(sections, "sblaster", "oplrate", oplrate);
        setFieldIfEnabled(sections, "sblaster", "oplemu", oplemu);
        setFieldIfEnabled(sections, "sblaster", "base", "sbbase", sbbase);
        setFieldIfEnabled(sections, "sblaster", "irq", irq);
        setFieldIfEnabled(sections, "sblaster", "dma", dma);
        setFieldIfEnabled(sections, "sblaster", "hdma", hdma);
        setFieldIfEnabled(sections, "sblaster", "mixer", "sbmixer", sbmixer);
        setFieldIfEnabled(sections, "gus", "gus", gus);
        setFieldIfEnabled(sections, "gus", "rate", "gusrate", gusrate);
        setFieldIfEnabled(sections, "gus", "base", "gusbase", gusbase);
        setFieldIfEnabled(sections, "gus", "irq1", "gusirq", gusirq1);
        setFieldIfEnabled(sections, "gus", "irq2", "gusirq", gusirq2);
        setFieldIfEnabled(sections, "gus", "dma1", "gusdma", gusdma1);
        setFieldIfEnabled(sections, "gus", "dma2", "gusdma", gusdma2);
        setFieldIfEnabled(sections, "gus", "ultradir", ultradir);
        setFieldIfEnabled(sections, "speaker", "pcspeaker", pcspeaker);
        setFieldIfEnabled(sections, "speaker", "pcrate", pcrate);
        setFieldIfEnabled(sections, "speaker", "tandy", tandy);
        setFieldIfEnabled(sections, "speaker", "tandyrate", tandyrate);
        setFieldIfEnabled(sections, "speaker", "disney", disney);
        setFieldIfEnabled(sections, "sdl", "autolock", autolock);
        setFieldIfEnabled(sections, "sdl", "sensitivity", sensitivity);
        setFieldIfEnabled(sections, "sdl", "usescancodes", usescancodes);
        setFieldIfEnabled(sections, "sdl", "mapperfile", mapperfile);
        setFieldIfEnabled(sections, "dos", "keyboardlayout", keyboard_layout);
        if (sections.hasValue("joystick", "joysticktype")) {
            setFieldIfEnabled(sections, "joystick", "joysticktype", joysticktype);
            setFieldIfEnabled(sections, "joystick", "timed", timed);
            setFieldIfEnabled(sections, "joystick", "autofire", autofire);
            setFieldIfEnabled(sections, "joystick", "swap34", swap34);
            setFieldIfEnabled(sections, "joystick", "buttonwrap", buttonwrap);
        } else {
            setFieldIfEnabled(sections, "bios", "joysticktype", joysticktype);
        }
        setFieldIfEnabled(sections, "serial", "serial1", serial1);
        setFieldIfEnabled(sections, "serial", "serial2", serial2);
        setFieldIfEnabled(sections, "serial", "serial3", serial3);
        setFieldIfEnabled(sections, "serial", "serial4", serial4);
        setFieldIfEnabled(sections, "ipx", "ipx", ipx);
        ipxnet.setEnabled(ipx.getSelection());

        // autoexec settings
        setFieldIfEnabled(String.valueOf(conf.getAutoexec().isExit()), Conf.isConflictingValue(conf.getAutoexec().isExit()), exit);
        setFieldIfEnabled(conf.getAutoexec().getMixer(), Conf.isConflictingValue(conf.getAutoexec().getMixer()), mixer_config);
        setFieldIfEnabled(conf.getAutoexec().getKeyb(), Conf.isConflictingValue(conf.getAutoexec().getKeyb()), keyb);
        setFieldIfEnabled(conf.getAutoexec().getIpxnet(), Conf.isConflictingValue(conf.getAutoexec().getIpxnet()), ipxnet);
        
        if (!isMultiEdit()) {
	        mountingpoints.setItems(conf.getAutoexec().getMountingpoints());
	        dosExpandItem.setExpanded(!conf.getAutoexec().isBooter());
	        booterExpandItem.setExpanded(conf.getAutoexec().isBooter());
        }
    }

    protected void updateConfigurationBySettings(Conf conf) {
		boolean singleEdit = !isMultiEdit();
		conf.updateValue("sdl", "priority", priority_active.getText() + "," + priority_inactive.getText(), singleEdit || ((Boolean)priority_active.getData() || (Boolean)priority_inactive.getData()));
        conf.updateValue("sdl", "waitonerror", String.valueOf(waitonerror.getSelection()), singleEdit || (Boolean)waitonerror.getData());
        conf.updateValue("dosbox", "language", language.getText(), singleEdit || (Boolean)language.getData());
        conf.updateValue("sdl", "output", output.getText(), singleEdit || (Boolean)output.getData());
        conf.updateValue("render", "frameskip", frameskip.getText(), singleEdit || (Boolean)frameskip.getData());
        conf.updateScalerValue(scaler.getText(), scaler_forced.getSelection(), singleEdit || (Boolean)scaler.getData() || (Boolean)scaler_forced.getData());
        conf.updateValue("sdl", "pixelshader", pixelshader.getText(), singleEdit || (Boolean)pixelshader.getData());
        conf.updateValue("sdl", "fullscreen", String.valueOf(fullscreen.getSelection()), singleEdit || (Boolean)fullscreen.getData());
        conf.updateValue("sdl", "fulldouble", String.valueOf(fulldouble.getSelection()), singleEdit || (Boolean)fulldouble.getData());
        conf.updateValue("sdl", "fullresolution", fullresolution.getText(), singleEdit || (Boolean)fullresolution.getData());
        conf.updateValue("sdl", "windowresolution", windowresolution.getText(), singleEdit || (Boolean)windowresolution.getData());
        conf.updateValue("render", "aspect", String.valueOf(aspect.getSelection()), singleEdit || (Boolean)aspect.getData());
        conf.updateValue("sdl", "overscan", overscan.getText(), singleEdit || (Boolean)overscan.getData());
        conf.updateValue("vga", "svgachipset", svgachipset.getText(), singleEdit || (Boolean)svgachipset.getData());
        conf.updateValue("vga", "videoram", videoram.getText(), singleEdit || (Boolean)videoram.getData());
        conf.updateValue("vsync", "vsyncmode", vsyncmode.getText(), singleEdit || (Boolean)vsyncmode.getData());
        conf.updateValue("vsync", "vsyncrate", vsyncrate.getText(), singleEdit || (Boolean)vsyncrate.getData());
        conf.updateValue("glide", "glide", String.valueOf(glide.getSelection()), singleEdit || (Boolean)glide.getData());
        conf.updateValue("glide", "port", "grport", glideport.getText(), singleEdit || (Boolean)glideport.getData());
        conf.updateValue("glide", "lfb", lfbGlide.getText(), singleEdit || (Boolean)lfbGlide.getData());
        conf.updateValue("dosbox", "machine", machine.getText(), singleEdit || (Boolean)machine.getData());
        conf.updateValue("cpu", "cputype", cpu_type.getText(), singleEdit || (Boolean)cpu_type.getData());
        conf.updateValue("cpu", "core", core.getText(), singleEdit || (Boolean)core.getData());
        conf.updateValue("cpu", "cycles", cycles.getText(), singleEdit || (Boolean)cycles.getData());
        conf.updateValue("cpu", "cycleup", cycles_up.getText(), singleEdit || (Boolean)cycles_up.getData());
        conf.updateValue("cpu", "cycledown", cycles_down.getText(), singleEdit || (Boolean)cycles_down.getData());
        conf.updateValue("cpu", "timesynched", String.valueOf(timesynched.getSelection()), singleEdit || (Boolean)timesynched.getData());
        conf.updateValue("dosbox", "memsize", memsize.getText(), singleEdit || (Boolean)memsize.getData());
        conf.updateValue("dos", "xms", String.valueOf(xms.getSelection()), singleEdit || (Boolean)xms.getData());
        conf.updateValue("dos", "ems", ems.getText(), singleEdit || (Boolean)ems.getData());
        conf.updateValue("dos", "umb", umb.getText(), singleEdit || (Boolean)umb.getData());
        conf.updateValue("mixer", "nosound", String.valueOf(nosound.getSelection()), singleEdit || (Boolean)nosound.getData());
        conf.updateValue("mixer", "rate", rate.getText(), singleEdit || (Boolean)rate.getData());
        conf.updateValue("midi", "mt32rate", mt32rate.getText(), singleEdit || (Boolean)mt32rate.getData());
        conf.updateValue("mixer", "blocksize", blocksize.getText(), singleEdit || (Boolean)blocksize.getData());
        conf.updateValue("mixer", "prebuffer", prebuffer.getText(), singleEdit || (Boolean)prebuffer.getData());
        conf.updateMidiValue(mpu401.getText(), singleEdit || (Boolean)mpu401.getData());
        conf.updateValue("midi", "device", "mididevice", midi_device.getText(), singleEdit || (Boolean)midi_device.getData());
        conf.updateValue("midi", "config", "midiconfig", midi_config.getText(), singleEdit || (Boolean)midi_config.getData());
        conf.updateValue("sblaster", "type", "sbtype", sbtype.getText(), singleEdit || (Boolean)sbtype.getData());
        conf.updateValue("sblaster", "oplmode", oplmode.getText(), singleEdit || (Boolean)oplmode.getData());
        conf.updateValue("sblaster", "oplrate", oplrate.getText(), singleEdit || (Boolean)oplrate.getData());
        conf.updateValue("sblaster", "oplemu", oplemu.getText(), singleEdit || (Boolean)oplemu.getData());
        conf.updateValue("sblaster", "base", "sbbase", sbbase.getText(), singleEdit || (Boolean)sbbase.getData());
        conf.updateValue("sblaster", "irq", irq.getText(), singleEdit || (Boolean)irq.getData());
        conf.updateValue("sblaster", "dma", dma.getText(), singleEdit || (Boolean)dma.getData());
        conf.updateValue("sblaster", "hdma", hdma.getText(), singleEdit || (Boolean)hdma.getData());
        conf.updateValue("sblaster", "mixer", "sbmixer", String.valueOf(sbmixer.getSelection()), singleEdit || (Boolean)sbmixer.getData());
        conf.updateValue("gus", "gus", String.valueOf(gus.getSelection()), singleEdit || (Boolean)gus.getData());
        conf.updateValue("gus", "rate", "gusrate", gusrate.getText(), singleEdit || (Boolean)gusrate.getData());
        conf.updateValue("gus", "base", "gusbase", gusbase.getText(), singleEdit || (Boolean)gusbase.getData());
        conf.updateValue("gus", "irq1", "gusirq", gusirq1.getText(), singleEdit || (Boolean)gusirq1.getData());
        conf.updateValue("gus", "irq2", gusirq2.getText(), singleEdit || (Boolean)gusirq2.getData());
        conf.updateValue("gus", "dma1", "gusdma", gusdma1.getText(), singleEdit || (Boolean)gusdma1.getData());
        conf.updateValue("gus", "dma2", gusdma2.getText(), singleEdit || (Boolean)gusdma2.getData());
        conf.updateValue("gus", "ultradir", ultradir.getText(), singleEdit || (Boolean)ultradir.getData());
        conf.updateValue("speaker", "pcspeaker", String.valueOf(pcspeaker.getSelection()), singleEdit || (Boolean)pcspeaker.getData());
        conf.updateValue("speaker", "pcrate", pcrate.getText(), singleEdit || (Boolean)pcrate.getData());
        conf.updateValue("speaker", "tandy", tandy.getText(), singleEdit || (Boolean)tandy.getData());
        conf.updateValue("speaker", "tandyrate", tandyrate.getText(), singleEdit || (Boolean)tandyrate.getData());
        conf.updateValue("speaker", "disney", String.valueOf(disney.getSelection()), singleEdit || (Boolean)disney.getData());
        conf.updateValue("sdl", "autolock", String.valueOf(autolock.getSelection()), singleEdit || (Boolean)autolock.getData());
        conf.updateValue("sdl", "sensitivity", sensitivity.getText(), singleEdit || (Boolean)sensitivity.getData());
        conf.updateValue("sdl", "usescancodes", String.valueOf(usescancodes.getSelection()), singleEdit || (Boolean)usescancodes.getData());
        conf.updateValue("sdl", "mapperfile", mapperfile.getText(), singleEdit || (Boolean)mapperfile.getData());
        conf.updateValue("dos", "keyboardlayout", keyboard_layout.getText(), singleEdit || (Boolean)keyboard_layout.getData());
        conf.updateJoystickValue(joysticktype.getText(), timed.getSelection(), autofire.getSelection(), swap34.getSelection(),
        		buttonwrap.getSelection(), singleEdit || (Boolean)joysticktype.getData(), singleEdit || (Boolean)timed.getData(),
        		singleEdit || (Boolean)autofire.getData(), singleEdit || (Boolean)swap34.getData(), singleEdit || (Boolean)buttonwrap.getData());
        conf.updateValue("serial", "serial1", serial1.getText(), singleEdit || (Boolean)serial1.getData());
        conf.updateValue("serial", "serial2", serial2.getText(), singleEdit || (Boolean)serial2.getData());
        conf.updateValue("serial", "serial3", serial3.getText(), singleEdit || (Boolean)serial3.getData());
        conf.updateValue("serial", "serial4", serial4.getText(), singleEdit || (Boolean)serial4.getData());
        conf.updateValue("ipx", "ipx", String.valueOf(ipx.getSelection()), singleEdit || (Boolean)ipx.getData());
        
        // autoexec settings
        if (singleEdit) {
        	conf.setAutoexecSettingsForTemplate(exit.getSelection(), mixer_config.getText(), keyb.getText(),
        			ipx.getSelection()? ipxnet.getText(): "", booterExpandItem.getExpanded());
        }
	}

    protected void doAddMount() {
        final EditMountDialog addMountDialog = new EditMountDialog(shell);
        try {
            addMountDialog.setDefaultDriveletter(
               Mount.getFreeDriveletter(booterExpandItem.getExpanded(), multiProfileList.get(0).getConf().nettoMountedDriveLetters()));
        } catch (Exception e) {
            // nothing we can do, just take default 'C'
        }
        String mount = (String) addMountDialog.open();
        if (mount != null) {
            mountingpoints.setItems(multiProfileList.get(0).getConf().addMount(mount));
            mountingpoints.select(mountingpoints.getItemCount() - 1);
        }
    }

    protected void doEditMount() {
        int mounts = mountingpoints.getItemCount();
        int sel = mountingpoints.getSelectionIndex();
        if (sel != -1) {
            final EditMountDialog editMountDialog = new EditMountDialog(shell);
            editMountDialog.setMount(mountingpoints.getItem(sel));
            String mount = (String) editMountDialog.open();
            if (mount != null) {
                mountingpoints.setItems(multiProfileList.get(0).getConf().editMount(sel, mount));
                if (mountingpoints.getItemCount() == mounts) {
                    mountingpoints.select(sel);
                } else {
                    mountingpoints.select(mountingpoints.getItemCount() - 1);
                }
            }
        }
    }
    
    protected void doRemoveMount() {
        int mounts = mountingpoints.getItemCount();
        int sel = mountingpoints.getSelectionIndex();
        if (sel == -1 && mounts == 1) { sel = 0; mountingpoints.select(sel); }
        if (sel != -1) {
            mountingpoints.setItems(multiProfileList.get(0).getConf().removeMount(sel));
            if (mountingpoints.getItemCount() == mounts) {
                mountingpoints.select(sel);
            } else {
                if (mountingpoints.getItemCount() > 0) {
                    mountingpoints.select(mountingpoints.getItemCount() - 1);
                }
            }
        }
    }

    protected void enableSettingsByConfiguration(SectionsWrapper conf) {
    	setButton.setEnabled(false);
        switchButton.setEnabled(false);
        
    	String[] otherValues = null;
    	if (conf != null) {
        	otherValues = conf.hasValue("cpu", "cputype")? settings.getSettings().getValues("profile", "machine073"): settings.getSettings().getValues("profile", "machine");
        } else {
        	otherValues = settings.getSettings().getCommonValues("profile", "machine073", "machine");
        }
    	if (!Arrays.equals(machine.getItems(), otherValues)) {
    		Object obj = machine.getData();
            machine.setItems(otherValues);
            machine.setData(obj);
    	}
        
        enableDisableControl(conf, "cpu", "cputype", cpu_type);
        enableDisableControl(conf, "dos", "umb", umb);
        enableDisableControl(conf, "sdl", "windowresolution", windowresolution);
        enableDisableControl(conf, "sdl", "pixelshader", pixelshader);
        enableDisableControl(conf, "sdl", "overscan", overscan);
        enableDisableControl(conf, "sdl", "usescancodes", usescancodes);
        enableDisableControl(conf, "vga", "svgachipset", svgachipset);
        enableDisableControl(conf, "vga", "videoram", videoram);
        enableDisableControl(conf, "vsync", "vsyncmode", vsyncmode);
        enableDisableControl(conf, "vsync", "vsyncrate", vsyncrate);
        enableDisableControl(conf, "glide", "glide", glide);
        enableDisableControl(conf, "glide", "port", "grport", glideport);
        enableDisableControl(conf, "glide", "lfb", lfbGlide);
        enableDisableControl(conf, "cpu", "timesynched", timesynched);
        enableDisableControl(conf, "sblaster", "oplemu", oplemu);
        enableDisableControl(conf, "gus", "irq2", gusirq2);
        enableDisableControl(conf, "gus", "dma2", gusdma2);
        enableDisableControl(conf, "midi", "mt32rate", mt32rate);
        enableDisableControl(conf, "speaker", "tandy", tandy);
        enableDisableControl(conf, "bios", "joysticktype", "joystick", "joysticktype", joysticktype);
        enableDisableControl(conf, "joystick", "timed", timed);
        enableDisableControl(conf, "joystick", "autofire", autofire);
        enableDisableControl(conf, "joystick", "swap34", swap34);
        enableDisableControl(conf, "joystick", "buttonwrap", buttonwrap);
        enableDisableControl(conf, "dos", "keyboardlayout", keyboard_layout);
        enableDisableControl(conf, "serial", "serial1", serial1);
        enableDisableControl(conf, "serial", "serial2", serial2);
        enableDisableControl(conf, "serial", "serial3", serial3);
        enableDisableControl(conf, "serial", "serial4", serial4);
    }
    
    protected void doPerformDosboxConfAction(DosboxConfAction action) {
		try {
	    	ByteArrayOutputStream bos = new ByteArrayOutputStream();
	        PrintStream ps = new PrintStream(bos);
			updateConfigurationBySettings(multiProfileList.get(0).getConf());
			Conf newDosboxVersion = new Conf(dbversionsList.get(dbversion.getSelectionIndex()), ps);
			
			if (action == DosboxConfAction.SET) {
				multiProfileList.get(0).getConf().setToDosboxVersion(newDosboxVersion);
			} else if (action == DosboxConfAction.SWITCH) {
				multiProfileList.get(0).getConf().switchToDosboxVersion(newDosboxVersion);
			} else if (action == DosboxConfAction.RELOAD) {
				multiProfileList.get(0).getConf().reloadDosboxVersion(newDosboxVersion);
			}
			
			enableSettingsByConfiguration(multiProfileList.get(0).getConf().getDosboxSettings());
            selectSettingsByConfiguration(multiProfileList.get(0).getConf());
            
            if (bos.size() > 0) {
            	GeneralPurposeDialogs.warningMessage(getParent(), bos.toString());
            	bos.reset();
            }
		} catch (IOException e) {
			GeneralPurposeDialogs.warningMessage(getParent(), e);
		}
	}

    protected static void enableDisableControl(final SectionsWrapper dbConf, final String oldSection, final String oldItem,
    		final String newSection, final String newItem, final Control control) {
    	control.setEnabled((dbConf != null) && (dbConf.hasValue(newSection, newItem) || dbConf.hasValue(oldSection, oldItem)));
    }
    
    protected static void enableDisableControl(final SectionsWrapper dbConf, final String section, final String oldItem,
    		final String newItem, final Control control) {
    	control.setEnabled((dbConf != null) && (dbConf.hasValue(section, newItem) || dbConf.hasValue(section, oldItem)));
    }

    protected static void enableDisableControl(final SectionsWrapper dbConf, final String section, final String item,
            final Control control) {
        control.setEnabled((dbConf != null) && dbConf.hasValue(section, item));
    }

	protected static void highlight(final Control control, final int foreGroundColor) {
		Control[] children = control.getParent().getChildren();
		for (int i = 0; i < children.length; i++) {
			if (children[i] == control) {
				if (i > 0) {
					Control target = null;
					if (children[i - 1] instanceof Label) {
						target = children[i - 1];
					} else {
						if ((i + 1) == children.length - 1) {
							target = children[i + 1];
						} else if ((i - 1) > 0 && children[i - 2] instanceof Label) {
							target = children[i - 2];
						} 
					}
					if (target != null) {
						target.setForeground(control.getDisplay().getSystemColor(foreGroundColor));
					}
				} else {
					highlight(control.getParent(), foreGroundColor);
				}
			}
		}
	}
	
	protected static void setFieldIfEnabled(final String value, final boolean isConflictingValue, final AutoSelectCombo combo) {
    	if (isConflictingValue) {
    		highlight(combo.getControl(), SWT.COLOR_DARK_RED);
    	} else {
    		if (!combo.getText().equals(value))
    			combo.setText(value);
    	}
    }
	
	protected static void setFieldIfEnabled(final String value, final boolean isConflictingValue, final Control control) {
        if (control.isEnabled()) {
            if (control instanceof Text) {
            	if (isConflictingValue) {
            		highlight(control, SWT.COLOR_DARK_RED);
            	} else {
	            	if (!((Text)control).getText().equals(value))
	            		((Text)control).setText(value);
            	}
            } else if (control instanceof Combo) {
            	if (isConflictingValue) {
            		highlight(control, SWT.COLOR_DARK_RED);
            	} else {
            		if (!((Combo)control).getText().equals(value))
            			((Combo)control).setText(value);
            	}
            } else if (control instanceof Button) {
            	if (isConflictingValue) {
            		((Button)control).setSelection(true);
            		((Button)control).setGrayed(true);
            		highlight(control, SWT.COLOR_DARK_RED);
            	} else {
	            	boolean newValue = Boolean.valueOf(value);
	        		if ((((Button)control).getSelection() != newValue) || ((Button)control).getGrayed()) {
	            		((Button)control).setSelection(newValue);
	                	((Button)control).notifyListeners(SWT.Selection, new Event());
	        		}
            	}
            } else if (control instanceof Scale) {
            	if (isConflictingValue) {
            		highlight(control, SWT.COLOR_DARK_RED);
            	} else {
	            	Integer newValue = Integer.valueOf(value);
	        		if (((Scale)control).getSelection() != newValue) {
	            		((Scale)control).setSelection(newValue);
	        		}
            	}
            } else if (control instanceof Spinner) {
            	if (isConflictingValue) {
            		highlight(control, SWT.COLOR_DARK_RED);
            	} else {
	            	Integer newValue = Integer.valueOf(value);
	        		if (((Spinner)control).getSelection() != newValue) {
	            		((Spinner)control).setSelection(newValue);
	        		}
            	}
            }
        }
    }

    protected static void setFieldIfEnabled(final SectionsWrapper conf, final String section, final String item, final Control control) {
       	setFieldIfEnabled(conf.getValue(section, item), conf.isConflictingValue(section, item), control);
    }

    protected static void setFieldIfEnabled(final SectionsWrapper conf, final String section, final String item, final Control control1, final Control control2) {
    	if (conf.isConflictingValue(section, item)) {
    		setFieldIfEnabled(conf.getValue(section, item), conf.isConflictingValue(section, item), control1);
    		setFieldIfEnabled(conf.getValue(section, item), conf.isConflictingValue(section, item), control2);
    	} else {
	    	String value = conf.getValue(section, item);
	        String[] seperatedValues = value.split(",");
	        if ((seperatedValues != null) && (seperatedValues.length >= 2)) {
	            setFieldIfEnabled(seperatedValues[0], false, control1);
	            setFieldIfEnabled(seperatedValues[1], false, control2);
	        }
        }
    }
    
    protected static void setFieldIfEnabled(final SectionsWrapper conf, final String section, 
            final String oldItem, final String newItem, final Control control) {
        if (conf.hasValue(section, newItem)) {
            setFieldIfEnabled(conf, section, newItem, control);
        } else {
            setFieldIfEnabled(conf, section, oldItem, control);
        }
    }
    
    protected boolean isMultiEdit() {
    	return multiProfileList.size() > 1;
    }
    
    protected String fetch(Text t) {
    	return ((Boolean)t.getData())? t.getText(): null;
    }

    protected String fetch(Combo t) {
    	return ((Boolean)t.getData())? t.getText(): null;
    }

    protected String fetch(AutoSelectCombo t) {
    	return ((Boolean)t.getData())? t.getText(): null;
    }

    protected Boolean fetch(Button t) {
    	return ((Boolean)t.getData())? t.getSelection(): null;
    }

    protected int fetch(Scale t) {
    	return ((Boolean)t.getData())? t.getSelection(): -1;
    }

    protected int fetch(Spinner t) {
    	return ((Boolean)t.getData())? t.getSelection(): -1;
    }
    
    private boolean isValid() {
        GeneralPurposeDialogs.initErrorDialog();
        if (title.getText().equals("")) {
            GeneralPurposeDialogs.addError(settings.msg("dialog.template.required.title"), title, infoTabItem);
        }
        if (setButton.isEnabled()) {
        	GeneralPurposeDialogs.addError(settings.msg("dialog.template.required.dosboxassociation"), setButton, generalTabItem);
        }
        return !GeneralPurposeDialogs.displayErrorDialog(shell);
    }
}
