/*
 *  Copyright (C) 2006-2019  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.dialog;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import org.apache.commons.lang3.StringUtils;
import org.dbgl.gui.GeneralPurposeDialogs;
import org.dbgl.gui.abstractdialog.SizeControlledTabbedDialog;
import org.dbgl.gui.controls.BrowseButton;
import org.dbgl.gui.controls.BrowseButton.BrowseType;
import org.dbgl.gui.controls.BrowseButton.CanonicalType;
import org.dbgl.model.aggregate.DosboxVersion;
import org.dbgl.model.factory.DosboxVersionFactory;
import org.dbgl.model.repository.DosboxVersionRepository;
import org.dbgl.service.FileLocationService;
import org.dbgl.util.ExecuteUtils;
import org.dbgl.util.FilesUtils;
import org.dbgl.util.SystemUtils;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;


public class EditDosboxVersionDialog extends SizeControlledTabbedDialog<DosboxVersion> {

	private final boolean isDefault_;
	private final DosboxVersion dbversion_;

	public EditDosboxVersionDialog(Shell parent, boolean isDefault, DosboxVersion dbversion) {
		super(parent, "dosboxdialog");
		isDefault_ = isDefault;
		dbversion_ = dbversion;
	}

	@Override
	protected String getDialogTitle() {
		return (dbversion_ == null || (dbversion_.getId() == -1)) ? text_.get("dialog.dosboxversion.title.add")
				: text_.get("dialog.dosboxversion.title.edit", new Object[] {dbversion_.getTitle(), dbversion_.getId()});
	}

	@Override
	protected void onShellCreated() {
		Composite composite = createTabWithComposite(text_.get("dialog.dosboxversion.tab.info"), 3);

		Text title = createLabelAndText(composite, text_.get("dialog.dosboxversion.title"), 2);
		title.setFocus();
		Text path = createLabelAndText(composite, text_.get("dialog.dosboxversion.path"));
		BrowseButton browsePathButton = new BrowseButton(composite);
		Text exe = createLabelAndText(composite, text_.get("dialog.dosboxversion.executable"), 1, StringUtils.EMPTY,
			text_.get("dialog.dosboxversion.executable.tooltip", new Object[] {FileLocationService.DOSBOX_EXE_STRING}));
		BrowseButton browseExeButton = new BrowseButton(composite);
		Text conf = createLabelAndText(composite, text_.get("dialog.profile.configfile"));
		BrowseButton browseConfButton = new BrowseButton(composite);

		browsePathButton.connect(shell_, path, conf, SystemUtils.IS_OSX ? BrowseType.FILE: BrowseType.DIR, CanonicalType.DOSBOX, false, null);
		browseExeButton.connect(shell_, exe, null, BrowseType.FILE, CanonicalType.DOSBOXEXE, false, null);
		browseConfButton.connect(shell_, conf, null, BrowseType.FILE, CanonicalType.DOSBOXCONF, false, null);

		Text parameters = createLabelAndText(composite, text_.get("dialog.dosboxversion.parameters"), 2);
		Combo version = createLabelAndCombo(composite, text_.get("dialog.dosboxversion.version"), false, 2, DosboxVersion.SUPP_RELEASES, 15);
		Button multiconf = createLabelAndCheckButton(composite, text_.get("dialog.dosboxversion.multiconfsupport"), 2);
		Button usingCurses = createLabelAndCheckButton(composite, text_.get("dialog.dosboxversion.altstartup"), 2, text_.get("dialog.dosboxversion.altstartupexplanation"));
		Button defaultButton = createLabelAndCheckButton(composite, text_.get("dialog.dosboxversion.default"), 2);

		createOkCancelButtons(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				if (!isValid(title, path, exe, conf, usingCurses)) {
					return;
				}
				try {
					if (dbversion_ == null || (dbversion_.getId() == -1)) {
						DosboxVersion dbv = DosboxVersionFactory.create(title.getText(), version.getText(), defaultButton.getSelection(), multiconf.getSelection(), usingCurses.getSelection(),
							path.getText(), exe.getText(), parameters.getText(), conf.getText());
						result_ = new DosboxVersionRepository().add(dbv);
					} else {
						dbversion_.setTitle(title.getText());
						dbversion_.setVersion(version.getText());
						dbversion_.setDefault(defaultButton.getSelection());
						dbversion_.setMultiConfig(multiconf.getSelection());
						dbversion_.setUsingCurses(usingCurses.getSelection());
						dbversion_.setPath(path.getText());
						dbversion_.setExe(exe.getText());
						dbversion_.setExecutableParameters(parameters.getText());
						dbversion_.setConfigurationFileLocation(conf.getText());
						new DosboxVersionRepository().update(dbversion_);
						result_ = dbversion_;
					}
				} catch (SQLException e) {
					GeneralPurposeDialogs.warningMessage(shell_, e);
				}
				shell_.close();
			}
		});

		// init values
		if (dbversion_ != null) {
			title.setText(dbversion_.getTitle());
			path.setText(dbversion_.getPath().getPath());
			exe.setText(dbversion_.getExe().getPath());
			conf.setText(dbversion_.getConfigurationFile().getPath());
			parameters.setText(dbversion_.getExecutableParameters());
			version.setText(dbversion_.getVersion());
			defaultButton.setSelection(dbversion_.isDefault());
			multiconf.setSelection(dbversion_.isMultiConfig());
			usingCurses.setSelection(dbversion_.isUsingCurses());
		} else {
			version.select(version.getItemCount() - 1);
			defaultButton.setSelection(isDefault_);
			multiconf.setSelection(true);
		}
	}

	private boolean isValid(Text title, Text path, Text exe, Text conf, Button usingCurses) {
		GeneralPurposeDialogs.initErrorDialog();
		if (StringUtils.isBlank(title.getText())) {
			GeneralPurposeDialogs.addError(text_.get("dialog.dosboxversion.required.title"), title);
		}
		if (StringUtils.isBlank(path.getText())) {
			GeneralPurposeDialogs.addError(text_.get("dialog.dosboxversion.required.path"), path);
		}
		if (StringUtils.isBlank(conf.getText())) {
			GeneralPurposeDialogs.addError(text_.get("dialog.dosboxversion.required.conf"), conf);
		}
		if (!GeneralPurposeDialogs.hasErrors()) {
			DosboxVersion dbversion = DosboxVersionFactory.create(StringUtils.EMPTY, StringUtils.EMPTY, false, false, false, path.getText(), exe.getText(), StringUtils.EMPTY, conf.getText());
			File executable = dbversion.getCanonicalExecutable();
			File configFile = dbversion.getConfigurationCanonicalFile();
			boolean exeAvailable = FilesUtils.isReadableFile(executable);
			if (!exeAvailable) {
				GeneralPurposeDialogs.addError(text_.get("dialog.dosboxversion.error.dosboxexemissing", new Object[] {executable}), path);
			}
			if (!FilesUtils.isReadableFile(configFile) && exeAvailable) {
				if (GeneralPurposeDialogs.confirmMessage(shell_, text_.get("dialog.dosboxversion.confirm.createmissingdosboxconf", new Object[] {configFile}))) {
					try {
						ExecuteUtils.doCreateDosboxConf(dbversion);
					} catch (IOException e) {
						GeneralPurposeDialogs.warningMessage(shell_, e);
					}
				}
			}
			if (!usingCurses.getSelection() && !FilesUtils.isReadableFile(configFile)) {
				GeneralPurposeDialogs.addError(text_.get("dialog.dosboxversion.error.dosboxconfmissing", new Object[] {configFile}), path);
			}
		}
		return !GeneralPurposeDialogs.displayErrorDialog(shell_);
	}
}
