/*
 * @(#)MasterDetailGraphTag.java
 *
 * Copyright 2001-2002 by Oracle Corporation,
 * 500 Oracle Parkway, Redwood Shores, California, 94065, U.S.A.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information
 * of Oracle Corporation.
 */

package oracle.jbo.html.jsp.graph;

import java.util.ArrayList;
import oracle.dss.util.CubeDataDirector;
import oracle.dss.util.DataSource;
import oracle.dss.util.RelationalDataDirector;
import oracle.jbo.JboException;
import oracle.jbo.Row;
import oracle.jbo.RowSetIterator;


/**
 * Data source for the BI Graph bean. This binding should be used for
 * Graphs which require multiple values per marker. High-Low-Close stock
 * chart is one example, which needs three values per marker. 
 *
 * The detail table contains series data for the Graph. Each row represents one 
 * marker. The number of columns in the detail should match the number of 
 * values required for a marker. The detail table represents one 'series' 
 * of data in the Graph. 
 *
 * @see JUSingleTableGraphBinding
 */
public class MasterDetailGraphTag
	extends GraphModelBase
	implements DataSource
{
	protected BIBeanDataAccessAdapter mAdapter;

	protected String mChildAccessorName;

	protected int mNumberOfColumnValuesPerMarker;

	protected String mGroupLabelAttrName;

	protected ArrayList mChildSeries = new ArrayList(10);

	public MasterDetailGraphTag()
	{
	    init();
	}
    
    public void setChildAccessorName(String childName)
	{
	    mChildAccessorName = childName;
	}

	public String getChildAccessorName()
	{
		return mChildAccessorName;
	}


	// Implement DataSource interface
	public RelationalDataDirector createRelationalDataDirector() 
	{
 	    return mAdapter;
    }

    public CubeDataDirector createCubeDataDirector() 
    {
        return mAdapter;
    }


	void init()
    {
	     createAdapter();
    }

	protected oracle.dss.util.DataSource getGraphDataSource()
	{
	    return this;
	}
	
    protected void rsiChanged(RowSetIterator rsi, GraphTagBase graphTag)
    {
	    super.setRowSetIterator(rsi);
        
        mNumberOfColumnValuesPerMarker = super.getNumberOfColumnPerMarker(
                        graphTag.getGraphTypeAsInt());

	    updateValuesFromRows(getRowSetIterator().getAllRowsInRange()); 
    }

	protected void refreshView()
	{
	      super.refreshBIBeanAdapter(getAdapter());
    }


	protected GraphDataFromCol getSeries(int whichSeries)
	{
		GraphDataFromCol childSeries = (GraphDataFromCol)mChildSeries.get(whichSeries);

		if ( childSeries == null )
		{
			throw new JboException("Graph : Child series missing "); 
		}

		return childSeries;
	}

	// implement GraphModelBase abstract methods.

	protected String getColumnLabel(int i)
	{
	     GraphDataFromCol series = getSeries(0);

         return series.getColumnLabel(i);
	}

	protected int getColumnCount()
	{

	    GraphDataFromCol series = getSeries(0);

	    int rc = series.getColumnCount(); 
		 
        return rc;
	}


	protected String getRowLabel(int i)
	{
	    GraphDataFromCol series = getSeries(i);

    	return series.getSeriesLabel();

	}

	protected long getRowCount()
	{
	    return getRowSetIterator().getRowCountInRange();
	}


	protected Object getValue(int row, int col)
	{
		GraphDataFromCol series = getSeries(row);
    
	    return series.getColumnValue(col);
    }

	public void updateValuesFromRows(Row[] rows)
    { 
		for ( int i=0; i < rows.length; i++)
		{
			Object child = rows[i].getAttribute(mChildAccessorName);

			if (child instanceof RowSetIterator)
			{
				RowSetIterator childIter = (RowSetIterator)child;

				Object seriesLabel = rows[i].getAttribute(mSeriesLabelAttrName);

				if ( seriesLabel == null )
					seriesLabel = "";

				GraphDataFromCol childData = createGraphDataFromCol(childIter,
								mNumberOfColumnValuesPerMarker, 
								seriesLabel.toString(),
								mGroupLabelAttrName);
				mChildSeries.add(i, childData);
			}
			else
			{
				StringBuffer sbuf = new StringBuffer("RowSetIterator expected. Check the cardinality for the ViewLink accesor ");

				sbuf.append(mChildAccessorName);

				throw new JboException(sbuf.toString());
			}
		}

    }


   protected GraphDataFromCol createGraphDataFromCol(RowSetIterator rsi,
							int numberOfColumnValuesPerMarker,
							String seriesLabel,
							String groupLabelAttrName)
   {
	   rsi.setRangeSize( -1 );

	   return new GraphDataFromCol( rsi, numberOfColumnValuesPerMarker, 
			seriesLabel, groupLabelAttrName); 

   }

   // private methods
   private BIBeanDataAccessAdapter createAdapter()
   {
	   return new BIBeanDataAccessAdapter(this);
   }

   private BIBeanDataAccessAdapter getAdapter()
   {
	   return mAdapter;
   }


}

