/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) 
 *                                                                            
 *  All rights reserved. This program and the accompanying materials           
 *  are made available under the terms of the Eclipse Public License 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Florian Pirchner - Initial implementation
 * 
 */

package org.eclipse.osbp.ecview.extension.grid.editparts.renderer;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Delegates the calls to the implementing services provided by OSGi-DS.
 */
public final class DelegatingGridRendererFactory implements
		IGridRendererFactory {

	/** The Constant LOGGER. */
	private static final Logger LOGGER = LoggerFactory
			.getLogger(DelegatingGridRendererFactory.class);
	
	/** The instance. */
	private static DelegatingGridRendererFactory instance = new DelegatingGridRendererFactory();

	/** The delegates. */
	private final List<IGridRendererFactory> delegates = Collections
			.synchronizedList(new ArrayList<IGridRendererFactory>());
	
	/** The stashed. */
	private List<IGridRendererFactory> stashed;

	/**
	 * Instantiates a new delegating grid renderer factory.
	 */
	private DelegatingGridRendererFactory() {
	}

	/**
	 * Returns the instance of that manager.
	 * 
	 * @return the instance
	 */
	public static DelegatingGridRendererFactory getInstance() {
		return instance;
	}

	/**
	 * Removes all factories. Should only be used very carefully
	 */
	public void clear() {
		delegates.clear();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isFor(IViewContext uiContext, IGridRendererEditpart editpart) {
		for (IGridRendererFactory factory : delegates
				.toArray(new IGridRendererFactory[delegates.size()])) {
			if (factory.isFor(uiContext, editpart)) {
				return true;
			}
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.extension.grid.editparts.renderer.IGridRendererFactory#createRenderer(org.eclipse.osbp.ecview.core.common.context.IViewContext, org.eclipse.osbp.ecview.extension.grid.editparts.renderer.IGridRendererEditpart)
	 */
	@Override
	public Object createRenderer(IViewContext uiContext,
			IGridRendererEditpart editpart) throws IllegalArgumentException {
		for (IGridRendererFactory factory : delegates
				.toArray(new IGridRendererFactory[delegates.size()])) {
			if (factory.isFor(uiContext, editpart)) {
				try {
					Object result = factory.createRenderer(uiContext, editpart);
					if (result != null) {
						return result;
					}
				} catch (IllegalArgumentException e) {
					// nothing to do. Try the next factory
				}
			}
		}
		LOGGER.error("No proper converterFactory found for elements {} {}",
				new Object[] { uiContext, editpart });
		return null;
	}

	/**
	 * Will stash the current state. ONLY FOR TESTS!
	 */
	public void stash() {
		if (stashed != null) {
			return;
		}
		stashed = new ArrayList<IGridRendererFactory>(delegates);
	}

	/**
	 * Will unstash the stashed state. ONLY FOR TESTS!
	 */
	public void unstash() {
		if (stashed == null) {
			return;
		}
		delegates.clear();
		delegates.addAll(stashed);
		stashed = null;
	}

	/**
	 * Adds a new factory to the manager.
	 * 
	 * @param factory
	 *            Factory to be added.
	 */
	public void addDelegate(IGridRendererFactory factory) {
		if (!delegates.contains(factory)) {
			delegates.add(factory);
		}
	}

	/**
	 * Removes the factory from the manager.
	 * 
	 * @param factory
	 *            Factory to be removed.
	 */
	public void removeDelegate(IGridRendererFactory factory) {
		if (factory == null) {
			return;
		}
		delegates.remove(factory);
	}

	/**
	 * OSGi-DS component.
	 */
	@Component(immediate = true, service = {})
	public static class ServiceComponent {

		/**
		 * Called by OSGi-DS.
		 * 
		 * @param context
		 *            Component context
		 * @param properties
		 *            Map of properties
		 */
		@Activate
		public void activate(ComponentContext context,
				Map<String, Object> properties) {
			LOGGER.debug("DelegatingPresenterFactory activated");
		}

		/**
		 * Called by OSGi-DS.
		 * 
		 * @param context
		 *            Component context
		 * @param properties
		 *            Map of properties
		 */
		@Deactivate
		public void deactivate(ComponentContext context,
				Map<String, Object> properties) {
			LOGGER.debug("DelegatingPresenterFactory deactivated");
		}

		/**
		 * Called by OSGi DS.
		 * 
		 * @param factory
		 *            Factory to be added
		 */
		@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC, unbind = "removeDelegate")
		protected void addDelegate(IGridRendererFactory factory) {
			DelegatingGridRendererFactory.getInstance().addDelegate(factory);
		}

		/**
		 * Called by OSGi DS.
		 * 
		 * @param factory
		 *            Factory to be added
		 */
		protected void removeDelegate(IGridRendererFactory factory) {
			DelegatingGridRendererFactory.getInstance().removeDelegate(factory);
		}
	}
}
