/***************************************************************************************************
 * Copyright (c) 2003, 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
 **************************************************************************************************/
/*
 * Created on Sep 21, 2003
 *  
 */
package org.eclipse.wst.common.internal.emf.resource;

import org.eclipse.emf.ecore.EObject;


/*
 * Translator filters can be used to differentiate between Object and Attribute Translators without
 * breaking them out into seperate data structures. The Filter will rely on the underlying data
 * structure used to store the children of the given Translator.
 * 
 * getNextChild() will return null when no other translators of the given genre are available.
 * 
 * The processing hints which are created and then passed to getNext*Translator() store information
 * that needs to be persisted between calls. The createProcessingHints() will create a properly
 * initialized array. The constants NEXT_START_HINT_INDX and MODE_HINT_INDX provide pointers into
 * the array for the NEXT_START position and the proper mode to operate in
 * (STANDARD_TRANSLATORS_MODE or
 *  
 */
public abstract class TranslatorFilter {

	protected final Translator translator;
	protected final int version;

	public static final int NEXT_START_HINT_INDX = 0;
	public static final int MODE_HINT_INDX = 1;

	public static final int STANDARD_TRANSLATORS_MODE = 0;
	public static final int VARIABLE_TRANSLATORS_MODE = 1;

	/*
	 * These TranslatorFilters are used in a stateless mode. Only their scanNextTranslator() methods
	 * will be invoked
	 */
	private static final TranslatorFilter objectTranslatorFilter = new ObjectTranslatorFilter(null, -1);
	private static final TranslatorFilter attributeTranslatorFilter = new AttributeTranslatorFilter(null, -1);


	protected int mode = STANDARD_TRANSLATORS_MODE;
	protected int index = -1;

	protected Translator cachedPeekAheadTranslator = null;

	public TranslatorFilter(Translator trans, int version) {
		this.translator = trans;
		this.version = version;
	}

	/**
	 * Calling peek twice will advance the current child
	 */
	public Translator peekNextChild(EObject target) {
		cachedPeekAheadTranslator = getNextChild(target);
		return cachedPeekAheadTranslator;
	}

	/**
	 * getNextChild() will return null when no other translators of the given genre are available.
	 */
	public Translator getNextChild(EObject target) {

		Translator result = null;
		if (cachedPeekAheadTranslator != null) {
			result = cachedPeekAheadTranslator;
			cachedPeekAheadTranslator = null;
			return result;
		}

		int found = 0;
		Translator children[] = null;
		switch (mode) {
			case STANDARD_TRANSLATORS_MODE :
				children = this.translator.getChildren(target, this.version);

				/* Look for the next Attribute Translator */
				found = scanNextTranslator(children, this.index);

				if (found >= 0) {
					/*
					 * If found, (1) update the result, (2) update the index so we can skip ahead on
					 * the next invocation (3) escape the VARIABLE_TRANSLATORS processing
					 */
					result = children[found];
					this.index = found;
					break;
				}
				/*
				 * Reset the index. DO NOT BREAK. Allow entry into VARIABLE_TRANSLATORS case
				 */
				this.index = -1;
				/*
				 * update the mode to VARIABLE_TRANSLATORS so we can skip to it directly next time
				 */
				this.mode = VARIABLE_TRANSLATORS_MODE;
			case VARIABLE_TRANSLATORS_MODE :
				children = this.translator.getVariableChildren(target, this.version);
				found = scanNextTranslator(children, this.index);
				if (found >= 0) {
					/*
					 * If found, (1) update the result, (2) update the index so we can skip ahead on
					 * the next invocation
					 */
					result = children[found];
					this.index = found;
				}

		}

		return result;
	}

	public static final int[] createProcessingHints() {
		return new int[]{-1, STANDARD_TRANSLATORS_MODE};
	}

	public static final Translator getNextAttributeTranslator(Translator translator, int startHint, int[] nextHint, EObject target, int version) {

		return TranslatorFilter.getNextChild(translator, startHint, nextHint, target, version, attributeTranslatorFilter);
	}

	public static final Translator getNextObjectTranslator(Translator translator, int startHint, int[] nextHint, EObject target, int version) {

		return TranslatorFilter.getNextChild(translator, startHint, nextHint, target, version, objectTranslatorFilter);
	}

	/**
	 * getNextChild() takes hints on where to begin in the children array of the given Translator.
	 * When it finds the translator, it will update the hints array with the start hint for the next
	 * invocation(hints[0]) and when necessary it will use update the mode (hints[1]) to either
	 * STANDARD_TRANSLATORS or VARIABLE_TRANSLATORS.
	 * 
	 * @param translator
	 * @param startHint
	 * @param hints
	 *            a two-element array: hints[0] will be updated with the next startHint and hints[1]
	 *            will be used to store the mode.
	 * @param target
	 * @param version
	 * @param translatorFilter
	 * @return
	 */
	public static final Translator getNextChild(Translator translator, int startHint, int[] hints, EObject target, int version, TranslatorFilter translatorFilter) {

		Translator result = null;

		int index = startHint;
		Translator children[] = null;

		switch (hints[MODE_HINT_INDX]) {
			case STANDARD_TRANSLATORS_MODE :
				children = translator.getChildren(target, version);
				if (children != null && startHint < children.length) {

					/* Look for the next Attribute Translator */
					index = translatorFilter.scanNextTranslator(children, index);

					if (index >= 0) {
						/*
						 * If found, (1) update the result, (2) update the index so we can skip
						 * ahead on the next invocation (3) escape the VARIABLE_TRANSLATORS
						 * processing
						 */
						result = children[index];
						break;
					}
					/*
					 * DO NOT BREAK we will default to VARIABLE TRANSLATORS MODE so we must reset
					 * the startHint appropriately
					 */
					startHint = -1;
				}

			case VARIABLE_TRANSLATORS_MODE :
				hints[MODE_HINT_INDX] = VARIABLE_TRANSLATORS_MODE;
				/*
				 * Reset the index.
				 */
				index = startHint;
				children = translator.getVariableChildren(target, version);
				if (children != null && children.length > 0 && startHint < children.length) {
					index = translatorFilter.scanNextTranslator(children, index);
					result = (index >= 0) ? children[index] : null;
				}
		}

		hints[NEXT_START_HINT_INDX] = (result == null && children != null) ? children.length : index;

		return result;
	}


	public abstract int scanNextTranslator(Translator[] children, int start);

	/**
	 * @return
	 */
	public int getIndex() {
		return index;
	}

	/**
	 * @return
	 */
	public int getMode() {
		return mode;
	}

}