package net.sf.jasperreports.engine.fill;

import java.util.TimeZone;
import net.sf.jasperreports.engine.JRDatasetRun;
import net.sf.jasperreports.engine.JRElementDataset;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExpression;
import net.sf.jasperreports.engine.JRGroup;

public abstract class JRFillElementDataset implements JRElementDataset {
  protected JRElementDataset parent = null;
  
  private final JRBaseFiller filler;
  
  protected JRGroup resetGroup = null;
  
  protected JRGroup incrementGroup = null;
  
  private boolean isIncremented = true;
  
  protected JRFillDatasetRun datasetRun;
  
  private boolean increment = false;
  
  protected JRFillElementDataset(JRElementDataset dataset, JRFillObjectFactory factory) {
    factory.put(dataset, this);
    this.parent = dataset;
    this.filler = factory.getFiller();
    this.resetGroup = factory.getGroup(dataset.getResetGroup());
    this.incrementGroup = factory.getGroup(dataset.getIncrementGroup());
    this.datasetRun = factory.getDatasetRun(dataset.getDatasetRun());
  }
  
  public byte getResetType() {
    return this.parent.getResetType();
  }
  
  public byte getIncrementType() {
    return this.parent.getIncrementType();
  }
  
  public JRGroup getResetGroup() {
    return this.resetGroup;
  }
  
  public JRGroup getIncrementGroup() {
    return this.incrementGroup;
  }
  
  protected TimeZone getTimeZone() {
    return this.filler.getTimeZone();
  }
  
  protected void initialize() {
    customInitialize();
    this.isIncremented = false;
    this.increment = false;
  }
  
  protected void evaluate(JRCalculator calculator) throws JRExpressionEvalException {
    evaluateIncrementWhenExpression(calculator);
    if (this.increment)
      customEvaluate(calculator); 
    this.isIncremented = false;
  }
  
  protected void evaluateIncrementWhenExpression(JRCalculator calculator) throws JRExpressionEvalException {
    JRExpression incrementWhenExpression = getIncrementWhenExpression();
    if (incrementWhenExpression == null) {
      this.increment = true;
    } else {
      Boolean evaluated = (Boolean)calculator.evaluate(incrementWhenExpression);
      this.increment = (evaluated != null && evaluated.booleanValue());
    } 
  }
  
  protected void increment() {
    if (!this.isIncremented && this.increment)
      customIncrement(); 
    this.isIncremented = true;
  }
  
  protected abstract void customInitialize();
  
  protected abstract void customEvaluate(JRCalculator paramJRCalculator) throws JRExpressionEvalException;
  
  protected abstract void customIncrement();
  
  public JRDatasetRun getDatasetRun() {
    return this.datasetRun;
  }
  
  public void evaluateDatasetRun(byte evaluation) throws JRException {
    if (this.datasetRun != null)
      this.datasetRun.evaluate(this, evaluation); 
  }
  
  public JRFillDataset getInputDataset() {
    JRFillDataset inputDataset;
    if (this.datasetRun != null) {
      inputDataset = this.datasetRun.getDataset();
    } else {
      inputDataset = this.filler.mainDataset;
    } 
    return inputDataset;
  }
  
  public JRExpression getIncrementWhenExpression() {
    return this.parent.getIncrementWhenExpression();
  }
  
  public Object clone() {
    return null;
  }
}
