/*******************************************************************************
 * Copyright (c) 2003, 2010 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.gef.examples.flow.ui;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.EventObject;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.gef.ContextMenuProvider;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.KeyHandler;
import org.eclipse.gef.KeyStroke;
import org.eclipse.gef.dnd.TemplateTransferDragSourceListener;
import org.eclipse.gef.dnd.TemplateTransferDropTargetListener;
import org.eclipse.gef.editparts.ScalableRootEditPart;
import org.eclipse.gef.examples.flow.FlowEditorPaletteFactory;
import org.eclipse.gef.examples.flow.actions.FlowContextMenuProvider;
import org.eclipse.gef.examples.flow.model.ActivityDiagram;
import org.eclipse.gef.examples.flow.parts.ActivityPartFactory;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.gef.ui.actions.DirectEditAction;
import org.eclipse.gef.ui.actions.GEFActionConstants;
import org.eclipse.gef.ui.parts.GraphicalEditorWithPalette;
import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler;
import org.eclipse.jface.action.IAction;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.actions.ActionFactory;

/**
 * 
 * @author hudsonr Created on Jun 27, 2003
 */
public class FlowEditor extends GraphicalEditorWithPalette {

	ActivityDiagram diagram;
	private PaletteRoot root;
	private KeyHandler sharedKeyHandler;

	public FlowEditor() {
		DefaultEditDomain defaultEditDomain = new DefaultEditDomain(this);
		setEditDomain(defaultEditDomain);
	}

	/**
	 * @see org.eclipse.gef.commands.CommandStackListener#commandStackChanged(java.util.EventObject)
	 */
	public void commandStackChanged(EventObject event) {
		firePropertyChange(IEditorPart.PROP_DIRTY);
		super.commandStackChanged(event);
	}

	/**
	 * @see org.eclipse.gef.ui.parts.GraphicalEditor#createActions()
	 */
	protected void createActions() {
		super.createActions();
		ActionRegistry registry = getActionRegistry();
		IAction action;

		action = new DirectEditAction((IWorkbenchPart) this);
		registry.registerAction(action);
		getSelectionActions().add(action.getId());
	}

	/**
	 * Creates an appropriate output stream and writes the activity diagram out
	 * to this stream.
	 * 
	 * @param os
	 *            the base output stream
	 * @throws IOException
	 */
	protected void createOutputStream(OutputStream os) throws IOException {
		ObjectOutputStream out = new ObjectOutputStream(os);
		out.writeObject(diagram);
		out.close();
	}

	/**
	 * @see org.eclipse.gef.ui.parts.GraphicalEditor#configureGraphicalViewer()
	 */
	protected void configureGraphicalViewer() {
		super.configureGraphicalViewer();
		getGraphicalViewer().setRootEditPart(new ScalableRootEditPart());
		getGraphicalViewer().setEditPartFactory(new ActivityPartFactory());
		getGraphicalViewer().setKeyHandler(
				new GraphicalViewerKeyHandler(getGraphicalViewer())
						.setParent(getCommonKeyHandler()));

		ContextMenuProvider provider = new FlowContextMenuProvider(
				getGraphicalViewer(), getActionRegistry());
		getGraphicalViewer().setContextMenu(provider);
		getSite().registerContextMenu(
				"org.eclipse.gef.examples.flow.editor.contextmenu", //$NON-NLS-1$
				provider, getGraphicalViewer());

	}

	/**
	 * @see org.eclipse.gef.ui.parts.GraphicalEditor#initializeGraphicalViewer()
	 */
	protected void initializeGraphicalViewer() {
		getGraphicalViewer().setContents(diagram);
		getGraphicalViewer().addDropTargetListener(
				new TemplateTransferDropTargetListener(getGraphicalViewer()));

	}

	/**
	 * @see org.eclipse.gef.ui.parts.GraphicalEditorWithPalette#initializePaletteViewer()
	 */
	protected void initializePaletteViewer() {
		super.initializePaletteViewer();
		getPaletteViewer().addDragSourceListener(
				new TemplateTransferDragSourceListener(getPaletteViewer()));
	}

	/**
	 * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void doSave(IProgressMonitor monitor) {
		// try {
		// ByteArrayOutputStream out = new ByteArrayOutputStream();
		// createOutputStream(out);
		// IFile file = ((IFileEditorInput) getEditorInput()).getFile();
		// file.setContents(new ByteArrayInputStream(out.toByteArray()), true,
		// false, monitor);
		// out.close();
		// getCommandStack().markSaveLocation();
		// } catch (Exception e) {
		// e.printStackTrace();
		// }
	}

	/**
	 * @see org.eclipse.ui.ISaveablePart#doSaveAs()
	 */
	public void doSaveAs() {
		// SaveAsDialog dialog = new SaveAsDialog(getSite().getWorkbenchWindow()
		// .getShell());
		// dialog.setOriginalFile(((IFileEditorInput)
		// getEditorInput()).getFile());
		// dialog.open();
		// IPath path = dialog.getResult();
		//
		// if (path == null)
		// return;
		//
		// IWorkspace workspace = ResourcesPlugin.getWorkspace();
		// final IFile file = workspace.getRoot().getFile(path);
		//
		// WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
		// public void execute(final IProgressMonitor monitor)
		// throws CoreException {
		// try {
		// ByteArrayOutputStream out = new ByteArrayOutputStream();
		// createOutputStream(out);
		// file.create(new ByteArrayInputStream(out.toByteArray()),
		// true, monitor);
		// out.close();
		// } catch (Exception e) {
		// e.printStackTrace();
		// }
		// }
		// };
		//
		// try {
		// new ProgressMonitorDialog(getSite().getWorkbenchWindow().getShell())
		// .run(false, true, op);
		// setInput(new FileEditorInput((IFile) file));
		// getCommandStack().markSaveLocation();
		// } catch (Exception e) {
		// e.printStackTrace();
		// }
	}

	protected KeyHandler getCommonKeyHandler() {
		if (sharedKeyHandler == null) {
			sharedKeyHandler = new KeyHandler();
			sharedKeyHandler
					.put(KeyStroke.getPressed(SWT.DEL, 127, 0),
							getActionRegistry().getAction(
									ActionFactory.DELETE.getId()));
			sharedKeyHandler.put(
					KeyStroke.getPressed(SWT.F2, 0),
					getActionRegistry().getAction(
							GEFActionConstants.DIRECT_EDIT));
		}
		return sharedKeyHandler;
	}

	/**
	 * @see org.eclipse.gef.ui.parts.GraphicalEditorWithPalette#getPaletteRoot()
	 */
	protected PaletteRoot getPaletteRoot() {
		if (root == null)
			root = FlowEditorPaletteFactory.createPalette();
		return root;
	}

	// public void gotoMarker(IMarker marker) {
	// }

	/**
	 * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
	 */
	public boolean isSaveAsAllowed() {
		return true;
	}

	/**
	 * @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput)
	 */
	protected void setInput(IEditorInput input) {
		super.setInput(input);

		// IFile file = ((IFileEditorInput) input).getFile();
		// try {
		// InputStream is = file.getContents(false);
		// ObjectInputStream ois = new ObjectInputStream(is);
		// diagram = (ActivityDiagram) ois.readObject();
		// ois.close();
		// } catch (Exception e) {
		// // This is just an example. All exceptions caught here.
		// e.printStackTrace();
		diagram = new ActivityDiagram();
		// }
	}

}
