package jreport.uds.javabean;
import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;
import java.util.Vector;

import jreport.uds.javabean.api.JavaBeanDataProvider;
import jreport.uds.javabean.exception.JavaBeanDataProviderException;

/*
 * Created on Jul 17, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */

/**
 * @author jennyw
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 * 
 * Need to use the following parameters
 * @SBeanProvider_BeanClsName - the Java class name for the Bean
 * @SBeanProvider_UseFakeData - if it is true, then the data fake data will be populated.
 * 
 */
public class SimpleBeanDataProvider implements JavaBeanDataProvider {

	private Vector data = null;
	private int currentRecord=-1;
	private String dataID = null;

	private String beanRecordClsName =  null;
	
	/**
	 * Init the data for the SimpleBeanDataProvider. 
	 * 
	 * Reading the following two properties from the props argument:
	 * - <b>SBeanProvider_BeanClsName</b>: This is the Java class name for the bean for each record
	 * - <b>SBeanProvider_UseFakeData: This value is null or true indicates that this data provider will populate fake data instead of real data.
	 * If this value is false, then the data provide will get the Vector of Object from DataCenter by the dataID .
	 */
	public void init(String dataID, Properties props) throws JavaBeanDataProviderException{
		
		this.dataID =dataID;
		
		beanRecordClsName = (String)props.get("SBeanProvider_BeanClsName");
		if( beanRecordClsName == null ||beanRecordClsName.trim().length()==0){
			throw new JavaBeanDataProviderException(null, "SBeanProvider_BeanClsName is not specified for the data provdider SimpleBeanDataProvider");
		}
		
		String useFakeData =(String) props.get("SBeanProvider_UseFakeData");
		if( useFakeData==null ||useFakeData.trim().equals("") || // no value set to the parameter 
				new Boolean(useFakeData).booleanValue()){ // value is set and it is true.
			try {
				populateData();
			} catch (Exception e) {
				UDSForJavaBeanLogger.debug(e);
				throw new JavaBeanDataProviderException(null,"Class "+beanRecordClsName+ " cannot be loaded or the Class cannot be populated. Please check your classpath.");
			}
		}else{
			try {
				data = (Vector)DataCenter.getData(dataID);
			} catch (DataCenterException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				throw new JavaBeanDataProviderException(e, e.getMessage());
			}		
		}
	}
	
	/* (non-Javadoc)
	 * @see JavaBeanDataProvider#getRootBean()
	 * Interface to return the Metadat(Java Bean Class) for each record object.
	 */
	public Class getMetadataJavaBean() throws ClassNotFoundException{
		return Class.forName(beanRecordClsName);		
	}

	/* (non-Javadoc)
	 * @see JavaBeanDataProvider#next()
	 * Callback method from JReport ResultSetForJavaBean to get next record object.
	 */
	public Object next() {
	
		if( currentRecord ==-1 && data != null && data.size()>0){
			currentRecord = 0;
			return data.elementAt(currentRecord);
		}else if(currentRecord != -1 && ( currentRecord < (data.size()-1))){
			currentRecord ++;
			return data.elementAt(currentRecord);
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see JavaBeanDataProvider#exit()
	 * Callback method from ResultSetForJavaBean when the resultset is release by jreport engine.
	 * This method here is used to remove the data from the data center by the dataID.
	 */
	public void exit() {
		if(!dataID.equals("")){
			DataCenter.removeData(dataID);
		}

	}
	
	private void populateData() throws ClassNotFoundException,IllegalArgumentException, InvocationTargetException, InstantiationException, IllegalAccessException, IntrospectionException{
		data = new Vector(2);
		
		System.out.println("Populating Data>>>");
		Class cls = Class.forName(beanRecordClsName);
		Object data1;
		data1 = cls.newInstance();
		FakeDataGeneratorForJavaBean.populate(data1, null, 10);
		data.addElement(data1);
		
		data1 = cls.newInstance();
		FakeDataGeneratorForJavaBean.populate(data1, null,10);
		data.addElement(data1);
	}
	
	/**
	 * check to see the the property is a collection property needs to return to the report 
	 * with ID to run sub-report
	 */
	public boolean requireDetails(String collectionPropName) {
				return false;
	}
	
	
	/* (non-Javadoc)
	 * @see jreport.uds.javabean.JavaBeanDataProvider#getMaxShareTimes(java.lang.String)
	 */
	public int getMaxShareTimes(String collectionPropName) {
		return 1;
	}

	/* (non-Javadoc)
	 * @see jreport.uds.javabean.JavaBeanDataProvider#getTimeoutForSubCollection(java.lang.String)
	 */
	public int getTimeoutForSubCollection(String collectionPropName) {
		return -1;
	}
}
