/*******************************************************************************
 * 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.core.internal.parser;



import org.eclipse.jface.text.BadLocationException;
import org.eclipse.wst.sse.core.events.StructuredDocumentEvent;
import org.eclipse.wst.sse.core.internal.text.TextRegionListImpl;
import org.eclipse.wst.sse.core.text.IStructuredDocument;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.ITextRegion;
import org.eclipse.wst.sse.core.text.ITextRegionCollection;
import org.eclipse.wst.sse.core.text.ITextRegionContainer;
import org.eclipse.wst.sse.core.text.ITextRegionList;
import org.eclipse.wst.xml.core.internal.Logger;


public class ContextRegionContainer implements ITextRegionContainer {
	protected int length;
	protected ITextRegionCollection parent;
	protected ITextRegionList regions;
	protected int start;
	protected int textLength;
	protected String type;

	public ContextRegionContainer() {
		super();
		regions = new TextRegionListImpl();

	}

	/**
	 * these "deep" parenting is not normal, but just in case.
	 */
	private IStructuredDocument _getParentDocument() {
		// go up enough parents to get to document
		ITextRegionCollection parent = getParent();
		while (!(parent instanceof IStructuredDocumentRegion)) {
			// would be an error not to be container, but
			// won't check for it now
			parent = ((ITextRegionContainer) parent).getParent();
		}
		return ((IStructuredDocumentRegion) parent).getParentDocument();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sed.structured.text.ITextRegion#adjust(int)
	 */
	public void adjust(int i) {

		start += i;
		// I erroneously added length and textLength
		// may want to rename this method to adjustStart
		//length += i;
		//textLength += i;

	}

	public void adjustLengthWith(int i) {
		length += i;
	}

	public void adjustStart(int i) {
		start += i;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sed.structured.text.ITextRegion#adjustTextLength(int)
	 */
	public void adjustTextLength(int i) {
		textLength += i;

	}

	public boolean containsOffset(int i) {

		return getStartOffset() <= i && i < getEndOffset();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sed.structured.text.ITextRegionCollection#containsOffset(com.ibm.sed.structured.text.ITextRegion,
	 *      int)
	 */
	public boolean containsOffset(ITextRegion containedRegion, int offset) {
		return getStartOffset(containedRegion) <= offset && offset < getEndOffset(containedRegion);
	}

	/**
	 * This method is just to equate positions. clients may (will probably)
	 * still need to make calls to equate regions, parent, etc.
	 */
	public void equatePositions(ITextRegion region) {
		start = region.getStart();
		length = region.getLength();
		textLength = region.getTextLength();
	}

	public int getEnd() {
		return start + length;
	}

	public int getEndOffset() {
		// our startOffset take into account our parent, and our start
		return getStartOffset() + getLength();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sed.structured.text.ITextRegionCollection#getEndOffset(com.ibm.sed.structured.text.ITextRegion)
	 */
	public int getEndOffset(ITextRegion containedRegion) {
		return getStartOffset(containedRegion) + containedRegion.getLength();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sed.structured.text.ITextRegionCollection#getFirstRegion()
	 */
	public ITextRegion getFirstRegion() {
		return getRegions().get(0);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sed.structured.text.ITextRegionCollection#getFullText()
	 */
	public String getFullText() {
		// CMVC > 252430, 245586
		// unit test > com.ibm.sed.tests.other.UnitTests.testDeepEmbeddedJSP3
		// this code modified on 6/25/03 (pa)

		//		String result = null;
		//		try {
		//			result = _getParentDocument().get(start, length);
		//		} catch (BadLocationException e) {
		//			Logger.logException("program error: unreachable exception", e);
		// //$NON-NLS-1$
		//		}
		//		return result;
		return getParent().getFullText(this);
	}

	public String getFullText(org.eclipse.wst.sse.core.text.ITextRegion aRegion) {
		// Must be proxied here since aRegion should always be a child of
		// *this* container and indexed from
		// this container's offset
		//	try {
		return parent.getFullText().substring(start + aRegion.getStart(), start + aRegion.getEnd());
		//} catch (Exception e) {
		//if (com.ibm.sed.util.Debug.debugStructuredDocument)
		//e.printStackTrace();
		//}
		//return "";//$NON-NLS-1$
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sed.structured.text.ITextRegionCollection#getLastRegion()
	 */
	public ITextRegion getLastRegion() {
		return getRegions().get(getRegions().size() - 1);
	}

	public int getLength() {
		return length;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sed.structured.text.ITextRegionCollection#getNumberOfRegions()
	 */
	public int getNumberOfRegions() {
		return getRegions().size();
	}

	public ITextRegionCollection getParent() {
		return parent;
	}

	/**
	 * The parameter offset refers to the overall offset in the document.
	 */
	public ITextRegion getRegionAtCharacterOffset(int offset) {
		ITextRegion result = null;
		if (regions != null) {
			// transform the requested offset to the "scale" that
			// regions are stored in, which are all relative to the
			// start point.
			//int transformedOffset = offset - getStartOffset();
			//
			int length = getRegions().size();
			for (int i = 0; i < length; i++) {
				ITextRegion region = getRegions().get(i);
				if (org.eclipse.wst.sse.core.util.Debug.debugStructuredDocument) {
					System.out.println("region(s) in IStructuredDocumentRegion::getRegionAtCharacterOffset: " + region); //$NON-NLS-1$
					System.out.println("       requested offset: " + offset); //$NON-NLS-1$
					//System.out.println(" transformedOffset: " +
					// transformedOffset); //$NON-NLS-1$
					System.out.println("       region start: " + region.getStart()); //$NON-NLS-1$
					System.out.println("       region end: " + region.getEnd()); //$NON-NLS-1$
					System.out.println("       region type: " + region.getType()); //$NON-NLS-1$
					System.out.println("       region class: " + region.getClass()); //$NON-NLS-1$

				}
				if ((getStartOffset(region) <= offset) && (offset < getEndOffset(region))) {
					result = region;
					break;
				}
			}
		}
		return result;
	}

	public ITextRegionList getRegions() {
		return regions;
	}

	public int getStart() {
		return start;
	}

	public int getStartOffset() {
		return getParent().getStartOffset() + getStart();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sed.structured.text.ITextRegionCollection#getStartOffset(com.ibm.sed.structured.text.ITextRegion)
	 */
	public int getStartOffset(ITextRegion containedRegion) {
		return getStartOffset() + containedRegion.getStart();
	}

	/**
	 * same as getFullText for this region type ... do we need to take white
	 * space off?
	 */

	public String getText() {
		String result = null;
		try {
			IStructuredDocument parentDocument = _getParentDocument();
			result = parentDocument.get(start, length);
		} catch (BadLocationException e) {
			Logger.logException("program error: unreachable exception", e); //$NON-NLS-1$
		}
		return result;
	}

	public String getText(org.eclipse.wst.sse.core.text.ITextRegion aRegion) {
		// Must be proxied here since aRegion should always be a child of
		// *this* container and indexed from
		// this container's offset
		//	com.ibm.sed.util.Assert.isTrue(regions.contains(aRegion));
		//try {
		return parent.getText().substring(start + aRegion.getStart(), start + aRegion.getTextEnd());
		//} catch (Exception e) {
		//if (com.ibm.sed.util.Debug.debugStructuredDocument)
		//com.ibm.sed.util.Logger.log(e);
		//}
		// return ""; //$NON-NLS-1$
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sed.structured.text.ITextRegion#getTextEnd()
	 */
	public int getTextEnd() {
		//		int result = 0;
		//		ITextRegion lastRegion = (ITextRegion) regions.get(regions.size() -
		// 1);
		//		result = getStartOffset(lastRegion) + lastRegion.getTextLength();
		//		return result;
		return start + textLength;
	}

	public int getTextEndOffset() {
		ITextRegion region = regions.get(regions.size() - 1);
		// our startOffset take into account our parent, and our start
		// (pa) 10/4 changed to be based on text end
		//           it used to return incorrect value for embedded region containers
		//

		// TODO CRITICAL -- need to re-work this work around, so doesn't
		// depend on XMLRegionContext
		//		// this is a workaround for 226823///////////
		//		for (int i = regions.size() - 1; i >= 0 && region.getType() ==
		// XMLRegionContext.WHITE_SPACE; i--)
		//			region = (ITextRegion) regions.get(i);
		//		/////////////////////////////////////////////

		return getStartOffset() + region.getTextEnd();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sed.structured.text.ITextRegionCollection#getTextEndOffset(com.ibm.sed.structured.text.ITextRegion)
	 */
	public int getTextEndOffset(ITextRegion containedRegion) {
		int result = 0;
		if (regions != null) {
			int length = getRegions().size();
			for (int i = 0; i < length; i++) {
				ITextRegion region = getRegions().get(i);
				if (region == containedRegion) {
					result = getStartOffset(region) + region.getTextEnd();
					break;
				}
			}
		}
		return result;
	}

	public int getTextLength() {
		return textLength;
	}

	public String getType() {
		return type;
	}

	public void setLength(int i) {
		length = i;
	}

	public void setParent(ITextRegionCollection parentRegion) {
		parent = parentRegion;
	}

	public void setRegions(ITextRegionList containedRegions) {
		regions = containedRegions;
	}

	public void setStart(int i) {
		start = i;
	}

	public void setTextLength(int i) {
		textLength = i;
	}

	public void setType(String string) {
		type = string;
	}

	public String toString() {
		String className = getClass().getName();
		String shortClassName = className.substring(className.lastIndexOf(".") + 1); //$NON-NLS-1$
		String result = "Container!!! " + shortClassName + "--> " + getType() + ": " + getStart() + "-" + getTextEnd() + (getTextEnd() != getEnd() ? ("/" + getEnd()) : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
		return result;
	}

	public StructuredDocumentEvent updateModel(Object requester, IStructuredDocumentRegion parent, String changes, int requestStart, int lengthToReplace) {
		org.eclipse.wst.sse.core.events.RegionChangedEvent result = null;
		// FUTURE_TO_DO: need to implement region level parsing in
		// ITextRegionContainer::updateModel
		// never being called?
		return result;
	}

}
