//------------------------------------------------------------------------------
// 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.authoring.gef.viewer;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.epf.diagram.model.util.GraphicalDataHelper;
import org.eclipse.epf.diagram.model.util.GraphicalDataManager;
import org.eclipse.epf.diagramming.base.persistence.IDiagramService;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.VariabilityInfo;
import org.eclipse.epf.library.edit.util.IDiagramManager;
import org.eclipse.epf.library.edit.util.Suppression;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.layout.ProcessAdapterFactoryFilter;
import org.eclipse.epf.library.layout.diagram.DiagramInfo;
import org.eclipse.epf.library.layout.diagram.IActivityDiagramService;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.library.util.ResourceHelper;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;


/**
 * Provides service methods for creating diagram images for activity elements
 * 
 * @author Jinhua Xi
 * @since 1.0
 */
public class ActivityDiagramService implements IActivityDiagramService {

	private Composite parent = null;

	private Composite holder = null;

	private File pubDir;

	private static Map typeMap = new HashMap();

	private DiagramInfo diagramInfo = null;

	private boolean publishUncreatedADD = true;
	
	private boolean publishADForActivityExtension = true;

	static {
		typeMap.put(ResourceHelper.DIAGRAM_TYPE_WORKFLOW, new Integer(
				IDiagramManager.ACTIVITY_DIAGRAM));
		typeMap.put(ResourceHelper.DIAGRAM_TYPE_ACTIVITY_DETAIL, new Integer(
				IDiagramManager.ACTIVITY_DETAIL_DIAGRAM));
		typeMap.put(ResourceHelper.DIAGRAM_TYPE_WP_DEPENDENCY, new Integer(
				IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM));
	}

	public static int getIntType(String diagramType) {
		Integer type = (Integer) typeMap.get(diagramType);
		if (type != null) {
			return type.intValue();
		}

		return -1;
	}

	Shell shell = null;

	public ActivityDiagramService() {
		this(null, new File(LibraryService.getInstance().getCurrentMethodLibraryPath()));
	}

	public ActivityDiagramService(File pubDir) {
		this(null, pubDir);
	}

	public ActivityDiagramService(Composite parent, File pubDir) {
		this.parent = parent;
		this.pubDir = pubDir;
	}

	private AbstractDiagramGraphicalViewer getDiagramViewer(int diagramType) {
		// if the shell window is distroyed, recreate it
		if ((this.shell != null) && this.shell.isDisposed()) {
			this.parent = null;
			this.shell = null;
		}

		getViewerHolder(parent);

		switch (diagramType) {
		case IDiagramManager.ACTIVITY_DIAGRAM:
			return new ActivityDiagramViewer(holder);

		case IDiagramManager.ACTIVITY_DETAIL_DIAGRAM:
			return new ActivityDetailDiagramViewer(holder);

		case IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM:
			return new WPDependencyDiagramViewer(holder);
			
		default:
			return null;
		}
	}

	private void getViewerHolder(Composite parent) {
		if (parent == null) {
			if (shell == null || shell.isDisposed()) {
				shell = createShell();
			}
			shell.open();
			parent = shell;
		}

		if (holder != null) {
			holder.dispose();
		}

		holder = new Composite(parent, SWT.NONE);
		holder.setLayoutData(new GridData(1, 1)); // size can't be 0,0
		// otherwise the diagram
		// will not be painted
		holder.setLayout(new GridLayout());
		holder.setVisible(false);
	}

	private Shell createShell() {
		Shell shell = null;
		Display d = Display.getDefault();
		shell = new Shell(d);
		GridLayout layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		shell.setLayout(layout);
		shell.setBounds(0, 0, 0, 0);
		shell.setVisible(false);
		return shell;
	}

	public void dispose() {
		if ((shell != null) && (!shell.isDisposed())) {
			shell.close();
			shell.dispose();
		}
	}

	/**
	 * save the element diagram image and returns the image file url.
	 * 
	 * @param wrapper
	 * @param imgPath
	 * @param diagramType
	 * @param filter
	 *            IFilter
	 * @param sup
	 *            Suppression
	 * @return String the image path relative to the publishing dir
	 * 
	 * @see org.eclipse.epf.library.layout.diagram.IActivityDiagramService#saveDiagram(java.lang.Object, java.lang.String, java.lang.String, org.eclipse.epf.library.edit.IFilter, org.eclipse.epf.library.edit.util.Suppression)
	 */
	public DiagramInfo saveDiagram(final Object wrapper, final String imgPath, 
			final String diagramType, final IFilter filter,
			final Suppression sup) {
		// initialize the diagramInfo
		diagramInfo = null;

		// grab the UI thread to avoid thread access error
		SafeUpdateController.syncExec(new Runnable() {
			public void run() {
				__internal_saveDiagram(wrapper, imgPath, diagramType, filter, sup);
			}
		});

		return diagramInfo;
	}

	private boolean hasUserDefinedDiagram(Activity e, String imgPath, String diagramType) throws Exception
	{		
		// if there is a user defined diagram, use it
		org.eclipse.epf.diagram.model.util.DiagramInfo info = new org.eclipse.epf.diagram.model.util.DiagramInfo((Activity)e);
		switch (getIntType(diagramType))
		{
			case IDiagramManager.ACTIVITY_DIAGRAM:
				if ( info.canPublishADImage() )
				{
					return (info.getActivityDiagram() != null) && info.canPublishADImage();
				}
				break;
	
			case IDiagramManager.ACTIVITY_DETAIL_DIAGRAM:
				if ( info.canPublishADDImage() )
				{
					return (info.getActivityDetailDiagram() != null) && info.canPublishADDImage();
				}
				break;
							
			case IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM:
				if ( info.canPublishWPDImage() )
				{
					return (info.getWPDDiagram() != null ) && info.canPublishWPDImage();
				}
				break;

			default:
				break;
		}
		
		return false;
	}
	
	private void __internal_saveDiagram(Object wrapper, final String imgPath, String diagramType,
			IFilter filter, Suppression sup) {
		
		if ( sup.isSuppressed(wrapper) ) {
			return;
		}
		
		Object o = TngUtil.unwrap(wrapper);
		if (!(o instanceof Activity)) {
			return;
		}

		//MethodElement e = (MethodElement)o;
		Activity e = (Activity)o;
		// DiagramInfo diagramInfo = null;
		Image image = null;
		int type = getIntType(diagramType);
		if (type < 0) {
			return;
		}

		AbstractDiagramGraphicalViewer viewer = null;

		// keep the dirty flag and reset back to avoid make the library dirty
		boolean dirtyFlag = e.eResource().isModified();

		try {
			if ( hasUserDefinedDiagram((Activity)e, imgPath, diagramType) )
			{
				return;
			}


			// first check if we need to generate the diagram or not
			// if the diagram is supressed, don't generate diagram
			// don't create the diagram if it's not there,
			// id the diagram does not exist, it's supressed
			org.eclipse.epf.uma.Diagram d = GraphicalDataManager.getInstance()
					.getUMADiagram((Activity) e, type, false);

			// Allow the option to publish 'uncreated' diagrams
			// by default, uncreated activity detail diagrams will be published,
			// uncreated diagrams of other types will not be published
			boolean exist = (d != null);
			if (exist) {
				if (d.getSuppressed().booleanValue() == true)
					return;
				
				// If an extension has its own diagram. Base is replaced or contributed. 
				// extension diagram shows realized element in undefined location. 
				// In publishing don't display extension diagram even if it has its own
				// diagram if realized elements are coming in through variability.
				if(type == GraphicalDataHelper.ACTIVITY_DIAGRAM &&
						checkVariability(e, filter,type) != null){
					return;
				}
					
			}else{
				
				if((type == GraphicalDataHelper.WORK_PRODUCT_DEPENDENCY_DIAGRAM))
					return;

				// For Activity Diagram un opened extension publish.
				if(type == GraphicalDataHelper.ACTIVITY_DIAGRAM){
					// If option is not checked, don't generate a diagram
					if(!publishADForActivityExtension) return;
					
					//If extension is modified don't generate it.
					if(!e.getBreakdownElements().isEmpty())
						return;
					VariabilityElement calculatedBase = checkVariability(e, filter, type);
					if(calculatedBase == null) {
						return;
					}	
					
					wrapper = calculatedBase;
					e = (Activity)calculatedBase;
					exist = true;
				}
				
				if (publishUncreatedADD == false && type == GraphicalDataHelper.ACTIVITY_DETAIL_DIAGRAM){
					boolean contributorexist = false;
					// This is need, if contributor has a ADD diagra, base don't 
					// base should generate ADD in browsing.
					MethodConfiguration config = null;
					if (filter instanceof ProcessAdapterFactoryFilter) {
						config = ((ProcessAdapterFactoryFilter) filter)
								.getMethodConfiguration();
					}
					if (config == null)
						return;

					// Get immediate contributors first, and check immediate contributors
					// have anything extra breakdown elements.
					List list = ConfigurationHelper.getContributors(e, config);
					if(e instanceof Activity){
						Iterator iterator = list.iterator();
						if(iterator != null){
							while(iterator.hasNext()){
								Object act = iterator.next();
								if(act != null){
									org.eclipse.epf.uma.Diagram dx = GraphicalDataManager.getInstance()
									.getUMADiagram((Activity) act, type, false);
									if(dx != null){   
										contributorexist = true;
										break;
									}
								}
							}
						}
					}
					if(!contributorexist)
					return;
				}
			}
			
			try {
				viewer = getDiagramViewer(type);
				viewer.loadDiagram(wrapper, !exist, filter, sup);
				diagramInfo = viewer.getDiagramInfo();
				if (diagramInfo != null && !diagramInfo.isEmpty()) {
					image = viewer.createDiagramImage();
					if (image != null) {
						// save the image
						File f = new File(pubDir, imgPath);

						// make sure the file is created otherwise exception
						File parent = f.getParentFile();
						if (!parent.exists()) {
							parent.mkdirs();
						}

						if (!f.exists()) {
							f.createNewFile();
						}
						OutputStream os = new FileOutputStream(f);
						ImageLoader loader = new ImageLoader();
						loader.data = new ImageData[] { image.getImageData() };
						loader.save(os, SWT.IMAGE_JPEG);

						diagramInfo.setImageFilePath(imgPath);
					} else {
						System.out.println("Unable to create diagram image"); //$NON-NLS-1$
					}
				}
			} catch (RuntimeException e1) {
				e1.printStackTrace();
			}

			// delete the newly created diagram from the library
			if (!exist) {
				d = GraphicalDataManager.getInstance().getUMADiagram(
						(Activity) e, type, false);
				if (d != null) {
					EcoreUtil.remove(d);
				}
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {

				// restore the dirty flag
				e.eResource().setModified(dirtyFlag);

				if (viewer != null) {
					viewer.dispose();
				}
				if (image != null) {
					image.dispose();
				}
			} catch (RuntimeException e1) {
				e1.printStackTrace();
			}
		}

	}


	private VariabilityElement checkVariability(VariabilityElement e, IFilter filter,
			int type) {

		MethodConfiguration config = null;
		if (filter instanceof ProcessAdapterFactoryFilter) {
			config = ((ProcessAdapterFactoryFilter) filter)
					.getMethodConfiguration();
		}
		if (config == null)
			return null;

		// Get immediate contributors first, and check immediate contributors
		// have anything extra breakdown elements.
		List list = ConfigurationHelper.getContributors(e, config);
		for (Iterator iterator = list.iterator(); iterator.hasNext();) {
			Object next = iterator.next();
			if (next instanceof Activity) {
				if (!((Activity) next).getBreakdownElements().isEmpty())
					return null;
			}
		}

		// Get all Contributors from parent chain and contributor chain for the
		// element e.
		VariabilityInfo eInfo = ((ProcessAdapterFactoryFilter) filter)
				.getVariabilityInfo((VariabilityElement) e);
		List contributors = eInfo.getContributors();

		VariabilityElement ve = e.getVariabilityBasedOnElement();
		if (ve == null) {
			return null;
		}
		
		Activity replacer = (Activity) ConfigurationHelper.getReplacer(ve,
				config);
		if (replacer != null) {
			ve = replacer;
			org.eclipse.epf.uma.Diagram replacerDiagram = GraphicalDataManager
					.getInstance().getUMADiagram(replacer, type, false);
			if (replacerDiagram != null) {
				//anyReplacer.add(replacer);
				return replacer;
			} else {
				return null;
			}
		} else {
			org.eclipse.epf.uma.Diagram baseDiagram = GraphicalDataManager
					.getInstance()
					.getUMADiagram((Activity) ve, type, false);
			if (baseDiagram != null) {
				
				// Check first if baseDiagram is suppressed.
				if (baseDiagram.getSuppressed().booleanValue() == true)
					return null;
				
				// Find the contributors of Base
				VariabilityInfo veInfo = ((ProcessAdapterFactoryFilter) filter)
						.getVariabilityInfo((VariabilityElement) ve);
				List veContributors = veInfo.getContributors();
				if (contributors.size() != veContributors.size()) {
					for (Iterator iterator = contributors.iterator(); iterator
							.hasNext();) {
						Object next = iterator.next();
						if (!veContributors.contains(next)) {
							if (!((Activity) next).getBreakdownElements()
									.isEmpty()) {
								return null;
							}
						}
					}
				}
				
				return ve;
				
			}else{
				// If no base diagram, check base of base had any diagram.
				return checkVariability(ve, filter, type);
			}
		}
		
	}

	/**
	 * Set the window's preference attribute for Activity Detail Diagram.
	 * 
	 */
	public void setPublishedUnCreatedADD(boolean flag) {
		this.publishUncreatedADD = flag;
	}
	/**
	 * Set the window's preference attribute for Acitivyt Diagram
	 * 
	 */
	
	public void setPublishADForActivityExtension(boolean flag){
		this.publishADForActivityExtension = flag;
	}
}