/*******************************************************************************
 * Copyright (c) 2004, 2009 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.olap.driver;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.olap.OLAPException;

import org.eclipse.birt.data.engine.olap.cursor.DrilledAggregateResultSet;
import org.eclipse.birt.data.engine.olap.cursor.IRowDataAccessor;
import org.eclipse.birt.data.engine.olap.cursor.RowDataAccessor;
import org.eclipse.birt.data.engine.olap.cursor.RowDataAccessorService;
import org.eclipse.birt.data.engine.olap.data.api.IAggregationResultSet;
import org.eclipse.birt.data.engine.olap.query.view.BirtDimensionView;
import org.eclipse.birt.data.engine.olap.query.view.BirtEdgeView;

public class DrilledEdgeAxis implements IEdgeAxis
{

	private IAggregationResultSet mergedResultSet;
	private IRowDataAccessor dataAccessor;
	private DimensionAxis[] dimensionAxis;
	private RowDataAccessorService service;

	public DrilledEdgeAxis( IAggregationResultSet resultSet, List drillRs,
			BirtEdgeView view, List sortList, List drillFilters ) throws IOException
	{
		mergedResultSet = mergeBaseResultWithDrillResult( resultSet,
				drillRs,
				drillFilters );

		populateDimensionAxis( resultSet, view );
		service = new RowDataAccessorService( dimensionAxis, view );
		this.dataAccessor = new RowDataAccessor( service, mergedResultSet );

		for ( int i = 0; i < this.dimensionAxis.length; i++ )
		{
			this.dimensionAxis[i].setEdgeInfo( dataAccessor );
		}
	}

	private IAggregationResultSet mergeBaseResultWithDrillResult(
			IAggregationResultSet resultSet, List drillRs, List drills )
			throws IOException
	{
		return new DrilledAggregateResultSet( resultSet, drillRs, drills );
	}

	/**
	 * 
	 * @param rs
	 * @param view
	 * @param isCalculatedMember
	 * @throws OLAPException
	 * @throws IOException
	 */
	private void populateDimensionAxis( IAggregationResultSet rs,
			BirtEdgeView view ) throws IOException
	{

		List dimensionAxisList = new ArrayList( );
		int index = -1, levelIndex = -1;

		levelIndex = index = 0;
		for ( int i = 0; i < view.getDimensionViews( ).size( ); i++ )
		{
			BirtDimensionView dv = (BirtDimensionView) ( view.getDimensionViews( ).get( i ) );
			Iterator levelIter = dv.getMemberSelection( ).iterator( );

			while ( levelIter.hasNext( ) )
			{
				levelIter.next( );
				DimensionAxis axis = new DimensionAxis( this,
						mergedResultSet,
						index,
						levelIndex );
				index++;
				levelIndex++;
				dimensionAxisList.add( axis );
			}
		}

		this.dimensionAxis = new DimensionAxis[dimensionAxisList.size( )];
		for ( int i = 0; i < dimensionAxisList.size( ); i++ )
		{
			this.dimensionAxis[i] = (DimensionAxis) dimensionAxisList.get( i );
		}
	}
	
	public IRowDataAccessor getRowDataAccessor( )
	{
		return dataAccessor;
	}

	public DimensionAxis[] getAllDimensionAxis( )
	{
		return dimensionAxis;
	}

	public DimensionAxis getDimensionAxis( int index )
	{
		return dimensionAxis[index];
	}

	public IAggregationResultSet getQueryResultSet( )
	{
		return mergedResultSet;
	}

	public void populateEdgeInfo( boolean isPage ) throws OLAPException
	{
		if ( this.dataAccessor != null )
			try
			{
				this.dataAccessor.initialize( isPage );
			}
			catch ( IOException e )
			{
				throw new OLAPException( e.getLocalizedMessage( ) );
			}
	}
}
