/* 
-*- coding: latin-1 -*-

This file is part of RefactorErl.

RefactorErl is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

RefactorErl is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with RefactorErl.  If not, see <http://plc.inf.elte.hu/erlang/>.

The Original Code is RefactorErl.

The Initial Developer of the Original Code is Eötvös Loránd University.
Portions created  by Eötvös Loránd University and ELTE-Soft Ltd.
are Copyright 2007-2025 Eötvös Loránd University, ELTE-Soft Ltd.
and Ericsson Hungary. All Rights Reserved.
*/

package com.refactorerl.ui.presentation;

import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.NotEnabledException;
import org.eclipse.core.commands.NotHandledException;
import org.eclipse.core.commands.Parameterization;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.services.IServiceLocator;
import org.eclipse.ui.texteditor.ITextEditor;

import com.refactorerl.ui.communication.MessageParseHelper;
import com.refactorerl.ui.communication.StatusChangeMessage;
import com.refactorerl.ui.communication.event.IEvent;
import com.refactorerl.ui.communication.event.IEventHandler;
import com.refactorerl.ui.presentation.codebrowser.RemoteTemporaryFileEditorInput;
import com.refactorerl.ui.presentation.codebrowser.StringInput;
import com.refactorerl.ui.presentation.filelist.FileListView;

/**
 * This class listens to RefactorErl change events and reloads the Database view
 * if needed. This class is meant to be subscribed in an EventDispatcher, on a
 * topic which will receive events containing StatusChangeMessage objects. If
 * the change was a renaming, it refreshes the editor containing the file which
 * had a rename in its content. If the change was a module renaming, it closes
 * the old editor with the renamed file and opens a new one.
 * 
 * @author Daniel Lukacs, 2014 ELTE IK
 *
 */
class ReferlChangeEventHandler implements IEventHandler {

	public ReferlChangeEventHandler() {

	}

	@Override
	public void handleEvent(IEvent event) {

		Object o = Activator.getEdp().getValue(event);

		final StatusChangeMessage<?> change = MessageParseHelper.parseChanges2(o);

		if (change == null)
			return;

		final IPath changedFile = new Path(change.filePath);
		final boolean rename = change.key.equals("rename"); //$NON-NLS-1$

		new UIJob(getClass().toString()) {

			@Override
			public IStatus runInUIThread(IProgressMonitor monitor) {

				IWorkbenchWindow wb = PlatformUI.getWorkbench().getActiveWorkbenchWindow();

				IEditorReference[] openedEditors = wb.getActivePage().getEditorReferences();
				for (IEditorReference er : openedEditors) {
					try {
						IEditorInput ei = er.getEditorInput();
						IPath location = null;
						if (ei instanceof FileEditorInput) {
							final IFile file = ((FileEditorInput) ei).getFile();

							location = file.getLocation();
							if (changedFile.equals(location)){
								if (rename) {
									String newFilePath = (String) change.value;
									//
									// file.getProject()
									// .getFile(newFilePath).refreshLocal(IFile.DEPTH_INFINITE,
									// null);
									file.getProject().refreshLocal(IProject.DEPTH_INFINITE, null);
								} else
									file.refreshLocal(IFile.DEPTH_INFINITE, null);
							} else continue;
						} else if (ei instanceof RemoteTemporaryFileEditorInput) {
							location = ((RemoteTemporaryFileEditorInput) ei).getRemoteFilePath();
							if (changedFile.equals(location)){
								if (!rename)
									((RemoteTemporaryFileEditorInput) ei).refresh();
								// else do nothing
							} else continue;


						} else if (ei instanceof StringInput) {
							// untested
							location = ((StringInput) ei).getStorage().getFullPath();
							if (changedFile.equals(location)){
								ITextEditor ed = (ITextEditor) er.getEditor(true);
								ed.getDocumentProvider().changed(ed.getEditorInput());
								ed.doRevertToSaved();
							} else continue;
						} else
							return Status.OK_STATUS;

						
						if (rename) {
							ITextSelection textSelection = (ITextSelection) ((ITextEditor) er.getEditor(false))
									.getSite().getSelectionProvider().getSelection();
							int cursorPos = textSelection.getOffset();

							((ITextEditor) er.getEditor(false)).close(false);

							IServiceLocator serviceLocator = PlatformUI.getWorkbench();
							ICommandService commandService = (ICommandService) serviceLocator
									.getService(ICommandService.class);
							IHandlerService handlerService = (IHandlerService) serviceLocator
									.getService(IHandlerService.class);
							try {
								Command command = commandService.getCommand("com.refactorerl.ui.showFileCommand"); //$NON-NLS-1$
								Parameterization p = new Parameterization(
										command.getParameter("com.refactorerl.ui.showFileCommand.path"), //$NON-NLS-1$
										(String) change.value);
								Parameterization p2 = new Parameterization(
										command.getParameter("com.refactorerl.ui.showFileCommand.cursorpos"), //$NON-NLS-1$
										Integer.toString(cursorPos));
								ParameterizedCommand pc = new ParameterizedCommand(command, new Parameterization[] { p,
										p2 });
								handlerService.executeCommand(pc, null);
							} catch (ExecutionException | NotDefinedException | NotEnabledException
									| NotHandledException e) {
								Activator.showErrorDialog(e, PlatformUI.getWorkbench().getActiveWorkbenchWindow()
										.getShell());
							}
						}

					} catch (CoreException e) {
						Activator.showErrorDialog(e, PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
					}

				}
				
				// FIXME won't handle views in other perspectives
				// activeWB.getPages() won't work for this either
				if (change.key.equals("present") || change.key.equals("rename")) { //$NON-NLS-1$ //$NON-NLS-2$
					final FileListView fileListView = (FileListView) wb.getActivePage().findView(
							"com.refactorerl.ui.fileListView"); //$NON-NLS-1$

					if (fileListView != null)
						fileListView.reload();
				}
				
				return Status.OK_STATUS;
			}

		}.schedule();
		

	}
}