package ch.openech.mj.edit;

import java.awt.event.ActionEvent;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;

import ch.openech.mj.edit.form.IForm;
import ch.openech.mj.edit.form.SwitchForm;
import ch.openech.mj.edit.validation.Indicator;
import ch.openech.mj.edit.validation.ValidationMessage;
import ch.openech.mj.resources.ResourceHelper;
import ch.openech.mj.resources.Resources;

public abstract class Wizard<T> extends Editor<T> {

	private WizardStep<?> currentStep;
	private int currentStepIndex = 0;
	
	protected final Action prevAction;
	protected final Action nextAction;
	private SwitchForm<T> switchForm;
	private final Indicator indicator;
	
	protected Wizard() {
		nextAction = createNextAction();
		prevAction = createPrevAction();
		indicator = new WizardIndicator();
	}

	protected abstract WizardStep<?> getFirstStep();
	
	@Override
	public Action[] getActions() {
		return new Action[]{demoAction(), cancelAction(), prevAction, nextAction, saveAction()};
	}

	protected int getCurrentStepIndex() {
		return currentStepIndex;
	}
	
	protected Action createNextAction() {
		Action action = new AbstractAction() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (currentStep.isSaveable()) {
					currentStep.save();
					currentStepIndex++;
					setCurrentStep(currentStep.getNextStep());
				}
			}
		};
		ResourceHelper.initProperties(action, Resources.getResourceBundle(), "NextWizardStepAction");
		return action;
	}

	protected Action createPrevAction() {
		Action action = new AbstractAction() {
			@Override
			public void actionPerformed(ActionEvent e) {
				currentStep.finish();
				currentStepIndex--;
				setCurrentStep(currentStep.getPreviousStep());
			}
		};
		ResourceHelper.initProperties(action, Resources.getResourceBundle(), "PreviousWizardStepAction");
		return action;
	}

	@Override
	protected final IForm<T> createForm() {
		switchForm = new SwitchForm<T>();
		return switchForm;
	}
	
	@Override
	public IForm<T> startEditor() {
		IForm<T> formVisual = super.startEditor();
		setCurrentStep(getFirstStep());
		return formVisual;
	}

	@Override
	public void finish() {
		currentStep.finish();
		super.finish();
	}

	private void setCurrentStep(WizardStep<?> step) {
		currentStep = step;
		currentStep.setIndicator(indicator);
		switchForm.setForm(currentStep.startEditor());
		prevAction.setEnabled(currentStepIndex > 0);
	}

	@Override
	protected abstract T load();

	@Override
	protected abstract boolean save(T object) throws Exception;
	
	private class WizardIndicator implements Indicator {

		@Override
		public void setValidationMessages(List<ValidationMessage> validationResult) {
			nextAction.setEnabled(validationResult.isEmpty());
			saveAction().setEnabled(validationResult.isEmpty() && currentStep.canFinish());
		}
	}

	@Override
	public void fillWithDemoData() {
		currentStep.fillWithDemoData();
	}
	 
}

@@ -639,16 +639,55 @@
 ction;%0D%0A
+%09protected final Action finishAction;%0D%0A
 %09private
@@ -714,16 +714,16 @@
 hForm;%0D%0A
-
 %09private
@@ -849,16 +849,56 @@
 ion();%0D%0A
+%09%09finishAction = createFinishAction();%0D%0A
 %09%09indica
@@ -1108,28 +1108,28 @@
 Action, 
-save
+finish
 Action
-()
 %7D;%0D%0A%09%7D%0D%0A
@@ -2006,32 +2006,266 @@
  action;%0D%0A%09%7D%0D%0A%0D%0A
+%09protected final Action createFinishAction() %7B%0D%0A%09%09Action action = new SaveAction(%22OkAction%22) %7B%0D%0A%09%09%09@Override%0D%0A%09%09%09public void actionPerformed(ActionEvent e) %7B%0D%0A%09%09%09%09currentStep.save();%0D%0A%09%09%09%09save();%0D%0A%09%09%09%7D%0D%0A%09%09%7D;%0D%0A%09%09return action;%0D%0A%09%7D%0D%0A%09%0D%0A
 %09@Override%0D%0A%09pro
@@ -2833,53 +2833,8 @@
 %0D%0A%0D%0A
-%09@Override%0D%0A%09protected abstract T load();%0D%0A%0D%0A
 %09@Ov
@@ -3119,20 +3119,20 @@
 %0A%09%09%09
-save
+finish
 Action
-()
 .set

Save last step when finishing Wizard