/*******************************************************************************
 * Copyright (c) 2001, 2010 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui.internal.reconcile;

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.reconciler.DirtyRegion;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.model.ModelLifecycleEvent;
import org.eclipse.wst.sse.core.internal.provisional.IModelLifecycleListener;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;

/**
 * An IStructuredModel aware Region Processor. Adds ModelLifecycle listener.
 * ModelLifecycle listener notifies us that some reinitialization needs to
 * take place.
 * 
 * Model aware "process()" Implements a IndexedRegion-based "contains()"
 * method using IStructuredModel.
 * 
 */
public class StructuredRegionProcessor extends DocumentRegionProcessor {

	class ModelLifecycleListener implements IModelLifecycleListener {
		IStructuredModel changing = null;
		/**
		 * @see org.eclipse.wst.sse.core.internal.provisional.IModelLifecycleListener#processPostModelEvent(org.eclipse.wst.sse.core.internal.model.ModelLifecycleEvent)
		 */
		public void processPostModelEvent(ModelLifecycleEvent event) {

			// if underlying StructuredDocument changed, need to reconnect it
			// here...
			// ex. file is modified outside the workbench
			if (event.getType() == ModelLifecycleEvent.MODEL_DOCUMENT_CHANGED) {
				if (changing != null && event.getModel() == changing) {
					IStructuredDocument sDoc = event.getModel().getStructuredDocument();

					if (DEBUG) {
						System.out.println("======================================================"); //$NON-NLS-1$
						System.out.println("StructuredRegionProcessor: DOCUMENT MODEL CHANGED TO: "); //$NON-NLS-1$
						System.out.println(sDoc.get());
						System.out.println("======================================================"); //$NON-NLS-1$
					}
					setDocument(sDoc);
				}
				changing = null;
			}
		}

		/**
		 * @see org.eclipse.wst.sse.core.internal.provisional.IModelLifecycleListener#processPreModelEvent(org.eclipse.wst.sse.core.internal.model.ModelLifecycleEvent)
		 */
		public void processPreModelEvent(ModelLifecycleEvent event) {
			if(fCurrentDoc != null) {
				IStructuredModel model = null;
				try {
					model = getStructuredModelForRead(fCurrentDoc);
					if (event.getType() == ModelLifecycleEvent.MODEL_DOCUMENT_CHANGED && event.getModel() == model) {
						changing = event.getModel();
						flushDirtyRegionQueue();
						// note: old annotations are removed via the strategies on
						// AbstractStructuredTextReconcilingStrategy#setDocument(...)
					}
				} finally {
					if(model != null) {
						model.releaseFromRead();
					}
				}
			}
		}
	}

	/**
	 * The life cycle listener used to listen to the current documents model even though
	 * this class does not hold onto a reference to the model.
	 */
	private IModelLifecycleListener fLifeCycleListener = new ModelLifecycleListener();
	/** Used to get the current model on demand so a model does not need to be held by permanently */
	private IDocument fCurrentDoc = null;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor#getOuterRegion(org.eclipse.jface.text.reconciler.DirtyRegion,
	 *      org.eclipse.jface.text.reconciler.DirtyRegion)
	 */
	protected DirtyRegion getOuterRegion(DirtyRegion root, DirtyRegion possible) {
		// first try simple region check if one region contains the other
		DirtyRegion outer = super.getOuterRegion(root, possible);
		if (outer == null && fCurrentDoc != null) {
			IStructuredModel sModel = null;
			try {
				sModel = getStructuredModelForRead(fCurrentDoc);
				if (sModel != null) {
					// now compare nodes
					IndexedRegion rootRegion = sModel.getIndexedRegion(root.getOffset());
					IndexedRegion possRegion = sModel.getIndexedRegion(possible.getOffset());
					if (rootRegion != null && possRegion != null) {
						int rootStart = rootRegion.getStartOffset();
						int possStart = possRegion.getStartOffset();
						// first just check if rootregion starts before
						// possregion
						if (rootStart <= possStart) {
							// check if possregion is inside rootregion
							outer = _getOuterRegion(root, possible, sModel, rootStart, possStart);
						}
						else {
							// otherwise if rootregion is inside possregion
							outer = _getOuterRegion(possible, root, sModel, possStart, rootStart);
						}
					}
				}
				
			} finally {
				if(sModel != null) {
					sModel.releaseFromRead();
				}
			}
		}
		return outer;
	}

	/**
	 * Assumes that when this method is called, region1's node start offset >=
	 * region2's node start offset. Determines if region1 contains region2 or
	 * vice versa. Returns region1 if:
	 * <ul>
	 * <li>region1's node region == region2's node region</li>
	 * <li>region1's node region contains region2's node region</li>
	 * </ul>
	 * Returns region2 if:
	 * <ul>
	 * <li>region1's node region and region2's node region starts at same
	 * offset but region2's node region is longer</li>
	 * </ul>
	 * Returns null otherwise.
	 * 
	 * @param region1
	 * @param region2
	 * @param sModel
	 * @param region1NodeStart
	 * @param region2NodeStart
	 * @return outer dirty region or null if none exists.
	 */
	private DirtyRegion _getOuterRegion(DirtyRegion region1, DirtyRegion region2, IStructuredModel sModel, int region1NodeStart, int region2NodeStart) {
		DirtyRegion outer = null;
		int region1NodeEnd = -1;
		int region2NodeEnd = -1;
		// then check if region1's end appears after
		// region2's end
		IndexedRegion region1EndNode = sModel.getIndexedRegion(region1.getOffset() + region1.getLength());
		if (region1EndNode == null) {
			// if no end, just assume region spans all the
			// way to the end so it includes other region
			outer = region1;
		}
		else {
			region1NodeEnd = region1EndNode.getEndOffset();
			IndexedRegion region2EndNode = sModel.getIndexedRegion(region2.getOffset() + region2.getLength());
			region2NodeEnd = region2EndNode != null ? region2EndNode.getEndOffset() : getDocument().getLength();
			if (region1NodeEnd >= region2NodeEnd) {
				// root contains or is equal to possible
				outer = region1;
			}
			else if (region1NodeStart == region2NodeStart && region2NodeEnd >= region1NodeEnd) {
				// possible contains root because they
				// both start at same place but possible
				// is longer
				outer = region2;
			}
		}
		if (DEBUG) {
			if (outer != null)
				System.out.println("checking if [" + region1NodeStart + ":" + region1NodeEnd + "] contains [" + region2NodeStart + ":" + region2NodeEnd + "] ... " + outer.toString()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
			else
				System.out.println("checking if [" + region1NodeStart + ":" + region1NodeEnd + "] contains [" + region2NodeStart + ":" + region2NodeEnd + "] ... NO CONTAIN"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
		}
		return outer;
	}

	/**
	 * We already know content type from when we created the model, so just
	 * use that.
	 */
	protected String getContentType(IDocument doc) {
		String contentTypeId = null;
		IStructuredModel sModel = null;
		try {
			sModel = getStructuredModelForRead(doc);
			if (sModel != null) {
				contentTypeId = sModel.getContentTypeIdentifier();
			}
		}
		finally {
			if (sModel != null)
				sModel.releaseFromRead();
		}
		return contentTypeId;
	}


	/**
	 * Remember to release model after use!!
	 * 
	 * @return
	 */
	private IStructuredModel getStructuredModelForRead(IDocument doc) {
		IStructuredModel sModel = null;
		if (doc != null && doc instanceof IStructuredDocument)
			sModel = StructuredModelManager.getModelManager().getModelForRead((IStructuredDocument) doc);
		return sModel;
	}

	protected void process(DirtyRegion dirtyRegion) {
		if (!isInstalled() || isInRewriteSession() || dirtyRegion == null || getDocument() == null)
			return;

		// unhook old lifecycle listener
		if(fCurrentDoc != null) {
			IStructuredModel sModel = null;
			try {
				sModel = getStructuredModelForRead(fCurrentDoc);
				
				// use structured model to determine area to process
				if (sModel != null) {
					int start = dirtyRegion.getOffset();
					int end = start + dirtyRegion.getLength();
					IndexedRegion irStart = sModel.getIndexedRegion(start);
					IndexedRegion irEnd = sModel.getIndexedRegion(end);

					if (irStart != null) {
						start = Math.min(start, irStart.getStartOffset());
					}
					if (irEnd != null) {
						end = Math.max(end, irEnd.getEndOffset());
					}
					super.process(createDirtyRegion(start, end - start, DirtyRegion.INSERT));
				} else {
					super.process(dirtyRegion);
				}
			} finally {
				if(sModel != null) {
					sModel.releaseFromRead();
				}
			}
		} else {
			super.process(dirtyRegion);
		}
	}

	/**
	 * Reinitializes listeners and sets new document onall strategies.
	 * 
	 * @see org.eclipse.jface.text.reconciler.AbstractReconciler#reconcilerDocumentChanged(IDocument)
	 */
	protected void reconcilerDocumentChanged(IDocument newDocument) {
		setDocument(newDocument);
	}

	public void setDocument(IDocument newDocument) {
		// unhook old lifecycle listener
		if(fCurrentDoc != null) {
			IStructuredModel oldModel = null;
			try {
				oldModel = getStructuredModelForRead(fCurrentDoc);
				if(oldModel != null) {
					oldModel.removeModelLifecycleListener(fLifeCycleListener);
				}
			} finally {
				if(oldModel != null) {
					oldModel.releaseFromRead();
				}
			}
		}
		
		//set the new document
		super.setDocument(newDocument);
		fCurrentDoc = newDocument;
		
		// add new lifecycle listener
		if (newDocument != null) {
			IStructuredModel newModel = null;
			try {
				newModel = getStructuredModelForRead(newDocument);
				if(newModel != null) {
					newModel.addModelLifecycleListener(fLifeCycleListener);
				}
			} finally {
				if(newModel != null) {
					newModel.releaseFromRead();
				}
			}
		}
	}
}
