/*******************************************************************************
 * Copyright (c) 2003, 2004 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 API and implementation
 *******************************************************************************/
/*
 * Created on Jan 19, 2004
 *
 * To change the template for this generated file go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
package org.eclipse.jst.j2ee.internal.webservice;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

import org.eclipse.core.internal.resources.WorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.impl.NotificationImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jst.common.navigator.internal.providers.CommonAdapterFactoryContentProvider;
import org.eclipse.jst.j2ee.internal.webservices.WSDLServiceExtManager;
import org.eclipse.jst.j2ee.internal.webservices.WSDLServiceHelper;
import org.eclipse.jst.j2ee.internal.webservices.WebServicesManager;
import org.eclipse.jst.j2ee.webservice.wsclient.ServiceRef;
import org.eclipse.jst.j2ee.webservice.wsdd.Handler;
import org.eclipse.jst.j2ee.webservice.wsdd.PortComponent;
import org.eclipse.wst.common.internal.emfworkbench.integration.DynamicAdapterFactory;
import org.eclipse.wst.common.internal.emfworkbench.integration.EditModelEvent;
import org.eclipse.wst.common.internal.emfworkbench.integration.EditModelListener;
import org.eclipse.wst.common.navigator.internal.provisional.views.INavigatorContentProvider;

/**
 * @author jlanuti
 * 
 * To change the template for this generated type comment go to Window - Preferences - Java - Code
 * Generation - Code and Comments
 */
public class WebServicesNavigatorContentProvider extends CommonAdapterFactoryContentProvider implements INavigatorContentProvider, EditModelListener {

	private WebServicesManager webServicesManager = null;
	private boolean activityEnabled = false;
	private WebServiceNavigatorGroup webServiceNavigatorGroup;
	private WebServiceNavigatorGroupType SERVICES = null;
	private WebServiceNavigatorGroupType CLIENTS = null;
	private HashMap HANDLERS = new HashMap();
	private final static String VIEWER_ID = "org.eclipse.wst.navigator.ui.WTPCommonNavigator";//$NON-NLS-1$
	
	private TreeViewer viewer = null;
	
	public WebServicesNavigatorContentProvider() {
		super(createAdapterFactory());
		WebServicesManager.getInstance().addListener(this);
		// create the default synchronizer for any web service editor to use with view due
		// to the usage of seperate edit models.
		WebServicesNavigatorSynchronizer.createInstance(createAdapterFactory(), this);
		
	}
	
	/**
	 * Configure and return a composite adapter factory for our contents
	 */
	public static AdapterFactory createAdapterFactory() {
		return new DynamicAdapterFactory(VIEWER_ID);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.navigator.internal.views.navigator.INavigatorContentProvider#getChildren(java.lang.Object)
	 */
	public Object[] getChildren(Object parentElement) {
//		if (!NavigatorActivityHelper.isActivityEnabled(getContainingExtension())) {
//			activityEnabled = false;
//			return super.getChildren(parentElement);
//		}
//		activityEnabled = true;
		WSDLServiceHelper serviceHelper = WSDLServiceExtManager.getServiceHelper();
		if (parentElement instanceof WorkspaceRoot) {
			return new Object[]{getWebServicesNavigatorGroup(parentElement)};
		} else if (parentElement instanceof WebServiceNavigatorGroup) {
			return new Object[]{getServicesGroup(), getClientsGroup()};
		} else if (parentElement instanceof WebServiceNavigatorGroupType && ((WebServiceNavigatorGroupType) parentElement).isServices()) {
			List result = new ArrayList();
			result.addAll(getWebServicesManager().getInternalWSDLServices());
			result.addAll(getWebServicesManager().getExternalWSDLServices());
			return result.toArray();
		} else if (parentElement instanceof WebServiceNavigatorGroupType && ((WebServiceNavigatorGroupType) parentElement).isClients()) {
			return getWebServicesManager().getAllWorkspaceServiceRefs().toArray();
		} else if (serviceHelper.isService(parentElement)) {
			return getServiceLevelNodes(parentElement).toArray();
		} else if (parentElement instanceof WebServiceNavigatorGroupType && ((WebServiceNavigatorGroupType) parentElement).isHandlers()) {
			return getHandlerChildren(parentElement).toArray();
		} else if (parentElement instanceof ServiceRef) {
			Collection result = new ArrayList();
			result.add(getHandlersGroup(parentElement));
			return result.toArray();
		} else if (parentElement instanceof Handler) {
			return new ArrayList().toArray();
		} else if (serviceHelper.isWSDLResource(parentElement))
			return new ArrayList().toArray();
		else
			return super.getChildren(parentElement);
	}

	private List getServiceLevelNodes(Object parentElement) {
		List result = new ArrayList();
		// add service classes
		if (getWebServicesManager().isServiceInternal((EObject) parentElement) && getWebServicesManager().getServiceImplBean((EObject) parentElement) != null)
			result.add(getWebServicesManager().getServiceImplBean((EObject) parentElement));
		// Add handlers
		if (getWebServicesManager().isServiceInternal((EObject) parentElement))
			result.add(getHandlersGroup(parentElement));
		//add wsdl file
		Resource wsdl = getWebServicesManager().getWSDLResource((EObject) parentElement);
		if (wsdl != null)
			result.add(wsdl);
		return result;
	}

	private List getHandlerChildren(Object parentElement) {
		List result = new ArrayList();
		WebServiceNavigatorGroupType handlersGroup = (WebServiceNavigatorGroupType) parentElement;
		// handle web service handlers case
		if (handlersGroup.getWsdlService() != null) {
			PortComponent port = WebServicesManager.getInstance().getPortComponent(handlersGroup.getWsdlService());
			if (port != null && port.getHandlers() != null && !port.getHandlers().isEmpty())
				result.addAll(port.getHandlers());
		}
		// handle service ref case
		else if (handlersGroup.getServiceRef() != null) {
			result.addAll(handlersGroup.getServiceRef().getHandlers());
		}
		return result;
	}

	/**
	 * @param parentElement
	 * @return
	 */
	protected WebServiceNavigatorGroup getWebServicesNavigatorGroup(Object parentElement) {
		if (webServiceNavigatorGroup == null)
			webServiceNavigatorGroup = new WebServiceNavigatorGroup((WorkspaceRoot) parentElement);
		return webServiceNavigatorGroup;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.navigator.internal.views.navigator.INavigatorContentProvider#getParent(java.lang.Object)
	 */
	public Object getParent(Object element) {
		if (element instanceof WorkspaceRoot)
			return null;
		else if (element instanceof WebServiceNavigatorGroup)
			return ((WebServiceNavigatorGroup) element).getRoot();
		else
			return super.getParent(element);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.navigator.internal.views.navigator.INavigatorContentProvider#hasChildren(java.lang.Object)
	 */
	public boolean hasChildren(Object element) {
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.navigator.internal.views.navigator.INavigatorContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
	 *      java.lang.Object, java.lang.Object)
	 */
	public void inputChanged(Viewer aViewer, Object oldInput, Object newInput) {
		// TODO handle change events
		if (aViewer !=null && aViewer instanceof TreeViewer)
			viewer = (TreeViewer)aViewer;
		super.inputChanged(aViewer,oldInput,newInput);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
	 */
	public void dispose() {
		super.dispose();
		WebServicesManager.getInstance().removeListener(this);
		// dispose current instance of web service editor/explorer synchronizer
		WebServicesNavigatorSynchronizer.disposeInstance();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.internal.emfworkbench.integration.EditModelListener#editModelChanged(org.eclipse.wst.common.internal.emfworkbench.integration.EditModelEvent)
	 */
	public void editModelChanged(EditModelEvent anEvent) {
		//this.getExtensionSite().notifyElementReplaced(this, ((WebServicesNavigatorContentProvider) getContentProvider()).getNavigatorGroup());
		notifyChanged(new NotificationImpl(anEvent.getEventCode(),getNavigatorGroup(),getNavigatorGroup()));
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
	 */
	public Object[] getElements(Object inputElement) {
		return getChildren(inputElement);
	}

	/**
	 * @return Returns the navigatorGroup.
	 */
	public WebServiceNavigatorGroup getNavigatorGroup() {
		if (null == webServiceNavigatorGroup) {
			webServiceNavigatorGroup = new WebServiceNavigatorGroup((WorkspaceRoot) ResourcesPlugin.getWorkspace().getRoot());
		}
		return webServiceNavigatorGroup;
	}

	protected WebServicesManager getWebServicesManager() {
		if (webServicesManager == null)
			webServicesManager = WebServicesManager.getInstance();
		return webServicesManager;
	}

	/**
	 * @return Returns the activityEnabled.
	 */
	public boolean isActivityEnabled() {
		return activityEnabled;
	}

	private WebServiceNavigatorGroupType getServicesGroup() {
		if (SERVICES == null)
			SERVICES = new WebServiceNavigatorGroupType(WebServiceNavigatorGroupType.SERVICES);
		return SERVICES;
	}

	private WebServiceNavigatorGroupType getClientsGroup() {
		if (CLIENTS == null)
			CLIENTS = new WebServiceNavigatorGroupType(WebServiceNavigatorGroupType.CLIENTS);
		return CLIENTS;
	}

	private WebServiceNavigatorGroupType getHandlersGroup(Object key) {
		if (key == null)
			return null;
		WebServiceNavigatorGroupType handler = null;
		handler = (WebServiceNavigatorGroupType) HANDLERS.get(key);
		WSDLServiceHelper serviceHelper = WSDLServiceExtManager.getServiceHelper();
		if (handler == null) {
			if (serviceHelper.isService(key))
				handler = new WebServiceNavigatorGroupType(WebServiceNavigatorGroupType.HANDLERS, (EObject) key);
			else if (key instanceof ServiceRef)
				handler = new WebServiceNavigatorGroupType(WebServiceNavigatorGroupType.HANDLERS, (ServiceRef) key);
			if (handler != null)
				HANDLERS.put(key, handler);
		}
		return handler;
	}
	/**
	 * @return Returns the viewer.
	 */
	public TreeViewer getViewer() {
		return viewer;
	}
}