/*******************************************************************************
 * <copyright>
 *
 * Copyright (c) 2005, 2010 SAP AG.
 * 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:
 *    Stefan Dimov - initial API, implementation and documentation
 *
 * </copyright>
 *
 *******************************************************************************/
package org.eclipse.jpt.jpadiagrameditor.ui.internal.provider;

import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.graphiti.dt.AbstractDiagramTypeProvider;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.impl.AddContext;
import org.eclipse.graphiti.features.context.impl.CustomContext;
import org.eclipse.graphiti.features.context.impl.RemoveContext;
import org.eclipse.graphiti.mm.algorithms.RoundedRectangle;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.platform.IDiagramEditor;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.tb.IToolBehaviorProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jpt.jpa.core.JpaProject;
import org.eclipse.jpt.jpa.core.MappingKeys;
import org.eclipse.jpt.jpa.core.context.java.JavaPersistentType;
import org.eclipse.jpt.jpa.core.context.persistence.ClassRef;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnit;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.JPADiagramEditor;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.facade.EclipseFacade;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.feature.AddAllEntitiesFeature;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.feature.AddJPAEntityFeature;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.feature.RemoveRelationFeature;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.i18n.JPAEditorMessages;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.modelintegration.util.ModelIntegrationUtil;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JPACheckSum;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JPAEditorConstants;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JPASolver;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JpaArtifactFactory;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.SizePosition;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;


public class JPAEditorDiagramTypeProvider extends AbstractDiagramTypeProvider {
	
	private IToolBehaviorProvider[] toolBehaviorProviders;
    public final static String ID = "org.eclipse.jpt.jpadiagrameditor.ui.provider.JPAEditorDiagramTypeProvider"; //$NON-NLS-1$
    boolean isDisposed = false;
    boolean readOnly = false;
	
    public JPAEditorDiagramTypeProvider() {
    	IFeatureProvider fp = new JPAEditorFeatureProvider(this, new JPASolver());
        setFeatureProvider(fp);
    }

    @Override
	public void init(Diagram diagram, IDiagramEditor diagramEditor) {
    	super.init(diagram, diagramEditor);
    	if (getTargetJPAProject() == null)
    		closeEditor();
    	JPAEditorDiagramTypeProvider provider = ModelIntegrationUtil.getProviderByDiagram(diagram);
    	if ((provider != null) && provider.isAlive()) 
    		provider.getDiagramEditor().getSite().getWorkbenchWindow().getActivePage().closeEditor(provider.getDiagramEditor(), true);
    	ModelIntegrationUtil.mapDiagramToProvider(getDiagram(), this);
	}
    
    
    @Override
    public IToolBehaviorProvider[] getAvailableToolBehaviorProviders() {
        if (toolBehaviorProviders == null) {
            toolBehaviorProviders =
                new IToolBehaviorProvider[] { new JPAEditorToolBehaviorProvider(this, EclipseFacade.INSTANCE) };
        }
        return toolBehaviorProviders;
    }
    
    public JPAEditorFeatureProvider getFeatureProvider() {
    	return (JPAEditorFeatureProvider)super.getFeatureProvider();
    }
    
	public boolean hasToAdd() {
		JpaProject project = getTargetJPAProject();
		PersistenceUnit unit = project.getRootContextNode().getPersistenceXml().getPersistence().persistenceUnits().next();
		
		for (Iterator<ClassRef> classRefs = unit.classRefs(); classRefs.hasNext();) {
			ClassRef classRef = classRefs.next();
			if (classRef.getJavaPersistentType() != null) { 
				JavaPersistentType jpt = classRef.getJavaPersistentType(); 
				if (jpt.getMappingKey() == MappingKeys.ENTITY_TYPE_MAPPING_KEY) {
					PictogramElement pe = getFeatureProvider().getPictogramElementForBusinessObject(jpt);
					if (pe == null)
						return true;					
				}
			}
		}		
		return false;
	}
        
    
    public 	void postInit() {
    	final String jptName = getDiagramEditor().getPartProperty(JPAEditorConstants.OPEN_WHOLE_PERSISTENCE_UNIT_EDITOR_PROPERTY);
		if (jptName != null) {
			boolean hasToAdd = hasToAdd(); 
			boolean readOnly = openPersistedDiagram(hasToAdd);
			if (hasToAdd && !readOnly)
			addRemainingEntities();
		} else
			try {
				openPersistedDiagram(false);
			} catch (NullPointerException e) {
				return;
			}
	}
    
    private void addRemainingEntities() {
		final AddAllEntitiesFeature feature = new AddAllEntitiesFeature(getFeatureProvider());
		final CustomContext context = new CustomContext();
		TransactionalEditingDomain ted = ModelIntegrationUtil.getTransactionalEditingDomain(feature.getFeatureProvider().getDiagramTypeProvider().getDiagram());
		ted.getCommandStack().execute(new RecordingCommand(ted) {
			@Override
			protected void doExecute() {
				feature.execute(context);
			}
		});
	}

    private void closeEditor() {
		PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
			public void run() {
				IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();					
				page.closeEditor(getDiagramEditor(), false);
			}
		});    	
    }
    
	private boolean openPersistedDiagram(boolean hasToAdd) {		
		final Diagram diagram = getDiagram();
		final JpaProject proj = getTargetJPAProject();
		IProject project = proj.getProject();
		PersistenceUnit pu = JpaArtifactFactory.instance().getPersistenceUnit(proj);
		String diagramName = pu.getName();
	    IPath path = ModelIntegrationUtil.getDiagramsFolderPath(project).append(diagramName).addFileExtension(ModelIntegrationUtil.DIAGRAM_FILE_EXTENSION);
		final IFile f = project.getFile(path);
		boolean readOnly = (f != null) && f.exists() && f.isReadOnly();
		if (readOnly) {
			if (JPACheckSum.INSTANCE().isModelDifferentFromDiagram(diagram, proj) || hasToAdd) {
				String message = hasToAdd ? JPAEditorMessages.JPAEditorDiagramTypeProvider_JPADiagramReadOnlyHasToAddMsg : 
								JPAEditorMessages.JPAEditorDiagramTypeProvider_JPADiagramReadOnlyMsg;
				MessageDialog dialog = new MessageDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
						JPAEditorMessages.JPAEditorDiagramTypeProvider_JPADiagramReadOnlyTitle, null, message,
						MessageDialog.INFORMATION, new String[] {JPAEditorMessages.BTN_OK, JPAEditorMessages.BTN_CANCEL}, 0) {
					protected int getShellStyle() {
						return SWT.TITLE | SWT.BORDER
							| SWT.APPLICATION_MODAL
							| getDefaultOrientation();
					}
				};
				if (dialog.open() == 1) {
					closeEditor();		
					return true;
				} else {
					IStatus stat = ResourcesPlugin.getWorkspace().validateEdit(new IFile[]{f}, null);
					if (!stat.isOK()) {
						message = NLS.bind(JPAEditorMessages.JPAEditorDiagramTypeProvider_cantMakeDiagramWritableMsg, 
								stat.getMessage());;
						dialog = new MessageDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
								JPAEditorMessages.JPAEditorDiagramTypeProvider_cantMakeDiagramWritableTitle, null, message,
								MessageDialog.CANCEL, new String[] {JPAEditorMessages.BTN_OK}, 0) {
							protected int getShellStyle() {
								return SWT.CLOSE | SWT.TITLE | SWT.BORDER
									| SWT.APPLICATION_MODAL
									| getDefaultOrientation();
							}
						};
						dialog.open();
						closeEditor();						
						return true;
					} else {
						readOnly = false;
					}
				}
			} else {
				return readOnly;
			}
		}
		
		removeConnections();
		
		final Hashtable<String, SizePosition> marks = new Hashtable<String, SizePosition>(); 
		List<Shape> picts = diagram.getChildren();
		if (picts.size() == 0)
			return readOnly;
		Iterator<Shape> it = picts.iterator();
		HashSet<Shape> toDelete = new HashSet<Shape>();
		// collecting data from the saved pictograms
		while (it.hasNext()) {
			Shape pict = it.next();
			String name = Graphiti.getPeService().getPropertyValue(pict, JPAEditorConstants.PROP_ENTITY_CLASS_NAME); 
			SizePosition rectSP = loadSizeAndPosition(pict);
			marks.put(name, rectSP);
			toDelete.add(pict);
		}
		final Iterator<Shape> iter = toDelete.iterator();
		
		TransactionalEditingDomain ted = TransactionUtil.getEditingDomain(diagram);
		ted.getCommandStack().execute(new RecordingCommand(ted) {
			protected void doExecute() {
				while (iter.hasNext())
					Graphiti.getPeService().deletePictogramElement(iter.next());
				Collection<Connection> cns = diagram.getConnections();
				Iterator<Connection> itera = cns.iterator();
				Set<Connection> toDel = new HashSet<Connection>();
				while (itera.hasNext()) 
					toDel.add(itera.next());
				itera = toDel.iterator();
				while (itera.hasNext())
					Graphiti.getPeService().deletePictogramElement(itera.next());		
				
				Enumeration<String> itr = marks.keys();
				
				// create new pictograms
				while (itr.hasMoreElements()) {
					String entityName = itr.nextElement();
					JavaPersistentType jpt = JpaArtifactFactory.instance().getContextPersistentType(proj, entityName);
					if (jpt != null) {
						SizePosition sp = marks.get(entityName);
						AddContext ctx = new AddEntityContext(sp.primaryCollapsed,
								sp.relationCollapsed, sp.basicCollapsed);
						ctx.setNewObject(jpt);
						ctx.setTargetContainer(getDiagram());
						ctx.setWidth(sp.getWidth());
						ctx.setHeight(sp.getHeight());
						ctx.setX(sp.getX());
						ctx.setY(sp.getY());
						AddJPAEntityFeature ft = new AddJPAEntityFeature(getFeatureProvider());
						ft.add(ctx);
					}
				}
			}			
		});
		getDiagramEditor().saveWithoutEntities(new NullProgressMonitor());

		// delete old pictograms
		return false;
	}

	private SizePosition loadSizeAndPosition(Shape pict) {
		RoundedRectangle rect = (RoundedRectangle)pict.getGraphicsAlgorithm();
		SizePosition rectSP = new SizePosition(rect.getWidth(), rect.getHeight(), 
											   rect.getX(), rect.getY()); 
		
		rectSP.primaryCollapsed = JPAEditorConstants.TRUE_STRING.equals(Graphiti.getPeService().getPropertyValue(pict, JPAEditorConstants.PRIMARY_COLLAPSED));
		rectSP.relationCollapsed = JPAEditorConstants.TRUE_STRING.equals(Graphiti.getPeService().getPropertyValue(pict, JPAEditorConstants.RELATION_COLLAPSED));
		rectSP.basicCollapsed = JPAEditorConstants.TRUE_STRING.equals(Graphiti.getPeService().getPropertyValue(pict, JPAEditorConstants.BASIC_COLLAPSED));
		return rectSP;
	}
    
	private void removeConnections() {
		Collection<org.eclipse.graphiti.mm.pictograms.Connection> cons = getDiagram().getConnections();
		Iterator<org.eclipse.graphiti.mm.pictograms.Connection> consIt = cons.iterator();
		Collection<org.eclipse.graphiti.mm.pictograms.Connection> allCons = new HashSet<org.eclipse.graphiti.mm.pictograms.Connection>();
		while (consIt.hasNext()) {
			org.eclipse.graphiti.mm.pictograms.Connection con = consIt.next();
			allCons.add(con);
		}
		consIt = allCons.iterator();
		while (consIt.hasNext()) {
			org.eclipse.graphiti.mm.pictograms.Connection con = consIt.next();
	    	RemoveContext ctx = new RemoveContext(con);
	    	RemoveRelationFeature ft = new RemoveRelationFeature(getFeatureProvider());
	    	ft.remove(ctx);			
		}		
	}
	
	public JPADiagramEditor getDiagramEditor() {
		return (JPADiagramEditor)super.getDiagramEditor();
	}    
    
	private JpaProject getTargetJPAProject() {
		return ModelIntegrationUtil.getProjectByDiagram(getDiagram());
	}
	
	public boolean isAlive() {
		return !isDisposed;
	}
	           
	public void dispose() {
		super.dispose();
		setFeatureProvider(null);
		isDisposed = true;
	}
        
}