/*******************************************************************************
 * Copyright (c) 2001, 2004 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.xml.ui.reconcile;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.reconciler.IReconcileResult;
import org.eclipse.wst.sse.core.INodeNotifier;
import org.eclipse.wst.sse.core.IndexedRegion;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.rules.StructuredTextPartitioner;
import org.eclipse.wst.sse.ui.StructuredTextReconciler;
import org.eclipse.wst.sse.ui.internal.reconcile.IReconcileStepAdapter;
import org.eclipse.wst.sse.ui.internal.reconcile.ReconcileAnnotationKey;
import org.eclipse.wst.sse.ui.internal.reconcile.StructuredReconcileStep;
import org.eclipse.wst.xml.ui.internal.Logger;


/**
 * This reconcile step is an adapter on the IStructuredModel. Validation is
 * triggered from StructuredDocumentEvents
 * 
 * @deprecated moving toward reconcileValidator extension point
 *  
 * @author pavery
 */
public class AbstractReconcileStepAdapter implements IReconcileStepAdapter {

	protected static final IReconcileResult[] EMPTY_RECONCILE_RESULT_SET = new IReconcileResult[0];
	protected List fDirtyElements = new ArrayList();
	private StructuredReconcileStep fParentStep = null;
	private HashSet fPartitionTypes = null;

	public AbstractReconcileStepAdapter() {
		super();
		fPartitionTypes = new HashSet();
	}

	public ReconcileAnnotationKey createKey(IStructuredDocumentRegion sdRegion, int scope) {
		ITypedRegion tr = null;
		if (!sdRegion.isDeleted()) {
			try {
				tr = sdRegion.getParentDocument().getPartition(sdRegion.getStartOffset());
			} catch (BadLocationException e) {
				// do nothing but leave tr as null
				// probably due to changes made on another thread
			}
		}
		String partitionType = (tr != null) ? tr.getType() : StructuredTextPartitioner.ST_UNKNOWN_PARTITION;
		return createKey(partitionType, scope);
	}

	public ReconcileAnnotationKey createKey(String partitionType, int scope) {
		fPartitionTypes.add(partitionType);
		return new ReconcileAnnotationKey(getParentStep(), partitionType, scope);
	}

	public StructuredReconcileStep getParentStep() {
		return fParentStep;
	}

	public String[] getPartitionTypes() {
		String[] results = new String[fPartitionTypes.size()];
		System.arraycopy(fPartitionTypes.toArray(), 0, results, 0, results.length);
		return results;
	}


	public boolean isAdapterForType(Object type) {
		return type == IReconcileStepAdapter.class;
	}

	protected boolean isCanceled(IProgressMonitor monitor) {
		return monitor != null && monitor.isCanceled();
	}

	/**
	 * @param notifier
	 */
	public void markForReconciling(Object notifier) {
		synchronized (fDirtyElements) {
			// pa_TODO possible bottleneck
			if (!fDirtyElements.contains(notifier)) {
				Logger.trace(StructuredTextReconciler.TRACE_FILTER, "marking :" + notifier + ": for reconciling"); //$NON-NLS-1$ //$NON-NLS-2$
				fDirtyElements.add(notifier);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sed.model.INodeAdapter#notifyChanged(com.ibm.sed.model.INodeNotifier,
	 *      int, java.lang.Object, java.lang.Object, java.lang.Object, int)
	 */
	public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) {
		// Adapters are notified before the JFace Document events are sent to
		// the IReconciler
		markForReconciling(notifier);
	}

	public IReconcileResult[] reconcile(IProgressMonitor monitor, IndexedRegion xmlNode) {
		List workingElements = null;
		List results = new ArrayList();

		IReconcileResult[] temp = EMPTY_RECONCILE_RESULT_SET;
		synchronized (fDirtyElements) {
			if (fDirtyElements != null && fDirtyElements.size() > 0) {
				workingElements = new ArrayList();
				workingElements.addAll(0, fDirtyElements);
				fDirtyElements = new ArrayList();
			}
		}
		if (workingElements != null) {
			Iterator elements = workingElements.iterator();
			while (elements.hasNext() && !isCanceled(monitor)) {
				temp = reconcile(elements.next(), monitor);
				for (int i = 0; i < temp.length; i++)
					results.add(temp[i]);
			}
		}
		temp = new IReconcileResult[results.size()];
		System.arraycopy(results.toArray(), 0, temp, 0, results.size());
		return temp;
	}

	protected IReconcileResult[] reconcile(Object o, IProgressMonitor monitor) {
		return EMPTY_RECONCILE_RESULT_SET;
	}

	/**
	 * @see org.eclipse.wst.sse.ui.IReleasable#release()
	 */
	public void release() {
		// nothing to release
	}

	public void setParentStep(StructuredReconcileStep parentStep) {
		fParentStep = parentStep;
	}
}
