//------------------------------------------------------------------------------
// 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.library.services;

import java.util.Collection;
import java.util.Iterator;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryResources;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.edit.command.ActionManager;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.util.ContentDescriptionFactory;
import org.eclipse.epf.uma.util.IMethodLibraryPersister.FailSafeMethodLibraryPersister;
import org.eclipse.osgi.util.NLS;

/**
 * This helper is using an instance of IActionManager to keep track of changes.
 * Clien must {@link #dispose() <em>dispose</em>} this helper after use.
 * 
 * @author Jinhua Xi
 * @since 1.0
 */
public class LibraryModificationHelper {

	ActionManager actionMgr = null;

	public LibraryModificationHelper() {
	}

	public ActionManager getActionManager() {
		if (actionMgr != null) {
			return actionMgr;
		}

		actionMgr = new ActionManager() {
			public boolean doAction(int actionType, EObject object,
					EStructuralFeature feature, Object value, int index) {
				if (canUpdate(object)) {
					return super.doAction(actionType, object, feature, value,
							index);
				}
				return false;
			}

			protected void save(Resource resource) {
			}
		};

		return actionMgr;
	}

	public void dispose() {
		if (actionMgr != null) {
			actionMgr.dispose();
			actionMgr = null;
		}
	}

	public static boolean canUpdate(EObject object) {
		IStatus status = TngUtil.checkEdit(object, null);
		if (status.isOK()) {
			return true;
		} else {
			String msg = NLS.bind(LibraryResources.LibraryModificationHelper_cannotUpdate, TngUtil.getTypeText(object), object
			.eGet(UmaPackage.eINSTANCE.getNamedElement_Name()));
			LibraryPlugin.getDefault().getMsgDialog().displayWarning(
					LibraryResources.warningDlg_title
					, msg, TngUtil.getMessage(status));

			return false;
		}
	}

	public boolean isSaveNeeded() {
		return (actionMgr != null) && actionMgr.isSaveNeeded();
	}

	public void save() {
		if (actionMgr == null) {
			return;
		}

		FailSafeMethodLibraryPersister persister = getPersister();
		try {
			Collection modifiedResources = actionMgr.getModifiedResources();
			for (Iterator iter = modifiedResources.iterator(); iter.hasNext();) {
				Resource resource = (Resource) iter.next();
				try {
					persister.save(resource);
				} catch (Exception e) {
					String msg = NLS.bind(LibraryResources.errorDlg_saveError, resource.getURI().toFileString()); 
					LibraryPlugin.getDefault().getMsgDialog().displayError(
							LibraryResources.errorDlg_title
							, msg, e);
				}
			}

			try {
				persister.commit();
				actionMgr.saveIsDone();
			} catch (Exception e) {
				try {
					persister.rollback();
				} catch (Throwable th) {
					try {
						// if rollback failed, reload the library
						LibraryService.getInstance()
								.reopenCurrentMethodLibrary();
					} catch (RuntimeException e1) {
						e1.printStackTrace();
					}
				}
				e.printStackTrace();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public FailSafeMethodLibraryPersister getPersister() {
		return ContentDescriptionFactory.getMethodLibraryPersister()
				.getFailSafePersister();
	}

}
