/*
 *  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.wizard;

import java.io.File;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.dbgl.gui.GeneralPurposeDialogs;
import org.dbgl.gui.abstractdialog.JobWizardDialog;
import org.dbgl.gui.controls.BrowseButton;
import org.dbgl.gui.controls.BrowseButton.BrowseType;
import org.dbgl.gui.controls.BrowseButton.CanonicalType;
import org.dbgl.gui.thread.ExportThread;
import org.dbgl.model.GamePack;
import org.dbgl.model.ICanonicalize;
import org.dbgl.model.aggregate.Profile;
import org.dbgl.model.entity.GamePackEntry;
import org.dbgl.service.FileLocationService;
import org.dbgl.util.FilesUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;


public class ExportDialog extends JobWizardDialog<Object> {

	private GamePack gamePack_;
	private Button settingsOnly_, exportGameData_, exportCapturesButton_, exportMapperfilesButton_, exportNativeCommandsButton_;
	private Text title_, notes_, author_, filename_;
	private Table profilesTable_;
	private ICanonicalize canonicalizer_;

	public ExportDialog(Shell parent, List<Profile> profiles) {
		super(parent, "export");

		gamePack_ = new GamePack();
		for (int i = 0; i < profiles.size(); i++) {
			Profile prof = profiles.get(i);
			gamePack_.getEntries().add(new GamePackEntry(i, prof));
		}
	}

	@Override
	protected String getDialogTitle() {
		return text_.get("dialog.export.title", new Object[] {gamePack_.getEntries().size()});
	}

	@Override
	protected int stepSize(int step, boolean forward) {
		if (((step == 0 && forward) || (step == 2 && !forward)) && settingsOnly_.getSelection())
			return 2;
		return super.stepSize(step, forward);
	}

	@Override
	protected boolean onNext(int step) {
		if (step == 1) {
			return isValidGameDirs();
		} else if (step == 2) {
			return isValidTargetZip();
		} else if (step == 3) {
			try {
				gamePack_.setTitle(title_.getText());
				gamePack_.setAuthor(author_.getText());
				gamePack_.setNotes(notes_.getText());
				gamePack_.setCapturesAvailable(exportCapturesButton_.getSelection());
				gamePack_.setMapperfilesAvailable(exportMapperfilesButton_.getSelection());
				gamePack_.setNativecommandsAvailable(exportNativeCommandsButton_.getSelection());
				gamePack_.setGamedataAvailable(exportGameData_.getSelection());
				job_ = new ExportThread(log_, progressBar_, status_, gamePack_, canonicalizer_.canonicalize(new File(filename_.getText())));
			} catch (Exception ex) {
				GeneralPurposeDialogs.warningMessage(shell_, ex);
				job_ = null;
				return false;
			}
		} else if (step == 4) {
			if (job_.isEverythingOk()) {
				GeneralPurposeDialogs.infoMessage(shell_, text_.get("dialog.export.notice.exportok"));
			} else {
				GeneralPurposeDialogs.warningMessage(shell_, text_.get("dialog.export.error.problem"));
			}
			status_.setText(text_.get("dialog.export.reviewlog"));
			status_.pack();
		}
		return true;
	}

	private boolean isValidTargetZip() {
		GeneralPurposeDialogs.initErrorDialog();
		if (StringUtils.isBlank(title_.getText())) {
			GeneralPurposeDialogs.addError(text_.get("dialog.export.required.title"), title_);
		}
		String gpaFilename = filename_.getText();
		if (StringUtils.isBlank(gpaFilename)) {
			GeneralPurposeDialogs.addError(text_.get("dialog.export.required.filename"), filename_);
		} else {
			File target = canonicalizer_.canonicalize(new File(gpaFilename));
			if (FilesUtils.isExistingFile(target))
				GeneralPurposeDialogs.addError(text_.get("dialog.export.error.fileexists", new Object[] {target}), filename_);
			else if (!FilesUtils.isExistingDirectory(target.getParentFile()))
				GeneralPurposeDialogs.addError(text_.get("dialog.export.error.exportdirmissing", new Object[] {target}), filename_);
		}
		return !GeneralPurposeDialogs.displayErrorDialog(shell_);
	}

	private boolean isValidGameDirs() {
		GeneralPurposeDialogs.initErrorDialog();
		for (GamePackEntry entry: gamePack_.getEntries()) {
			if (!FilesUtils.isExistingDirectory(entry.getCanonicalGameDir())) {
				GeneralPurposeDialogs.addError(text_.get("dialog.export.error.gamedirmissing", new Object[] {entry.getCanonicalGameDir()}), profilesTable_);
			}
			if (entry.getGameDir().isAbsolute()) {
				GeneralPurposeDialogs.addError(text_.get("dialog.export.error.gamedirnotrelative", new Object[] {entry.getGameDir()}), profilesTable_);
			}
			for (GamePackEntry entry2: gamePack_.getEntries()) {
				if (entry != entry2 && FilesUtils.areRelated(entry.getCanonicalGameDir(), entry2.getCanonicalGameDir())) {
					GeneralPurposeDialogs.addError(text_.get("dialog.export.error.gamedirsconflict",
						new Object[] {entry.getCanonicalGameDir(), entry.getProfile().getTitle(), entry2.getCanonicalGameDir(), entry2.getProfile().getTitle()}), profilesTable_);
				}
			}
		}
		return !GeneralPurposeDialogs.displayErrorDialog(shell_);
	}

	@Override
	protected void onShellCreated() {
		Group group1 = createGroup(shell_, text_.get("dialog.export.step1"), 2);

		settingsOnly_ = createLabelAndRadioButton(group1, text_.get("dialog.export.export"), text_.get("dialog.export.export.profiles"), true);

		createLabel(group1, 1, 5);
		exportGameData_ = createRadioButton(group1, text_.get("dialog.export.export.games"));
		createLabel(group1);
		exportCapturesButton_ = createCheckButton(group1, 1, text_.get("dialog.template.captures"), true);
		exportMapperfilesButton_ = createCheckButton(group1, 1, text_.get("dialog.template.mapperfile"), false);
		exportNativeCommandsButton_ = createCheckButton(group1, 1, text_.get("dialog.export.nativecommands"), false);
		addStep(group1);

		Group reviewDirsGroup = createGroup(shell_, text_.get("dialog.export.step2"), new FillLayout());
		profilesTable_ = new Table(reviewDirsGroup, SWT.FULL_SELECTION | SWT.BORDER);
		profilesTable_.setHeaderVisible(true);
		profilesTable_.setLinesVisible(true);
		TableColumn titleColumn = new TableColumn(profilesTable_, SWT.NONE);
		titleColumn.setWidth(260);
		titleColumn.setText(text_.get("dialog.main.profiles.column.title"));
		TableColumn subdirColumn = new TableColumn(profilesTable_, SWT.NONE);
		subdirColumn.setWidth(120);
		subdirColumn.setText(text_.get("dialog.export.column.gamedir"));
		for (GamePackEntry entry: gamePack_.getEntries()) {
			TableItem item = new TableItem(profilesTable_, SWT.NONE);
			item.setText(entry.getProfile().getTitle());
			item.setText(1, entry.getGameDir().getPath());
		}
		profilesTable_.addMouseListener(new MouseAdapter() {
			public void mouseDoubleClick(MouseEvent event) {
				int idx = profilesTable_.getSelectionIndex();
				GamePackEntry entry = gamePack_.getEntries().get(idx);
				DirectoryDialog dialog = new DirectoryDialog(shell_);
				dialog.setFilterPath(entry.getCanonicalGameDir().getPath());
				String result = dialog.open();
				if (result != null) {
					entry.setGameDir(result);
					profilesTable_.getSelection()[0].setText(1, entry.getGameDir().getPath());
				}
			}
		});
		addStep(reviewDirsGroup);

		Group settingsGroup = createGroup(shell_, text_.get("dialog.export.step3"), 3);
		title_ = createLabelAndText(settingsGroup, text_.get("dialog.export.exporttitle"), 2);
		author_ = createLabelAndText(settingsGroup, text_.get("dialog.export.author"), 2);
		notes_ = createLabelAndTextarea(settingsGroup, text_.get("dialog.export.notes"), false, true, 2, 1);
		StringBuffer sb = new StringBuffer();
		for (GamePackEntry entry: gamePack_.getEntries()) {
			sb.append(entry.getProfile().getTitle()).append(notes_.getLineDelimiter());
		}
		notes_.setText(sb.toString());
		filename_ = createLabelAndText(settingsGroup, text_.get("dialog.export.file"), FileLocationService.getInstance().getDefaultGpaExportFile().getPath());
		canonicalizer_ = new BrowseButton(settingsGroup).connect(shell_, filename_, null, BrowseType.FILE, CanonicalType.DBGLZIP, true, null);
		addStep(settingsGroup);

		addFinalStep(text_.get("dialog.export.step4"), text_.get("dialog.export.start"));
	}
}