/*******************************************************************************
 * Copyright (c) 2003, 2007 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.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jst.j2ee.internal.webservice.helper.WebServicesManager;
import org.eclipse.jst.j2ee.internal.webservices.WSDLServiceExtManager;
import org.eclipse.jst.j2ee.navigator.internal.IJ2EENavigatorConstants;
import org.eclipse.jst.j2ee.webservice.wsclient.ServiceRef;
import org.eclipse.jst.j2ee.webservice.wsclient.Webservice_clientPackage;
import org.eclipse.jst.j2ee.webservice.wsdd.Handler;
import org.eclipse.jst.j2ee.webservice.wsdd.PortComponent;
import org.eclipse.jst.j2ee.webservice.wsdd.WsddPackage;
import org.eclipse.wst.common.internal.emfworkbench.integration.DynamicAdapterFactory;

/**
 * @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 AdapterFactoryContentProvider {

	private static final Object[] NO_CHILDREN = new Object[0]; 

	private WebServicesManager webServicesManager = null; 
	private WebServiceNavigatorGroup webServiceNavigatorGroup;
	private WebServiceNavigatorGroupType SERVICES = null;
	private WebServiceNavigatorGroupType CLIENTS = null;
	private HashMap HANDLERS = new HashMap();
	private TreeViewer viewer = null;

	private WebServiceViewerSynchronization viewerSynchronization;
	NewProjectsListener projectListener;
	

	public WebServicesNavigatorContentProvider() {
		super(createAdapterFactory());
		viewerSynchronization = new WebServiceViewerSynchronization(this);
		projectListener = new NewProjectsListener(viewerSynchronization);

	} 
	
	public void dispose() { 
		super.dispose();
		projectListener.dispose();
	}

	/**
	 * Configure and return a composite adapter factory for our contents
	 */
	public static AdapterFactory createAdapterFactory() {
		return new DynamicAdapterFactory(IJ2EENavigatorConstants.VIEWER_ID);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.navigator.internal.views.navigator.INavigatorContentProvider#getChildren(java.lang.Object)
	 */
	public Object[] getChildren(Object parentElement) {
		
		if (parentElement instanceof IWorkspaceRoot) {
			// return new Object[]{ getWebServicesNavigatorGroup(parentElement) };
			if(WebServiceViewerSynchronization.isThereWebServicesPreferenceSet()){
				if(WebServiceViewerSynchronization.areThereWebServices()){
					viewerSynchronization.setNavigatorGroupAdded(true);
					return new Object[]{getNavigatorGroup()};
				} else {
					return NO_CHILDREN;
				}
			} else {
				// first time on this workspace, let the job set the WebServiceViewerSynchronization.ARE_THERE_WEBSERVICES
				if (!viewerSynchronization.hasIndexJobBeenScheduled()) {
					viewerSynchronization.startIndexJob();
				}
				return NO_CHILDREN;
			}
		} else if (parentElement instanceof WebServiceNavigatorGroup){
			if (!viewerSynchronization.hasIndexJobBeenScheduled()) {
				viewerSynchronization.startIndexJob();
			} 
			return new Object[]{getServicesGroup(), getClientsGroup()};

		}else if (parentElement instanceof WebServiceNavigatorGroupType) {
			if (!viewerSynchronization.hasIndexJobBeenScheduled()) {
				viewerSynchronization.startIndexJob();
			} 
			WebServiceNavigatorGroupType wsGroupType = (WebServiceNavigatorGroupType) parentElement;
			return wsGroupType.getChildren();
		
		} else if (WSDLServiceExtManager.getServiceHelper().isService(parentElement))
			return getServiceLevelNodes(parentElement).toArray();

		else if (parentElement instanceof ServiceRef)
			return new Object[]{getHandlersGroup(parentElement)};

		else if (parentElement instanceof Handler || parentElement instanceof org.eclipse.jst.j2ee.webservice.wsclient.Handler || WSDLServiceExtManager.getServiceHelper().isWSDLResource(parentElement))
			return NO_CHILDREN;

		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 = getWebServicesManager().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;
//	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.navigator.internal.views.navigator.INavigatorContentProvider#getParent(java.lang.Object)
	 */
	public Object getParent(Object element) {
		if (element instanceof IWorkspaceRoot)
			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.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(ResourcesPlugin.getWorkspace().getRoot());
		}
		return webServiceNavigatorGroup;
	}

	protected WebServicesManager getWebServicesManager() {
		if (webServicesManager == null)
			webServicesManager = WebServicesManager.getInstance();
		return webServicesManager;
	}
	
	private WebServiceNavigatorGroupType getServicesGroup() {
		if (SERVICES == null)
			SERVICES = new WebServiceNavigatorGroupType(WebServiceNavigatorGroupType.SERVICES, getAdapterFactory());
		return SERVICES;
	}

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

	private WebServiceNavigatorGroupType getHandlersGroup(Object key) {
		if (key == null)
			return null;
		WebServiceNavigatorGroupType handler = null;
		handler = (WebServiceNavigatorGroupType) HANDLERS.get(key);
		if (handler == null) {
			if (WSDLServiceExtManager.getServiceHelper().isService(key))
				handler = new WebServiceNavigatorGroupType(WebServiceNavigatorGroupType.HANDLERS, (EObject) key, getAdapterFactory());
			else if (key instanceof ServiceRef)
				handler = new WebServiceNavigatorGroupType(WebServiceNavigatorGroupType.HANDLERS, (ServiceRef) key, getAdapterFactory());

			if (handler != null)
				HANDLERS.put(key, handler);
		}
		return handler;
	}

	/**
	 * @return Returns the viewer.
	 */
	public TreeViewer getViewer() {
		return viewer;
	}
	
	public void notifyChanged(Notification notification) {
	
		if(notification.getNotifier() instanceof ServiceRef) {
			switch(notification.getFeatureID(ServiceRef.class)) {
				case Webservice_clientPackage.SERVICE_REF__HANDLERS:
					
					WebServiceNavigatorGroupType handlersGroup = getHandlersGroup(notification.getNotifier());

					if(handlersGroup != null) {
						switch(notification.getEventType()) {
							case Notification.ADD: 
								viewer.add(handlersGroup, notification.getNewValue());						
								break;
							case Notification.ADD_MANY: 
								viewer.add(handlersGroup, ((Collection)notification.getNewValue()).toArray());						
								break;
							case Notification.REMOVE: 						
								viewer.remove(notification.getOldValue());
								break;
							case Notification.REMOVE_MANY:
								viewer.remove(((Collection)notification.getOldValue()).toArray());
								break;
						}			
					}
					return;				
				default:			
			} 
		} else if(notification.getNotifier() instanceof PortComponent) {
			switch(notification.getFeatureID(PortComponent.class)) {
				case WsddPackage.PORT_COMPONENT__HANDLERS:
					
					PortComponent pComp = (PortComponent) notification.getNotifier();
					EObject service = getWebServicesManager().getService(pComp);
					if(service != null) {
						WebServiceNavigatorGroupType handlersGroup = getHandlersGroup(service);						
						if(handlersGroup != null) {
							switch(notification.getEventType()) {
								case Notification.ADD: 
									viewer.add(handlersGroup, notification.getNewValue());						
									break;
								case Notification.ADD_MANY: 
									viewer.add(handlersGroup, ((Collection)notification.getNewValue()).toArray());						
									break;
								case Notification.REMOVE: 						
									viewer.remove(notification.getOldValue());
									break;
								case Notification.REMOVE_MANY:
									viewer.remove(((Collection)notification.getOldValue()).toArray());
									break;
							}
						}
					}
					
					
					return;				
				default:			
			}
		}  
		super.notifyChanged(notification);	 
	}

}
