package org.etsi.mts.tdl.openapi2tdl.next;

import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IWorkbenchPropertyPage;
import org.eclipse.ui.preferences.ScopedPreferenceStore;

public class PropertyPage extends FieldEditorPreferencePage implements IWorkbenchPropertyPage {
	
	public static final String PROCEDURE_BASED = "ProcedureBased",
			GENERATE_JAVA_MAPPING = "GenerateJavaMapping",
			JAVA_GENERATOR = "JavaMappingGenerator",
			JAVA_API_PACKAGE = "JavaApiPackage";

	public static final String PREFERENCE_SCOPE = "org.etsi.mts.tdl.openapi2tdl";

	private static final List<String> REQUIRED_SETTINGS = Arrays.asList(new String[] { /* TODO */ });

	protected IAdaptable element;

	protected Map<FieldEditor, String> fields = new Hashtable<FieldEditor, String>();

	private StringFieldEditor javaApiPackage;

	public PropertyPage() {
		super(GRID);
	}

	@Override
	public IAdaptable getElement() {
		return element;
	}

	@Override
	public void setElement(IAdaptable element) {
		this.element = element;
	}

	@Override
	protected IPreferenceStore doGetPreferenceStore() {
		ProjectScope ps = new ProjectScope((IProject) this.element);
		ScopedPreferenceStore scopedStore = new ScopedPreferenceStore(ps, PREFERENCE_SCOPE);
		scopedStore.setDefault(JAVA_GENERATOR, "java");
		return scopedStore;
	}

	@Override
	protected void initialize() {
		for (FieldEditor e : fields.keySet()) {
			String value = getPreferenceStore().getString(e.getPreferenceName());
			fields.put(e, value);
			initialize(e.getPreferenceName(), value, e);
		}
		super.initialize();
	}

	protected void initialize(String name, String value, FieldEditor e) {
		if (name.equals(GENERATE_JAVA_MAPPING)) {
			javaApiPackage.setEnabled(
					Boolean.valueOf(value),
					getFieldEditorParent());
		}
	}

	@Override
	protected void addField(FieldEditor editor) {
		super.addField(editor);
		fields.put(editor, "");
	}

	@Override
	public void propertyChange(PropertyChangeEvent event) {
		super.propertyChange(event);
		if (event.getProperty().equals(FieldEditor.VALUE)) {
			FieldEditor e = (FieldEditor) event.getSource();

			String name = e.getPreferenceName();
			Object valueObj = event.getNewValue();
			String value = valueObj.toString();

			fields.put(e, value);

			initialize(name, value, e);

			checkState();
		}
	}

	@Override
	protected void checkState() {
		setErrorMessage(null);
		super.checkState();
	}

	@Override
	protected void createFieldEditors() {

		Composite parent = getFieldEditorParent();
		BooleanFieldEditor procBased = new BooleanFieldEditor(PROCEDURE_BASED, "Procedure-based API", parent);
		addField(procBased);
		
		parent = getFieldEditorParent();
		BooleanFieldEditor genJavaMappings = new BooleanFieldEditor(GENERATE_JAVA_MAPPING, "Generate type mappings for Java", parent);
		addField(genJavaMappings);

		parent = getFieldEditorParent();
		StringFieldEditor javaGenerator = new StringFieldEditor(JAVA_GENERATOR, "Code generator for mappings", parent);
		javaGenerator.setEnabled(false, parent);
		addField(javaGenerator);

		parent = getFieldEditorParent();
		javaApiPackage = new StringFieldEditor(JAVA_API_PACKAGE, "Java API package", parent);
		addField(javaApiPackage);
		
		// TODO
	}

	private boolean isValid(FieldEditor e) {
		String name = e.getPreferenceName();
		String value = fields.get(e);

		if (REQUIRED_SETTINGS.contains(name)) {
			if (value.isEmpty()) {
				setErrorMessage(String.format("%s must be selected!", e.getLabelText()));
				return false;
			}
		}

		return true;
	}

}