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.FormVisual;
import ch.openech.mj.edit.validation.Indicator;
import ch.openech.mj.edit.validation.ValidationMessage;
import ch.openech.mj.page.PageContext;
import ch.openech.mj.resources.ResourceHelper;
import ch.openech.mj.resources.Resources;

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

	private WizardPage<?> currentPage;
	private int currentPageIndex = 0;
	
	protected final Action prevAction;
	protected final Action nextAction;
	private SwitchFormVisual<?> switchFormVisual;
	private final Indicator indicator;
	
	protected Wizard() {
		nextAction = createNextAction();
		prevAction = createPrevAction();
		indicator = new WizardIndicator();
	}

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

	protected int getCurrentPageIndex() {
		return currentPageIndex;
	}
	
	protected Action createNextAction() {
		Action action = new AbstractAction() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (currentPage.isSaveable()) {
					currentPage.save();
					currentPageIndex++;
					setCurrentPage(currentPage.getNextPage());
				}
			}
		};
		ResourceHelper.initProperties(action, Resources.getResourceBundle(), "NextWizardPageAction");
		return action;
	}

	protected Action createPrevAction() {
		Action action = new AbstractAction() {
			@Override
			public void actionPerformed(ActionEvent e) {
				currentPage.finish();
				currentPageIndex--;
				setCurrentPage(currentPage.getPreviousPage());
			}
		};
		ResourceHelper.initProperties(action, Resources.getResourceBundle(), "PreviousWizardPageAction");
		return action;
	}

	@Override
	protected final FormVisual createForm() {
		switchFormVisual = new SwitchFormVisual<Object>();
		return switchFormVisual;
	}
	
	@Override
	public FormVisual<T> startEditor(PageContext context) {
		FormVisual<T> formVisual = super.startEditor(context);
		setCurrentPage(getFirstPage());
		return formVisual;
	}

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

	private void setCurrentPage(WizardPage<?> page) {
		currentPage = page;
		currentPage.setIndicator(indicator);
		switchFormVisual.setFormVisual(currentPage.startEditor(context));
		prevAction.setEnabled(currentPageIndex > 0);
	}

	@Override
	protected abstract T load();

	@Override
	protected void validate(T object, List resultList) {
		// not used
	}

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

		@Override
		public void setValidationMessages(List<ValidationMessage> validationResult) {
			Wizard.this.indicate(validationResult);
			nextAction.setEnabled(isSaveable());
			saveAction.setEnabled(isSaveable() && currentPage.canFinish());
		}
	}

	/* (non-Javadoc)
	 * @see ch.openech.mj.edit.Editor#fillWithDemoData()
	 */
	@Override
	public void fillWithDemoData() {
		currentPage.fillWithDemoData();
	}
	 
}

@@ -666,17 +666,17 @@
 mVisual%3C
-?
+T
 %3E switch
@@ -1985,16 +1985,19 @@
 rmVisual
+%3CT%3E
  createF
@@ -2051,14 +2051,9 @@
 ual%3C
-Object
+T
 %3E();
@@ -2701,16 +2701,35 @@
 ct, List
+%3CValidationMessage%3E
  resultL

remove two generic warnings