/*
 *  Copyright (C) 2006-2020  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.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.dbgl.gui.abstractdialog.JobWizardDialog;
import org.dbgl.gui.controls.DaControl;
import org.dbgl.gui.controls.Group_;
import org.dbgl.gui.controls.Mess_;
import org.dbgl.gui.controls.MetaControl;
import org.dbgl.gui.controls.Text_;
import org.dbgl.gui.thread.SearchEngineThread;
import org.dbgl.model.aggregate.Profile;
import org.dbgl.model.repository.ProfileRepository;
import org.dbgl.util.SystemUtils;
import org.dbgl.util.searchengine.WebSearchEngine;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;


public class UpdateMultiProfileDialog extends JobWizardDialog<Boolean> {

	private final List<Profile> orgProfs_, profs_;
	private final boolean dbversionChanged_, templateReloaded_;
	private final List<DaControl> daControls_;
	private final List<MetaControl> autoexecControls_;
	private final List<MetaControl> metaControls_;
	private final WebSearchEngine engine_;

	public UpdateMultiProfileDialog(Shell parent, List<Profile> orgProfs, List<Profile> profs, boolean dbversionChanged, boolean templateReloaded, List<DaControl> daControls,
			List<MetaControl> autoexecControls, List<MetaControl> metaControls, WebSearchEngine engine) {
		super(parent, "multiprofiledialog");
		orgProfs_ = orgProfs;
		profs_ = profs;
		dbversionChanged_ = dbversionChanged;
		templateReloaded_ = templateReloaded;
		daControls_ = daControls.stream().filter(x -> x.hasChangedValue()).collect(Collectors.toList());
		autoexecControls_ = autoexecControls.stream().filter(x -> x.hasChangedValue()).collect(Collectors.toList());
		metaControls_ = metaControls.stream().filter(x -> x.hasChangedValue()).collect(Collectors.toList());
		engine_ = engine;
	}

	@Override
	protected String getDialogTitle() {
		return text_.get("dialog.multiprofile.title.edit", new Object[] {profs_.size()});
	}

	@Override
	protected void onShellCreated() {
		StringBuffer info = new StringBuffer();
		if (dbversionChanged_) {
			long count = IntStream.range(0, profs_.size()).filter(x -> profs_.get(x).getDosboxVersion().getId() != orgProfs_.get(x).getDosboxVersion().getId()).count();
			info.append(text_.get("dialog.multiprofile.dosboxversionchanged", new Object[] {profs_.get(0).getDosboxVersion().getTitle(), count})).append(SystemUtils.EOLN);
		}
		if (templateReloaded_) {
			info.append(text_.get("dialog.multiprofile.templateloaded")).append(SystemUtils.EOLN);
		}
		String conflicting = text_.get("dialog.multiprofile.conflictingvalues");
		metaControls_.forEach(x -> info.append(x.getLabelText()).append(": ").append(x.getOriginalValue() == null ? conflicting: '"' + x.getOriginalValue() + '"').append(" -> ").append(
			'"' + x.getCurrentValue() + '"').append(SystemUtils.EOLN));
		daControls_.forEach(
			x -> info.append(x.getLabelText()).append(" (").append(x.getConfLabel()).append("): ").append(x.getOriginalValue() == null ? conflicting: '"' + x.getOriginalValue() + '"').append(
				" -> ").append('"' + x.getCurrentValue() + '"').append(SystemUtils.EOLN));
		autoexecControls_.forEach(x -> info.append(x.getLabelText()).append(": ").append(x.getOriginalValue() == null ? conflicting: '"' + x.getOriginalValue() + '"').append(" -> ").append(
			'"' + x.getCurrentValue() + '"').append(SystemUtils.EOLN));

		Group infoGroup = Group_.on(shell_).layout(new GridLayout()).key("dialog.multiprofile.reviewchanges").build();
		Text_.on(infoGroup).multi().readOnly().val(info.toString()).build();
		addStep(infoGroup);

		addFinalStep("dialog.dfendimport.progress", "dialog.multiprofile.applychanges");
		progressBar_.setMaximum(profs_.size());
	}

	@Override
	protected boolean onNext(int step) {
		if (step == 1) {
			for (Profile prof: profs_) {
				metaControls_.forEach(x -> x.updateProfileByControl(prof));
				daControls_.forEach(x -> x.updateConfigurationByControl(prof));
				autoexecControls_.forEach(x -> x.updateAutoexecByControl(prof.getConfiguration().getAutoexec()));

				try {
					new ProfileRepository().update(prof);
				} catch (SQLException e) {
					log_.append(e.toString());
					e.printStackTrace();
				}

				progressBar_.setSelection(progressBar_.getSelection() + 1);
			}

			progressBar_.setSelection(0);
			job_ = new SearchEngineThread(profs_, engine_, log_, progressBar_, status_);
		} else if (step == 2) {
			if (!job_.isEverythingOk())
				Mess_.on(shell_).key("dialog.multiprofile.error.problem").warning();

			status_.setText(text_.get("dialog.multiprofile.reviewlog"));
			status_.pack();

			result_ = true;
		}
		return true;
	}
}
