//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.publishing.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.epf.publishing.ui.actions.PublishAction;
import org.eclipse.jface.action.Action;
import org.osgi.framework.Bundle;

/**
 * Manages the creation of Publisher instances by loading the publisher extensions.
 * 
 * @author Jinhua Xi
 * @since 1.0
 */
public class PublisherFactory {

	/**
	 * The extension point namespace.
	 */
	public static final String EXTENSION_POINT_NAMESPACE = "org.eclipse.epf.publishing.ui"; //$NON-NLS-1$

	/**
	 * The extension point name.
	 */
	public static final String EXTENSION_POINT_NAME = "publishers"; //$NON-NLS-1$

	// The shared instance.
	private static PublisherFactory instance = null;

	// A map of publisher configuration elements.
	private Map publisherMap = new HashMap();

	/**
	 * Returns the shared instance.
	 */
	public static PublisherFactory getInstance() {
		if (instance == null) {
			synchronized (PublisherFactory.class) {
				if (instance == null) {
					instance = new PublisherFactory();
				}
			}
		}
		return instance;
	}

	/**
	 * Creates a new instance.
	 */
	private PublisherFactory() {
		init();
	}

	/**
	 * Performs the necessary initialization.
	 */
	protected void init() {
		// Process the "org.eclipse.epf.publishing.ui.publishers" extension point
		// contributors.
		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
		IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(
				EXTENSION_POINT_NAMESPACE, EXTENSION_POINT_NAME);
		if (extensionPoint != null) {
			IExtension[] extensions = extensionPoint.getExtensions();
			for (int i = 0; i < extensions.length; i++) {
				IExtension extension = extensions[i];
				String pluginId = extension.getNamespaceIdentifier();
				Bundle bundle = Platform.getBundle(pluginId);
				IConfigurationElement[] configElements = extension
						.getConfigurationElements();
				for (int j = 0; j < configElements.length; j++) {
					IConfigurationElement configElement = configElements[j];
					try {
						String id = configElement.getAttribute("id"); //$NON-NLS-1$
						String name = configElement.getAttribute("label"); //$NON-NLS-1$
						String icon = configElement.getAttribute("icon"); //$NON-NLS-1$
						String wizardClassName = configElement.getAttribute("wizardClass"); //$NON-NLS-1$
						String managerClassName = configElement.getAttribute("managerClass"); //$NON-NLS-1$
						if (	id != null && id.trim().length() > 0 
								&& name != null && name.trim().length() > 0 
								&& wizardClassName != null && wizardClassName.trim().length() > 0
								&& managerClassName != null && managerClassName.trim().length() > 0 ) {
							if (!publisherMap.containsKey(name)) {
								PublisherElement provider = new PublisherElement(
										bundle, id, name, icon, wizardClassName, managerClassName);
								
								publisherMap.put(id, provider);
							}
						}
					} catch (Exception e) {
						PublishingUIPlugin.getDefault().getLogger().logError(e);
					}
				}
			}
		}
	}


	/**
	 * get the publisher element which defines the publisher extension
	 * 
	 * @param id String id of the publisher
	 * 
	 * @return PublisherElement
	 */
	public PublisherElement getPublisherElement(String id) {
		return (PublisherElement)publisherMap.get(id);
	}
 
	/**
	 * get all publisher elements
	 * 
	 * @return List a list of PublisherElement objects
	 */
	public List getPublisherElements() {
		return new ArrayList(publisherMap.values());
	}
	
	/**
	 * create the UI actions for the publishers
	 * 
	 * @return Action[]
	 */
	public Action[] createPublishActions() {
		List items = new ArrayList();
		for ( Iterator it = getPublisherElements().iterator(); it.hasNext(); ) {
			PublisherElement e = (PublisherElement)it.next();
			
			Action action = new PublishAction(e.getId(), e.getLabel(), e.getImageDescriptor());
			items.add(action);
		} 

		int size = items.size();
		Action[] actions = new Action[size];
		items.toArray(actions);
		
		return actions;
	}
}
