content: /**
   *  Copyright (c) 2013-2016 Angelo ZERR and Genuitec LLC.
   *  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:
   *  Piotr Tomiak <piotr@genuitec.com> - initial API and implementation
   */
  package tern.eclipse.ide.internal.ui;
  
  import java.io.IOException;
  
  import org.eclipse.core.resources.IFile;
  import org.eclipse.core.runtime.IProgressMonitor;
  import org.eclipse.core.runtime.IStatus;
  import org.eclipse.core.runtime.Status;
  import org.eclipse.core.runtime.jobs.Job;
  import org.eclipse.jface.text.IDocument;
  import org.eclipse.swt.widgets.Display;
  import org.eclipse.ui.IEditorInput;
  import org.eclipse.ui.IEditorPart;
  import org.eclipse.ui.IFileEditorInput;
  import org.eclipse.ui.IWorkbench;
  import org.eclipse.ui.IWorkbenchPart;
  import org.eclipse.ui.PlatformUI;
  
  import tern.ITernFile;
  import tern.ITernProject;
  import tern.TernResourcesManager;
  import tern.eclipse.ide.core.resources.TernDocumentFile;
  import tern.eclipse.ide.internal.ui.util.AllInOneWorkbenchListener;
  import tern.eclipse.ide.ui.TernUIPlugin;
  
  /**
   * This class is responsible for tracking currently activated editors and
   * triggering synchronization of files to Tern Server. Following rules are
   * applied:
   * <ul>
   * <li>if JS or HTML file is opened, ensureSynch is called</li>
   * <li>if JS editor looses focus, it's contents are uploaded to tern server</li>
   * <li>if HTML editor looses focus, it is removed from the server on the next
   * synchronization</li>
   * </ul>
   */
  public class EditorActivationTracker extends AllInOneWorkbenchListener {
  
  	private static final EditorActivationTracker INSTANCE = new EditorActivationTracker();
  
  	public static EditorActivationTracker getInstance() {
  		return INSTANCE;
  	}
  
  	private EditorActivationTracker() {
  		initialize();
  		// initialize sync if needed
  		Display.getDefault().asyncExec(new Runnable() {
  			@Override
  			public void run() {
  				IWorkbench bench = PlatformUI.getWorkbench();
  				if (bench.getWorkbenchWindowCount() > 0) {
  					partActivated(bench.getActiveWorkbenchWindow()
  							.getActivePage().getActivePart());
  				}
  			}
  		});
  	}
  
  	@Override
  	public void partActivated(IWorkbenchPart part) {
  		IFile file = getFile(part);
  		if (file != null
  				&& (TernResourcesManager.isHTMLFile(file) || TernResourcesManager
  						.isJSFile(file))) {
  			// Ensure that everything is synchronized when JS or HTML file is
  			// opened
  			final ITernProject project = TernResourcesManager
  					.getTernProject(file.getProject());
  			if (project != null) {
  				new Job("Synchronizing script resources with Tern server...") {
  					@Override
  					protected IStatus run(IProgressMonitor monitor) {
  						monitor.beginTask("", -1); //$NON-NLS-1$
  						project.getFileSynchronizer().ensureSynchronized();
  						return Status.OK_STATUS;
  					}
  				}.schedule();
  			}
  		}
  	}
  
  	@Override
  	public void partDeactivated(IWorkbenchPart part) {
  		IFile file = getFile(part);
  		boolean isHtml = false;
  		if (file != null
  				&& (TernResourcesManager.isJSFile(file) || (isHtml = TernResourcesManager
  						.isHTMLFile(file)))) {
  			final ITernProject project = TernResourcesManager
  					.getTernProject(file.getProject());
  			if (project != null) {
  				if (isHtml) {
  					// Remove HTML file contents from the server next time
  					// content assist is invoked
  					project.getFileSynchronizer().refresh(file);
  					return;
  				}
  				IDocument document = (IDocument) part
  						.getAdapter(IDocument.class);
  				if (document != null) {
  					// Synchronize file with the server, when user moves to the
  					// other editor without saving content. This allows Tern
  					// server to calculate completion proposals based on unsaved
  					// content.
  					final ITernFile tf = new TernDocumentFile(file, document);
  					new Job("Synchronizing sources with Tern server") {
  						@Override
  						protected IStatus run(IProgressMonitor monitor) {
  							try {
  								project.getFileSynchronizer().synchronizeFile(
  										tf);
  							} catch (IOException e) {
  								TernUIPlugin
  										.getDefault()
  										.getLog()
  										.log(new Status(IStatus.ERROR,
  												TernUIPlugin.PLUGIN_ID, e
  														.getMessage(), e));
  							}
  							return Status.OK_STATUS;
  						}
  					}.schedule();
  				}
  			}
  		}
  	}
  
  	private IFile getFile(IWorkbenchPart part) {
  		if (part instanceof IEditorPart) {
  			IEditorInput input = ((IEditorPart) part).getEditorInput();
  			if (input instanceof IFileEditorInput) {
  				return ((IFileEditorInput) input).getFile();
  			}
  		}
  		return null;
  	}
  
  }
  