package phasereditor.canvas.ui.handlers;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.handlers.HandlerUtil;

import phasereditor.assetpack.core.IAssetKey;
import phasereditor.canvas.core.AssetSpriteModel;
import phasereditor.canvas.core.BaseObjectModel;
import phasereditor.canvas.ui.editors.CanvasEditor;
import phasereditor.canvas.ui.editors.operations.AddNodeOperation;
import phasereditor.canvas.ui.editors.operations.CompositeOperation;
import phasereditor.canvas.ui.editors.operations.DeleteNodeOperation;
import phasereditor.canvas.ui.editors.operations.SelectOperation;
import phasereditor.canvas.ui.shapes.BaseObjectControl;
import phasereditor.canvas.ui.shapes.GroupNode;
import phasereditor.canvas.ui.shapes.IObjectNode;
import phasereditor.canvas.ui.shapes.ISpriteNode;

/**
 * 
 * @author arian
 *
 */
public abstract class AbstractMorphHandler extends AbstractHandler {

	@Override
	public final Object execute(ExecutionEvent event) throws ExecutionException {
		Object[] sel = ((IStructuredSelection) HandlerUtil.getCurrentSelection(event)).toArray();

		CompositeOperation operations = new CompositeOperation();

		{
			List<String> beforeSelection = new ArrayList<>();

			for (Object elem : sel) {
				beforeSelection.add(((IObjectNode) elem).getModel().getId());
			}
			operations.add(new SelectOperation(beforeSelection));
		}

		{
			List<String> afterSelection = new ArrayList<>();

			for (Object elem : sel) {
				BaseObjectControl<?> control = ((IObjectNode) elem).getControl();
				BaseObjectModel model = control.getModel();
				IAssetKey source = null;

				boolean doMorph = true;

				if (model instanceof AssetSpriteModel<?>) {
					source = ((AssetSpriteModel<?>) model).getAssetKey();
					doMorph = source != null;
				}

				if (doMorph) {
					String id = addMorph(operations, (ISpriteNode) elem, source);
					afterSelection.add(id);
				}
			}

			operations.add(new SelectOperation(afterSelection));
		}

		CanvasEditor editor = (CanvasEditor) HandlerUtil.getActiveEditor(event);
		editor.getCanvas().getUpdateBehavior().executeOperations(operations);

		return null;
	}

	protected final String addMorph(CompositeOperation operations, ISpriteNode srcNode, Object source) {
		// delete source
		operations.add(new DeleteNodeOperation(srcNode.getModel().getId()));

		// create morph
		GroupNode parent = srcNode.getGroup();
		BaseObjectModel dstModel = createMorphModel(srcNode, source, parent);

		@SuppressWarnings("unlikely-arg-type")
		int i = parent.getNode().getChildren().indexOf(srcNode);
		operations.add(new AddNodeOperation(dstModel.toJSON(false), i, dstModel.getX(), dstModel.getY(),
				parent.getModel().getId()));
		return dstModel.getId();
	}

	protected abstract BaseObjectModel createMorphModel(ISpriteNode srcNode, Object source, GroupNode parent);

}

@@ -290,24 +290,64 @@
 dSelection;%0A
+import org.eclipse.jface.window.Window;%0A
 import org.e
@@ -520,24 +520,122 @@
 bjectModel;%0A
+import phasereditor.canvas.core.TextModel;%0Aimport phasereditor.canvas.ui.editors.AddSpriteDialog;%0A
 import phase
@@ -2119,24 +2119,449 @@
  null;%0A%09%09%09%09%7D
+ else if (model instanceof TextModel) %7B%0A%09%09%09%09%09AddSpriteDialog dlg = new AddSpriteDialog(HandlerUtil.getActiveShell(event), %22Select Texture%22);%0A%09%09%09%09%09CanvasEditor editor = (CanvasEditor) HandlerUtil.getActiveEditor(event);%0A%09%09%09%09%09dlg.setProject(editor.getEditorInputFile().getProject());%0A%09%09%09%09%09if (dlg.open() == Window.OK) %7B%0A%09%09%09%09%09%09source = (IAssetKey) dlg.getSelection().getFirstElement();%0A%09%09%09%09%09%7D else %7B%0A%09%09%09%09%09%09continue;%0A%09%09%09%09%09%7D%0A%09%09%09%09%7D
 %0A%0A%09%09%09%09if (do

support morph text to any.