/***************************************************************************************************
 * 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
 **************************************************************************************************/

package org.eclipse.jst.j2ee.internal.webservice.editmodel;

import java.util.ArrayList;
import java.util.Collections;
import java.util.EventObject;
import java.util.Hashtable;
import java.util.List;

import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jst.j2ee.internal.webservice.plugin.WebServicePlugin;
import org.eclipse.wst.common.internal.emf.resource.ReferencedResource;


public abstract class CompositeEditModel extends EditModel implements CommandStackListener {

	protected int fReferenceCount;

	protected Hashtable fEditModels;
	protected Hashtable fResources;
	protected Hashtable fRootObjects;
	protected List fDescriptors;

	protected EditModelEvent dirtyModelEvent;
	private List fListeners;
	protected boolean isNotifing = false;

	public int getReferenceCount() {
		return fReferenceCount;
	}

	public boolean access() {
		fReferenceCount++;
		if (fReferenceCount == 1) {
			//get all the registered edit models
			IConfigurationElement[] elements = getExtensions();

			//get a command stack
			createCommandStack();

			for (int i = 0; i < elements.length; i++) {
				try {
					Object editModelObject = elements[i].createExecutableExtension("class"); //$NON-NLS-1$
					if (editModelObject instanceof EditModel) {
						//Setup the edit model and add it to the Hashtable
						EditModel editModel = (EditModel) editModelObject;
						String descriptorName = elements[i].getAttribute("descriptorName"); //$NON-NLS-1$
						editModel.setResourceSet(fResourceSet);
						editModel.setProject(fProject);
						editModel.setInputFile(fInputFile);
						editModel.setCommandStack(fCommandStack);
						editModel.setParent(this);
						fEditModels.put(descriptorName, editModel);
						//Get the resource from the editmodel and add it to the resource Hashtable
						Resource res = editModel.getModelResource(descriptorName);
						if (res == null) {
							//Exit access()
							return false;
						}
						//The webservices.xml and webservicesclient.xml do not load as
						// ReferencedResources
						//so, for the time being, we only do proper accessing on the xmi resources
						// we load.
						if (res instanceof ReferencedResource)
							((ReferencedResource) res).accessForWrite();
						//todo: process the resource upon load (i.e. accessForWrite(), etc)
						fResources.put(descriptorName, res);
						//Get the root object from the resource and add it to the Hashtable
						EObject rootObject = editModel.getRootModelObject(descriptorName);
						fRootObjects.put(descriptorName, rootObject);
						fDescriptors.add(descriptorName);

					}
				} catch (CoreException e) {
					return false;
				}
			}
		}
		return true;
	}

	public abstract IConfigurationElement[] getExtensions();

	public void release() {
		fReferenceCount--;
		if (fReferenceCount == 0) {
			//release resources and dispose the edit model.
			Resource resource;
			int listsize = fDescriptors.size();
			for (int i = 0; i < listsize; i++) {
				String descriptorName = (String) fDescriptors.get(i);
				//release the resource
				resource = getModelResource(descriptorName);

				//The webservices.xml and webservicesclient.xml do not load as ReferencedResources
				//so, for the time being, we only do proper accessing on the xmi resources we load.
				if (resource instanceof ReferencedResource)
					((ReferencedResource) resource).releaseFromWrite();
				else {
					//this is a really bad but until we load ReferencedResources for
					// webservices.xml and
					//webservicesclient.xml we need to explicitly unload
					//resource.unload();
				}

				//remove stored resources, root objects and edit models from Hashtables
				fResources.remove(descriptorName);
				fRootObjects.remove(descriptorName);
				fEditModels.remove(descriptorName);
			}

			fDescriptors = null;
			fCommandStack = null;
			dirtyModelEvent = null;
			dispose();
		}
	}

	protected abstract void dispose();

	/** *************Getting resources and objects ******************* */
	public EditModel getEditModel(String descriptorName) {
		EditModel em = (EditModel) fEditModels.get(descriptorName);
		return em;
	}

	public Resource getModelResource(String descriptorName) {
		Resource res = (Resource) fResources.get(descriptorName);
		return res;
	}

	public EObject getRootModelObject(String descriptorName) {
		EObject res = (EObject) fRootObjects.get(descriptorName);
		return res;
	}

	public abstract EObject getRootModelObject();

	public abstract Resource getRootModelResource();


	/** *********Command Stack related methods*************************** */
	public BasicCommandStack createCommandStack() {
		if (fCommandStack == null) {
			fCommandStack = new BasicCommandStack();
			fCommandStack.addCommandStackListener(this);
		}
		return fCommandStack;
	}

	public void commandStackChanged(EventObject event) {
		if (dirtyModelEvent == null)
			dirtyModelEvent = new EditModelEvent(EditModelEvent.DIRTY, this);
		if (hasListeners())
			notifyListeners(dirtyModelEvent);
	}

	protected List getListeners() {
		if (fListeners == null)
			fListeners = new ArrayList();
		return fListeners;
	}

	/**
	 * Add
	 * 
	 * @aListener to the list of listeners.
	 */
	public void addListener(EditModelListener aListener) {
		if (aListener != null && !getListeners().contains(aListener))
			getListeners().add(aListener);
	}

	/**
	 * Returns true if there are any listeners
	 */
	public boolean hasListeners() {
		return !getListeners().isEmpty();
	}

	/**
	 * Notify listeners of
	 * 
	 * @anEvent.
	 */
	protected void notifyListeners(EditModelEvent anEvent) {
		if (fListeners == null)
			return;
		synchronized (this) {
			isNotifing = true;
		}
		try {
			List list = getListeners();
			for (int i = 0; i < list.size(); i++)
				((EditModelListener) list.get(i)).editModelChanged(anEvent);
		} finally {
			synchronized (this) {
				isNotifing = false;
			}
		}
	}

	/** *********Save related methods*************************** */
	public final void save(IProgressMonitor monitor) {
		//getSaveHandler().access();
		try {
			IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
				public void run(IProgressMonitor aMonitor) {
					primSave(aMonitor);
				}
			};
			runSaveOperation(runnable, monitor);
		} catch (CoreException ex) {
			//Pop up a dialog indicating that problems occurred during the save
			MessageDialog.openError(null, WebServicePlugin.getMessage("%TITLE_SAVE_ERROR"), WebServicePlugin.getMessage("%MSG_SAVE_ERROR")); //$NON-NLS-1$ //$NON-NLS-2$
		}

	}

	private void runSaveOperation(IWorkspaceRunnable runnable, IProgressMonitor monitor) throws CoreException {
		ResourcesPlugin.getWorkspace().run(runnable, monitor);
	}


	/**
	 * This will force all of the referenced Resources to be saved.
	 */
	public void primSave(IProgressMonitor monitor) {
		Resource resource;
		int listsize = fDescriptors.size();
		for (int i = 0; i < listsize; i++) {
			String descriptorName = (String) fDescriptors.get(i);
			resource = getModelResource(descriptorName);
			if (resource.isModified()) {
				try {
					resource.save(Collections.EMPTY_MAP);
					resource.setModified(false);
				} catch (Exception e) {
					//Ignore
				}
			}
		}

		getCommandStack().saveIsDone();
		if (hasListeners()) {
			EditModelEvent event = new EditModelEvent(EditModelEvent.SAVE, this);
			notifyListeners(event);
		}
	}

	public boolean isDirty() {
		Resource resource;
		int listsize = fDescriptors.size();
		for (int i = 0; i < listsize; i++) {
			String descriptorName = (String) fDescriptors.get(i);
			resource = getModelResource(descriptorName);
			if (resource.isModified()) {
				return true;
			}
		}
		return false;
	}


	public void resourceChanged(EditModelEvent anEvent) {
		if (hasListeners()) {
			anEvent.setEditModel(this);
			notifyListeners(anEvent);
		}
	}


	protected void resourceIsLoadedChanged(Resource aResource, boolean oldValue, boolean newValue) {
		//Do nothing for now
	}


	protected class ResourceAdapter extends AdapterImpl {
		public void notifyChanged(Notification notification) {
			if (notification.getEventType() == Notification.SET && notification.getFeatureID(null) == Resource.RESOURCE__IS_LOADED) {
				resourceIsLoadedChanged((Resource) notification.getNotifier(), notification.getOldBooleanValue(), notification.getNewBooleanValue());
			}
		}
	}

}