/*******************************************************************************
 * Copyright (c) 2004 Actuate Corporation.
 * 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:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/
package org.eclipse.birt.data.engine.impl.document;

/**
 * Provide function to get the information of row index etc.
 */
public class SubQueryIndexUtil
{
	private int[] oldParentGroupInfo;
	private int[] newParentGroupInfo;
	private int[] validRowIndex;
	
	/**
	 * 
	 * @param oldParentGroupInfo
	 * @param newParentGroupInfo
	 * @param validRowIndex
	 */
	public SubQueryIndexUtil( int[] oldParentGroupInfo, int[] newParentGroupInfo,
			int[] validRowIndex )
	{
		this.oldParentGroupInfo = oldParentGroupInfo;
		this.newParentGroupInfo = newParentGroupInfo;
		this.validRowIndex = validRowIndex;
	}
	
	/**
	 * Get the index of group instance the currParentIndex stays in.
	 * 
	 * @param currParentIndex
	 * @return
	 */
	public int getOldGroupInstanceIndex( int currParentIndex )
	{
		assert currParentIndex >= 0 && currParentIndex < this.validRowIndex.length;
		
		for ( int i = 0; i < this.oldParentGroupInfo.length - 1; i = i + 2 )
		{
			if ( this.validRowIndex[currParentIndex] >= this.oldParentGroupInfo[i]
					&& ( this.validRowIndex[currParentIndex] < this.oldParentGroupInfo[i + 1] || this.oldParentGroupInfo[i + 1] < 0 ) )
			{
				return i/2;
			}
		}
		return -1;
	}
	/**
	 * Return the index of rows that should be kept in subquery.
	 * 
	 * @param currParentIndex
	 * @return
	 */
	public int[] getRowOffsetOfSubQuery( int currParentIndex )
	{
		int[] validIndex = null;

		int start = 0;
		int end = 0;

		int rowIndex = currParentIndex;
		
		/*		for ( int i = 0; i < this.validRowIndex.length; i++ )
		{
			if ( this.validRowIndex[i] == currParentIndex )
			{
				rowIndex = i;
				break;
			}
		}*/

		//Find group instance boundary.
		for ( int i = 0; i < this.newParentGroupInfo.length - 1; i = i + 2 )
		{
			if ( rowIndex >= this.newParentGroupInfo[i]
					&& rowIndex < this.newParentGroupInfo[i + 1] )
			{
				start = this.newParentGroupInfo[i];
				end = this.newParentGroupInfo[i + 1];
				break;
			}
		}

		validIndex = new int[end - start];

		for ( int i = 0; i < validIndex.length; i++ )
		{
			validIndex[i] = this.validRowIndex[i + start];
		}

		//get the adjustment of index in subquery.
		int dec = 0;
		for ( int i = 0; i < this.oldParentGroupInfo.length - 1; i = i + 2 )
		{
			if ( validIndex[0] >= this.oldParentGroupInfo[i]
					&& ( validIndex[0] < this.oldParentGroupInfo[i + 1] || this.oldParentGroupInfo[i + 1] < 0 ) )
			{
				dec = this.oldParentGroupInfo[i];
				break;
			}
		}
		
		//adjust the index of subquery.
		for ( int i = 0; i < validIndex.length; i++ )
		{
			validIndex[i] = validIndex[i] - dec;
		}

		return validIndex;
	}
	
	/**
	 * @param
	 * @return
	 */
	public int getGroupIndex( int currIndex )
	{
		assert this.newParentGroupInfo != null
				&& this.newParentGroupInfo.length % 2 == 0;

		for ( int i = 0; i < this.newParentGroupInfo.length; i += 2 )
		{
			if ( currIndex >= this.newParentGroupInfo[i]
					&& ( currIndex < this.newParentGroupInfo[i + 1] || this.newParentGroupInfo[i + 1] < 0 ) )
			{
				return i / 2;
			}
		}
		return -1;
	}

	/**
	 * @param
	 * @return
	 */
	public int[] getGroupStartAndEndIndex( int currIndex )
	{
		assert this.newParentGroupInfo != null
				&& this.newParentGroupInfo.length % 2 == 0;

		for ( int i = 0; i < this.newParentGroupInfo.length; i += 2 )
		{
			if ( currIndex >= this.newParentGroupInfo[i]
					&& ( currIndex < this.newParentGroupInfo[i + 1] || this.newParentGroupInfo[i + 1] < 0 ) )
			{
				return new int[]{
						this.newParentGroupInfo[i],
						this.newParentGroupInfo[i + 1]
				};
			}
		}
		return null;
	}
	
}
