//------------------------------------------------------------------------------
// 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.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.epf.diagram.core.services.DiagramManager;
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.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
import org.eclipse.gmf.runtime.diagram.ui.image.ImageFileFormat;
import org.eclipse.gmf.runtime.diagram.ui.render.clipboard.DiagramGenerator;
import org.eclipse.gmf.runtime.diagram.ui.render.util.CopyToImageUtil;
import org.eclipse.gmf.runtime.notation.Diagram;
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
 * @author Shashidhar Kannoori
 * @since 1.0
 */
public class NewActivityDiagramService implements IActivityDiagramService {

	private Composite parent = null;

	private Composite holder = null;

	private File pubDir;

	private static Map<String, Integer> typeMap = new HashMap<String, Integer>();

	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 NewActivityDiagramService() {
		this(null, new File(LibraryService.getInstance().getCurrentMethodLibraryPath()));
	}

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

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

	private AbstractDiagramGraphicalViewer getDiagramViewer(int diagramType, Object wrapper) {
		// 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 IDiagramService.ACTIVITY_DIAGRAM:
			return new NewActivityDiagramViewer(holder, wrapper);

		case IDiagramService.ACTIVITY_DETAIL_DIAGRAM:
			return new NewActivityDetailDiagramViewer(holder,wrapper);

		case IDiagramService.WORK_PRODUCT_DEPENDENCY_DIAGRAM:
			return new NewWPDependencyDiagramViewer(holder,wrapper);

		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 IDiagramService.ACTIVITY_DIAGRAM:
				if ( info.canPublishADImage() )
				{
					return (info.getActivityDiagram() != null) && info.canPublishADImage();
				}
				break;
	
			case IDiagramService.ACTIVITY_DETAIL_DIAGRAM:
				if ( info.canPublishADDImage() )
				{
					return (info.getActivityDetailDiagram() != null) && info.canPublishADDImage();
				}
				break;
							
			case IDiagramService.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;
			}


			// Check diagram exists, don't generate for suppressed.
			Diagram d = getDiagram(e, type);
			
			//Check publishing options.
			boolean exist = (d != null);
			if (exist) {
				//TODO: Check for suppression.
//				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 == IDiagramManager.ACTIVITY_DIAGRAM &&
						checkVariability(e, filter,type) != null){
					return;
				}
					
			}else{
				
				if((type == IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM))
					return;

				// For Activity Diagram un opened extension publish.
				if(type == IDiagramManager.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 == IDiagramManager.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, wrapper);
				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 = getDiagram(e, type);
				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;
			Diagram replacerDiagram = getDiagram(replacer, type);
			if (replacerDiagram != null) {
				return replacer;
			} else {
				return null;
			}
		} else {
			Diagram baseDiagram = getDiagram((Activity) ve, type);
			if (baseDiagram != null) {
				
				// Check first if baseDiagram is suppressed.
				//TODO: Suppression work.
//				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;
	}

	public DiagramGenerator createDiagramImage(DiagramEditPart diagramEP, ImageFileFormat fileFormat)
	throws CoreException {
		CopyToImageUtil util = new CopyToImageUtil();
		DiagramGenerator dGen = util.copyToImage(diagramEP, new Path(pubDir.getPath()), fileFormat, new NullProgressMonitor());
		dGen.createAWTImageForDiagram();
		return dGen;
	}
	
	public Diagram getDiagram(Activity e, int type){
		DiagramManager dMgr = DiagramManager.getInstance(TngUtil.getOwningProcess(e));
		Diagram diagram = null;
		try{
			List list = dMgr.getDiagrams(e, type);
			if(!list.isEmpty()){
				diagram = (Diagram)list.get(0);
			}
		}catch(Exception ex){
			//TODO : Logger.
			System.out.println("Error in getDiagram()" + ex.getMessage());
		}
		finally{
			if(dMgr != null){
				dMgr.release();
			}
		}
		return diagram;
	}
}