//------------------------------------------------------------------------------
// 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.
 * 
 * @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);
					}
				}
			}
		}
	}


	public PublisherElement getPublisherElement(String id) {
		return (PublisherElement)publisherMap.get(id);
	}
 
	public List getPublisherElements() {
		return new ArrayList(publisherMap.values());
	}
	
	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;
	}
}
