/**
 * File:    ZoomControl.java
 * Created: 23.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.managed.zoom;

import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.gef.Disposable;
import org.eclipse.gef.editparts.ZoomListener;
import org.eclipse.gef.editparts.ZoomManager;
import org.eclipse.gef.ui.actions.ZoomComboContributionItem;
import org.eclipse.jwt.we.editors.actions.handlers.ZoomInHandler;
import org.eclipse.jwt.we.editors.actions.handlers.ZoomOutHandler;
import org.eclipse.jwt.we.editors.pages.activityEditor.internal.IActivityEditor;
import org.eclipse.jwt.we.misc.util.GeneralHelper;


/**
 * The controller for the zoom activities (toolbar and menu). The
 * ZoomComboContributionItem has to be set (in ActionBarContributor) and the method
 * refreshZoom() in WEEditor has to be called every time the editor is changed (i.e. every
 * time a page is activated and every time a file is activated).
 * 
 * @version $Id: ZoomControl.java,v 1.10 2009-11-26 12:41:32 chsaad Exp $
 * @author Christian Saad (csaad@gmx.net), Programming distributed Systems Lab, University
 *         of Augsburg, Germany, www.ds-lab.org
 */
public class ZoomControl
		implements ZoomListener, Disposable
{

	/**
	 * The singleton instance
	 */
	private static ZoomControl myinstance = null;

	/**
	 * The ZoomManager used to zoom in or out
	 */
	private ZoomManager zoomManager;

	/**
	 * The handlers for zoom in
	 */
	private ArrayList zoomInHandlers = new ArrayList();

	/**
	 * The handlers for zoom out
	 */
	private ArrayList zoomOutHandlers = new ArrayList();

	/**
	 * The zoom combo box
	 */
	private ZoomComboContributionItem zoomItem;


	/**
	 * Constructor
	 */
	private ZoomControl()
	{
		super();
	}


	/**
	 * Returns the singleton instance
	 */
	public static ZoomControl getInstance()
	{
		if (myinstance == null)
			myinstance = new ZoomControl();
		return myinstance;
	}


	/**
	 * Set a reference to the zoom combo box.
	 * 
	 * @param zoomItem
	 */
	public void setZoomItem(ZoomComboContributionItem zoomItem)
	{
		this.zoomItem = zoomItem;
	}


	/**
	 * Exchanged the possibly outdated zoomManager with a new one and attaches this class
	 * as a listener to it.
	 */
	public void refreshZoomManager()
	{
		// if no window is open or activity sheed is active, then the listener is removed
		// from the old zoom manager and the zoom manager is thrown away
		if (GeneralHelper.getActiveInstance() == null
				|| !(GeneralHelper.getActiveInstance().getActiveEditor() instanceof IActivityEditor))
		{
			if (zoomManager != null)
			{
				zoomManager.removeZoomListener(this);
				zoomManager = null;
			}
			return;
		}

		// the new zoom manager from the active editor sheet
		ZoomManager newZoomManager = GeneralHelper.getActiveInstance()
				.getCurrentActivitySheet().getRootEditPart().getZoomManager();

		// if nothing has changed, the zoom manager is still the right one...
		if (newZoomManager == zoomManager)
		{
			return;
		}

		// ...if not, remove the listener from the old zoommanager...
		if (zoomManager != null)
		{
			zoomManager.removeZoomListener(this);
		}

		// ...and add a listener to the new zoommanager
		zoomManager = newZoomManager;

		if (zoomManager != null)
		{
			zoomManager.addZoomListener(this);
		}
	}


	/**
	 * Sets the enabled state of the handlers. If enabled is false, than the handlers are
	 * all set to false.
	 * 
	 * @param enable
	 */
	private void refreshEnabledState(boolean enable)
	{
		if (enable && zoomManager != null && GeneralHelper.getActiveInstance() != null)
		{
			// set zoom manager of combo box
			if (zoomItem != null)
			{
				zoomItem.setZoomManager(zoomManager);
			}

			// set enabled state of zoom in handlers
			boolean canZoomIn = zoomManager.canZoomIn();
			for (Iterator iterator = zoomInHandlers.iterator(); iterator.hasNext();)
			{
				ZoomInHandler zih = (ZoomInHandler) iterator.next();
				zih.setEnabled(canZoomIn);
			}

			// set enabled state of zoom out handlers
			boolean canZoomOut = zoomManager.canZoomOut();
			for (Iterator iterator = zoomOutHandlers.iterator(); iterator.hasNext();)
			{
				ZoomOutHandler zoh = (ZoomOutHandler) iterator.next();
				zoh.setEnabled(canZoomOut);
			}
		}
		else
		{
			// disable combo box
			if (zoomItem != null)
			{
				zoomItem.setZoomManager(null);
			}

			// disable zoom in handlers
			for (Iterator iterator = zoomInHandlers.iterator(); iterator.hasNext();)
			{
				ZoomInHandler zih = (ZoomInHandler) iterator.next();
				zih.setEnabled(false);
			}

			// disable zoom out handlers
			for (Iterator iterator = zoomOutHandlers.iterator(); iterator.hasNext();)
			{
				ZoomOutHandler zoh = (ZoomOutHandler) iterator.next();
				zoh.setEnabled(false);
			}
		}
	}


	/**
	 * Set enabled state of zoom handlers according to the available functions of the zoom
	 * manager.
	 */
	public void enableZoom()
	{
		refreshEnabledState(true);
	}


	/**
	 * Disable all zoom handlers.
	 */
	public void disableZoom()
	{
		refreshEnabledState(false);
	}


	/**
	 * Zoom in.
	 */
	public void zoomIn()
	{
		if (zoomManager != null)
		{
			zoomManager.zoomIn();
		}
	}


	/**
	 * Zoom out.
	 */
	public void zoomOut()
	{
		if (zoomManager != null)
		{
			zoomManager.zoomOut();
		}
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editparts.ZoomListener#zoomChanged(double)
	 */
	public void zoomChanged(double zoom)
	{
		// if zoom has changed, refresh enabled state
		refreshEnabledState(true);
	}


	/**
	 * Register a zoom in handler.
	 * 
	 * @param zoomInHandler
	 */
	public void registerZoomInHandler(ZoomInHandler zoomInHandler)
	{
		zoomInHandlers.add(zoomInHandler);
		refreshEnabledState(true);
	}


	/**
	 * Register a zoom out handler.
	 * 
	 * @param zoomOutHandler
	 */
	public void registerZoomOutHandler(ZoomOutHandler zoomOutHandler)
	{
		zoomOutHandlers.add(zoomOutHandler);
		refreshEnabledState(true);
	}


	/**
	 * Unregister a zoom in handler.
	 * 
	 * @param zoomInHandler
	 */
	public void unRegisterZoomInHandler(ZoomInHandler zoomInHandler)
	{
		zoomInHandlers.remove(zoomInHandler);
	}


	/**
	 * Unregister a zoom out handler.
	 * 
	 * @param zoomOutHandler
	 */
	public void unRegisterZoomOutHandler(ZoomOutHandler zoomOutHandler)
	{
		zoomOutHandlers.remove(zoomOutHandler);
	}


	/**
	 * Dispose.
	 * 
	 * @see org.eclipse.gef.Disposable#dispose()
	 */
	public void dispose()
	{
		// remove listener from zoom manager
		if (zoomManager != null)
		{
			zoomManager.removeZoomListener(this);
		}

		zoomManager = null;
		zoomItem = null;
	}

}
