/*
 * (c) Copyright Sysdeo SA 2001, 2002.
 * All Rights Reserved.
 */

package com.sysdeo.eclipse.tomcat;

import static com.sysdeo.eclipse.tomcat.TomcatPluginResources.PLUGIN_ID;
import static com.sysdeo.eclipse.tomcat.TomcatPluginResources.PREF_PAGE_BOOTCLASSPATH_LABEL;
import static com.sysdeo.eclipse.tomcat.TomcatPluginResources.PREF_PAGE_CLASSPATH_LABEL;
import static com.sysdeo.eclipse.tomcat.TomcatPluginResources.PREF_PAGE_CREATE_LAUNCH_LABEL;
import static com.sysdeo.eclipse.tomcat.TomcatPluginResources.PREF_PAGE_DEBUGMODE_LABEL;
import static com.sysdeo.eclipse.tomcat.TomcatPluginResources.PREF_PAGE_DUMP_CONFIG_LABEL;
import static com.sysdeo.eclipse.tomcat.TomcatPluginResources.PREF_PAGE_JRE_LABEL;
import static com.sysdeo.eclipse.tomcat.TomcatPluginResources.PREF_PAGE_PARAMETERS_LABEL;
import static com.sysdeo.eclipse.tomcat.TomcatPluginResources.TOMCAT_PREF_DEBUGMODE_KEY;
import static com.sysdeo.eclipse.tomcat.TomcatPluginResources.TOMCAT_PREF_JRE_KEY;
import static com.sysdeo.eclipse.tomcat.TomcatPluginResources.TOMCAT_PREF_JVM_BOOTCLASSPATH_KEY;
import static com.sysdeo.eclipse.tomcat.TomcatPluginResources.TOMCAT_PREF_JVM_CLASSPATH_KEY;
import static com.sysdeo.eclipse.tomcat.TomcatPluginResources.TOMCAT_PREF_JVM_PARAMETERS_KEY;

import java.util.ArrayList;
import java.util.Arrays;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstallType;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.ComboFieldEditor;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.osgi.service.prefs.BackingStoreException;

import com.sysdeo.eclipse.tomcat.editors.ClasspathFieldEditor;
import com.sysdeo.eclipse.tomcat.editors.ListFieldEditor;

/**
 * TomcatJVMPreferencePage
 *
 */
public class TomcatJVMPreferencePage extends PreferencePage implements IWorkbenchPreferencePage, SelectionListener {

	/** ComboFieldEditor */
	private ComboFieldEditor jvmChoice;
	/** ListFieldEditor */
	private ListFieldEditor jvmParamaters;
	/** ClasspathFieldEditor */
	private ClasspathFieldEditor jvmClasspath;
	/** ClasspathFieldEditor */
	private ClasspathFieldEditor jvmBootClasspath;
	/** BooleanFieldEditor */
	private BooleanFieldEditor debugModeEditor;
	/** Button */
	private Button btAddLaunch;
	/** Button */
	private Button btLog;

	/**
	 * Constructor
	 */
	public TomcatJVMPreferencePage() {
		super();
		setPreferenceStore(TomcatLauncherPlugin.getDefault().getPreferenceStore());
	}

	/**
	 * @see PreferencePage#createContents(Composite)
	 */
	@Override
	protected Control createContents(final Composite parent) {
		final ScrolledComposite scrolledComposite = new ScrolledComposite(parent, SWT.V_SCROLL);
		Composite composite = new Composite(scrolledComposite, SWT.NULL);
		scrolledComposite.setContent(composite);
		composite.setLayout(new GridLayout(2, false));

		String[][] namesAndValues = collectAllJres();
		this.jvmChoice = new ComboFieldEditor(
				TOMCAT_PREF_JRE_KEY, PREF_PAGE_JRE_LABEL, namesAndValues, composite);

		this.debugModeEditor = new BooleanFieldEditor(
				TOMCAT_PREF_DEBUGMODE_KEY, PREF_PAGE_DEBUGMODE_LABEL, composite);
		initField(this.debugModeEditor);

		Label lbl = new Label(composite, SWT.NULL);
		lbl.setParent(composite);

		Composite group = new Composite(composite, SWT.NULL);
		GridData gd = new GridData(GridData.FILL_BOTH);
		gd.horizontalSpan = 2;
		group.setLayoutData(gd);
		group.setLayout(new GridLayout(2, false));

		this.btAddLaunch = new Button(group, SWT.PUSH);
		this.btAddLaunch.setText(PREF_PAGE_CREATE_LAUNCH_LABEL);
		this.btAddLaunch.addSelectionListener(this);

		this.btLog = new Button(group, SWT.PUSH);
		this.btLog.setText(PREF_PAGE_DUMP_CONFIG_LABEL);
		this.btLog.addSelectionListener(this);

		this.jvmParamaters = new ListFieldEditor(
				TOMCAT_PREF_JVM_PARAMETERS_KEY, PREF_PAGE_PARAMETERS_LABEL, composite);
		this.jvmClasspath = new ClasspathFieldEditor(
				TOMCAT_PREF_JVM_CLASSPATH_KEY, PREF_PAGE_CLASSPATH_LABEL, composite);
		this.jvmBootClasspath = new ClasspathFieldEditor(
				TOMCAT_PREF_JVM_BOOTCLASSPATH_KEY, PREF_PAGE_BOOTCLASSPATH_LABEL, composite);

		initField(this.jvmChoice);
		initField(this.jvmParamaters);
		initField(this.jvmClasspath);
		initField(this.jvmBootClasspath);

		composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
		return scrolledComposite;
	}

	/**
	 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
	 */
	@Override
	public void widgetSelected(final SelectionEvent e) {

		try {
			if (e.widget == this.btAddLaunch) {
				TomcatLauncherPlugin.getTomcatBootstrap().addLaunch();

			} else if (e.widget == this.btLog) {
				TomcatLauncherPlugin.getTomcatBootstrap().logConfig();

			}
		} catch (final CoreException ex) {
			TomcatLauncherPlugin.log("Failed to create launch configuration/n");
			TomcatLauncherPlugin.log(ex);
		}
	}

	/**
	 * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
	 */
	@Override
	public void widgetDefaultSelected(final SelectionEvent e) {
		return;
	}

	/**
	 * Collect all JREs
	 * @return Jres
	 */
	private String[][] collectAllJres() {
		ArrayList<IVMInstall> allVMs = new ArrayList<>();
		IVMInstallType[] vmTypes = JavaRuntime.getVMInstallTypes();
		for (final IVMInstallType vm : vmTypes) {
			allVMs.addAll(Arrays.asList(vm.getVMInstalls()));
		}

		String[][] namesAndValues = new String[allVMs.size()][2];
		for (int i = 0; i < allVMs.size(); i++) {
			namesAndValues[i][0] = allVMs.get(i).getName();
			namesAndValues[i][1] = allVMs.get(i).getId();
		}
		return namesAndValues;
	}

	/**
	 * @see IWorkbenchPreferencePage#init(IWorkbench)
	 */
	@Override
	public void init(final IWorkbench workbench) {
		return;
	}

	/**
	 * @see org.eclipse.jface.preference.PreferencePage#performOk()
	 */
	@Override
	public boolean performOk() {
		this.jvmChoice.store();
		this.jvmBootClasspath.store();
		this.jvmClasspath.store();
		this.jvmParamaters.store();
		this.debugModeEditor.store();

		try {
			InstanceScope.INSTANCE.getNode(PLUGIN_ID).flush();
		} catch (final BackingStoreException e) {
			TomcatLauncherPlugin.log(e);
			return false;
		}
		// TomcatLauncherPlugin.getDefault().savePluginPreferences();
		return true;
	}

	/**
	 * initField
	 * @param field FieldEditor
	 */
	private void initField(final FieldEditor field) {
		field.setPreferenceStore(getPreferenceStore());
		field.setPage(this);
		field.load();
	}
}
