package net.sf.jasperreports.engine.base;

import net.sf.jasperreports.engine.JRCommonElement;
import net.sf.jasperreports.engine.JRElement;
import net.sf.jasperreports.engine.JRExpression;
import net.sf.jasperreports.engine.JRExpressionCollector;
import net.sf.jasperreports.engine.JRSubreport;
import net.sf.jasperreports.engine.JRSubreportParameter;
import net.sf.jasperreports.engine.JRSubreportReturnValue;
import net.sf.jasperreports.engine.JRVisitor;
import net.sf.jasperreports.engine.util.JRStyleResolver;

public class JRBaseSubreport extends JRBaseElement implements JRSubreport {
  private static final long serialVersionUID = 10200L;
  
  public static final String PROPERTY_USING_CACHE = "usingCache";
  
  protected Boolean isUsingCache = null;
  
  protected JRExpression parametersMapExpression = null;
  
  protected JRSubreportParameter[] parameters = null;
  
  protected JRExpression connectionExpression = null;
  
  protected JRExpression dataSourceExpression = null;
  
  protected JRExpression expression = null;
  
  protected JRSubreportReturnValue[] returnValues = null;
  
  public byte getMode() {
    return JRStyleResolver.getMode((JRCommonElement)this, (byte)2);
  }
  
  protected JRBaseSubreport(JRSubreport subreport, JRBaseObjectFactory factory) {
    super((JRElement)subreport, factory);
    this.isUsingCache = subreport.isOwnUsingCache();
    this.parametersMapExpression = factory.getExpression(subreport.getParametersMapExpression());
    JRSubreportParameter[] jrSubreportParameters = subreport.getParameters();
    if (jrSubreportParameters != null && jrSubreportParameters.length > 0) {
      this.parameters = new JRSubreportParameter[jrSubreportParameters.length];
      for (int i = 0; i < this.parameters.length; i++)
        this.parameters[i] = factory.getSubreportParameter(jrSubreportParameters[i]); 
    } 
    this.connectionExpression = factory.getExpression(subreport.getConnectionExpression());
    this.dataSourceExpression = factory.getExpression(subreport.getDataSourceExpression());
    JRSubreportReturnValue[] subrepReturnValues = subreport.getReturnValues();
    if (subrepReturnValues != null && subrepReturnValues.length > 0) {
      this.returnValues = new JRSubreportReturnValue[subrepReturnValues.length];
      for (int i = 0; i < subrepReturnValues.length; i++)
        this.returnValues[i] = factory.getSubreportReturnValue(subrepReturnValues[i]); 
    } 
    this.expression = factory.getExpression(subreport.getExpression());
  }
  
  public boolean isUsingCache() {
    if (this.isUsingCache == null) {
      JRExpression subreportExpression = getExpression();
      if (subreportExpression != null)
        return String.class.getName().equals(subreportExpression.getValueClassName()); 
      return true;
    } 
    return this.isUsingCache.booleanValue();
  }
  
  public void setUsingCache(boolean isUsingCache) {
    setUsingCache(isUsingCache ? Boolean.TRUE : Boolean.FALSE);
  }
  
  public JRExpression getParametersMapExpression() {
    return this.parametersMapExpression;
  }
  
  public JRSubreportParameter[] getParameters() {
    return this.parameters;
  }
  
  public JRExpression getConnectionExpression() {
    return this.connectionExpression;
  }
  
  public JRExpression getDataSourceExpression() {
    return this.dataSourceExpression;
  }
  
  public JRExpression getExpression() {
    return this.expression;
  }
  
  public void collectExpressions(JRExpressionCollector collector) {
    collector.collect(this);
  }
  
  public void visit(JRVisitor visitor) {
    visitor.visitSubreport(this);
  }
  
  public JRSubreportReturnValue[] getReturnValues() {
    return this.returnValues;
  }
  
  public Boolean isOwnUsingCache() {
    return this.isUsingCache;
  }
  
  public void setUsingCache(Boolean isUsingCache) {
    Object old = this.isUsingCache;
    this.isUsingCache = isUsingCache;
    getEventSupport().firePropertyChange("usingCache", old, this.isUsingCache);
  }
  
  public Object clone() {
    JRBaseSubreport clone = (JRBaseSubreport)super.clone();
    if (this.parameters != null) {
      clone.parameters = new JRSubreportParameter[this.parameters.length];
      for (int i = 0; i < this.parameters.length; i++)
        clone.parameters[i] = (JRSubreportParameter)this.parameters[i].clone(); 
    } 
    if (this.returnValues != null) {
      clone.returnValues = new JRSubreportReturnValue[this.returnValues.length];
      for (int i = 0; i < this.returnValues.length; i++)
        clone.returnValues[i] = (JRSubreportReturnValue)this.returnValues[i].clone(); 
    } 
    if (this.parametersMapExpression != null)
      clone.parametersMapExpression = (JRExpression)this.parametersMapExpression.clone(); 
    if (this.connectionExpression != null)
      clone.connectionExpression = (JRExpression)this.connectionExpression.clone(); 
    if (this.dataSourceExpression != null)
      clone.dataSourceExpression = (JRExpression)this.dataSourceExpression.clone(); 
    if (this.expression != null)
      clone.expression = (JRExpression)this.expression.clone(); 
    return clone;
  }
}
