package jp.hasc.hasctool.ui.views;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;

/**
 * An example showing how to create a multi-page editor. This example has 3
 * pages:
 * <ul>
 * <li>page 0 contains a nested text editor.
 * <li>page 1 allows you to change the font used in page 2
 * <li>page 2 shows the words in page 0 in sorted order
 * </ul>
 */
public abstract class AbstractWaveEditor extends MultiPageEditorPart implements
		IResourceChangeListener {
	/** logger for this class */
	private final static org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
			.getLog(AbstractWaveEditor.class);

	public static final long DEFAULT_TASK_TIMEOUT = 30000;

	/** The text editor. */
	protected TextEditor textEditor_;

	/** The WaveView. */
	protected WaveViewWidget waveViewWidget_;

	/**
	 * Creates a multi-page editor example.
	 */
	public AbstractWaveEditor() {
		super();
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
	}
	
	protected int textEditorPageIndex_;
	protected int waveEditorPageIndex_;

	/**
	 * Creates page 0 of the multi-page editor, which contains a text editor.
	 */
	protected void createTextEditorPage() {
		try {
			textEditor_ = new TextEditor();
			textEditorPageIndex_ = addPage(textEditor_, getEditorInput());
			setPageText(textEditorPageIndex_, "Text"); // textEditor_.getTitle());
		} catch (PartInitException e) {
			ErrorDialog.openError(getSite().getShell(),
					"Error creating nested text editor", null, e.getStatus());
		}
	}

	protected void createWaveEditorPage() {
		waveViewWidget_ = new WaveViewWidget(getContainer(), SWT.NONE);
		waveViewWidget_.setFollowSlider(false);
		waveEditorPageIndex_ = addPage(waveViewWidget_);
		setPageText(waveEditorPageIndex_, "Wave");
	}

	/**
	 * Creates the pages of the multi-page editor.
	 */
	@Override
	protected void createPages() {
		createTextEditorPage();
		createWaveEditorPage();
	}

	/**
	 * The <code>MultiPageEditorPart</code> implementation of this
	 * <code>IWorkbenchPart</code> method disposes all nested editors. Subclasses
	 * may extend.
	 */
	public void dispose() {
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
		super.dispose();
	}

	/**
	 * Saves the multi-page editor's document.
	 */
	public void doSave(IProgressMonitor monitor) {
		//getEditor(textEditorPageIndex_)
		textEditor_.doSave(monitor);
	}

	/**
	 * Saves the multi-page editor's document as another file. Also updates the
	 * text for page 0's tab, and updates this multi-page editor's input to
	 * correspond to the nested editor's.
	 */
	public void doSaveAs() {
		IEditorPart editor = textEditor_; //getEditor(textEditorPageIndex_);
		editor.doSaveAs();
		//setPageText(textEditorPageIndex_, editor.getTitle());
		setInput(editor.getEditorInput());
		setPartName(getEditorInput().getName());
	}

	/*
	 * (non-Javadoc) Method declared on IEditorPart
	 */
	public void gotoMarker(IMarker marker) {
		setActivePage(textEditorPageIndex_);
		IDE.gotoMarker(textEditor_/*getEditor(textEditorPageIndex_)*/, marker);
	}

	/**
	 * The <code>MultiPageEditorExample</code> implementation of this method
	 * checks that the input is an instance of <code>IFileEditorInput</code>.
	 */
	public void init(IEditorSite site, IEditorInput editorInput)
			throws PartInitException {
		if (!(editorInput instanceof IFileEditorInput))
			throw new PartInitException("Invalid Input: Must be IFileEditorInput");
		super.init(site, editorInput);
		setPartName(editorInput.getName());
	}

	/*
	 * (non-Javadoc) Method declared on IEditorPart.
	 */
	public boolean isSaveAsAllowed() {
		return true;
	}

	/**
	 * Calculates the contents of a wave page when it is activated.
	 */
	protected void pageChange(int newPageIndex) {
		super.pageChange(newPageIndex);
		//
		if (newPageIndex==waveEditorPageIndex_) {
			updateWaveEditorViewContents();
		}
	}

	private void updateWaveEditorViewContents() {
		String editorText = getEditorText();
		try {
			onUpdateWaveEditorViewContents(editorText);
		} catch (Exception ex) {
			LOG.warn("Exception",ex);
		}
	}

	protected String getEditorText() {
		String editorText =
			textEditor_.getDocumentProvider().getDocument(textEditor_.getEditorInput()).get();
		return editorText;
	}
	
	abstract protected void onUpdateWaveEditorViewContents(String editorText) throws Exception;

	/**
	 * Closes all project files on project close.
	 */
	public void resourceChanged(final IResourceChangeEvent event) {
		if (event.getType() == IResourceChangeEvent.PRE_CLOSE) {
			Display.getDefault().asyncExec(new Runnable() {
				public void run() {
					IWorkbenchPage[] pages = getSite().getWorkbenchWindow().getPages();
					for (int i = 0; i < pages.length; i++) {
						if (((FileEditorInput) textEditor_.getEditorInput()).getFile()
								.getProject().equals(event.getResource())) {
							IEditorPart editorPart = pages[i].findEditor(textEditor_
									.getEditorInput());
							pages[i].closeEditor(editorPart, true);
						}
					}
				}
			});
		}
	}

	public WaveViewWidget getWaveViewWidget() {
		return waveViewWidget_;
	}

	public TextEditor getTextEditor() {
		return textEditor_;
	}

}
