/**
 * File:    WEActionHandler.java
 * Created: 20.09.2007
 *
 *
/*******************************************************************************
 * Copyright (c) 2005-2011
 * University of Augsburg, Germany <www.ds-lab.org>
 *
 * 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:
 *    Christian Saad, Programming distributed Systems Lab, University of Augsburg 
 *    	- initial API and implementation
 *******************************************************************************/

package org.eclipse.jwt.we.editors.actions;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.HandlerEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jwt.we.misc.util.GeneralHelper;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;


/**
 * This is a base class for an "action" which is referenced through the
 * org.eclipse.ui.menus extension point (i.e. as a handler for a command).
 * 
 * When calling the constructor with "true", the menu/toolbar/popup entry associated with
 * the command of this handler will only be enabled if a WEEditor is active.
 * 
 * @version $Id: WEActionHandler.java
 * @author Christian Saad (csaad@gmx.net), Programming distributed Systems Lab, University
 *         of Augsburg, Germany, www.ds-lab.org
 * @since 0.6.0
 */
public abstract class WEActionHandler
		extends AbstractHandler
		implements ISelectionListener
{

	/**
	 * The Logger.
	 */
	// private static final Logger logger = Logger.getLogger(WEActionHandler.class);
	/**
	 * Indicates whether the command should only be enabled if an WEEditor is active.
	 */
	private boolean requiresOpenEditor;

	/**
	 * Indicates whether the command is enabled.
	 */
	private boolean enabled;


	/**
	 * Constructor.
	 * 
	 * @param requiresOpenEditor
	 */
	public WEActionHandler(boolean requiresOpenEditor)
	{
		super();

		setRequiresOpenEditor(requiresOpenEditor);

		// add selection listener and refresh enabled state
		if (isRequiresOpenEditor())
		{

			final WEActionHandler theInstance = this;

			PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable()
			{

				public void run()
				{
					// selection listener can only be attached if a workbench window is
					// present
					if (PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null)
					{
						// add listener
						PlatformUI.getWorkbench().getActiveWorkbenchWindow()
								.getSelectionService().addSelectionListener(theInstance);

						// call selection changed method
						ISelection selection;

						if (GeneralHelper.getActiveInstance() != null)
						{
							selection = GeneralHelper.getActiveInstance()
									.getSelectionProvider().getSelection();
						}
						else
						{
							selection = new StructuredSelection();
						}

						selectionChanged(null, selection);
					}
					else
					{
						// there is a bug in eclipse where all handlers which appear only
						// in the popup menu are first removed and than created again when
						// closing the application. because this happens every time we
						// do not want to display an error on each program exit

						// logger.warning("could not attach selection listener to handler
						// because
						// no workbench window is present.");

						// set enabled state to false
						setEnabled(false);
					}
				}
			});
		}
		else
		{
			// set enabled state to true
			setEnabled(true);
		}
	}


	/**
	 * Is the "requires open editor" property set?
	 * 
	 * @return requiresOpenEditor
	 */
	public boolean isRequiresOpenEditor()
	{
		return requiresOpenEditor;
	}


	/**
	 * Sets the "requires open editor" property.
	 * 
	 * @param requiresOpenEditor
	 */
	private void setRequiresOpenEditor(boolean requiresOpenEditor)
	{
		this.requiresOpenEditor = requiresOpenEditor;
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.AbstractHandler#isEnabled()
	 */
	@Override
	public boolean isEnabled()
	{
		return enabled;
	}


	/**
	 * Sets the enabled state and notifies listeners.
	 * 
	 * @param enabled
	 */
	public void setEnabled(boolean enabled)
	{
		if (this.enabled != enabled)
		{
			this.enabled = enabled;
			fireHandlerChanged(new HandlerEvent(this, true, false));
		}
	}


	/**
	 * Sets the internal enabled state depending on the "requires open editor" property.
	 */
	private void refreshEnabledState()
	{
		if (GeneralHelper.getActiveInstance() != null)
		{
			setEnabled(true);
		}
		else
		{
			setEnabled(false);
		}
	}


	/**
	 * Refresh enabled state if selection has changed.
	 */
	public void selectionChanged(IWorkbenchPart part, ISelection selection)
	{
		refreshEnabledState();
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.commands.AbstractHandler#dispose()
	 */
	@Override
	public void dispose()
	{
		super.dispose();

		// remove listener
		if (isRequiresOpenEditor()
				&& PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null)
		{
			PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService()
					.removeSelectionListener(this);
		}
	}

}
