package net.sf.jasperreports.engine.base;

import java.io.Serializable;
import net.sf.jasperreports.engine.JRExpression;
import net.sf.jasperreports.engine.JRGroup;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.JRVariable;
import net.sf.jasperreports.engine.util.JRClassLoader;

public class JRBaseVariable implements JRVariable, Serializable {
  private static final long serialVersionUID = 10200L;
  
  protected String name = null;
  
  protected String valueClassName = String.class.getName();
  
  protected String valueClassRealName = null;
  
  protected String incrementerFactoryClassName = null;
  
  protected String incrementerFactoryClassRealName = null;
  
  protected byte resetType = 1;
  
  protected byte incrementType = 5;
  
  protected byte calculation = 0;
  
  protected boolean isSystemDefined = false;
  
  protected transient Class valueClass = null;
  
  protected transient Class incrementerFactoryClass = null;
  
  protected JRExpression expression = null;
  
  protected JRExpression initialValueExpression = null;
  
  protected JRGroup resetGroup = null;
  
  protected JRGroup incrementGroup = null;
  
  protected JRBaseVariable(JRVariable variable, JRBaseObjectFactory factory) {
    factory.put(variable, this);
    this.name = variable.getName();
    this.valueClassName = variable.getValueClassName();
    this.incrementerFactoryClassName = variable.getIncrementerFactoryClassName();
    this.resetType = variable.getResetType();
    this.incrementType = variable.getIncrementType();
    this.calculation = variable.getCalculation();
    this.isSystemDefined = variable.isSystemDefined();
    this.expression = factory.getExpression(variable.getExpression());
    this.initialValueExpression = factory.getExpression(variable.getInitialValueExpression());
    this.resetGroup = factory.getGroup(variable.getResetGroup());
    this.incrementGroup = factory.getGroup(variable.getIncrementGroup());
  }
  
  public String getName() {
    return this.name;
  }
  
  public Class getValueClass() {
    if (this.valueClass == null) {
      String className = getValueClassRealName();
      if (className != null)
        try {
          this.valueClass = JRClassLoader.loadClassForName(className);
        } catch (ClassNotFoundException e) {
          throw new JRRuntimeException(e);
        }  
    } 
    return this.valueClass;
  }
  
  public String getValueClassName() {
    return this.valueClassName;
  }
  
  private String getValueClassRealName() {
    if (this.valueClassRealName == null)
      this.valueClassRealName = JRClassLoader.getClassRealName(this.valueClassName); 
    return this.valueClassRealName;
  }
  
  public Class getIncrementerFactoryClass() {
    if (this.incrementerFactoryClass == null) {
      String className = getIncrementerFactoryClassRealName();
      if (className != null)
        try {
          this.incrementerFactoryClass = JRClassLoader.loadClassForName(className);
        } catch (ClassNotFoundException e) {
          throw new JRRuntimeException(e);
        }  
    } 
    return this.incrementerFactoryClass;
  }
  
  public String getIncrementerFactoryClassName() {
    return this.incrementerFactoryClassName;
  }
  
  private String getIncrementerFactoryClassRealName() {
    if (this.incrementerFactoryClassRealName == null)
      this.incrementerFactoryClassRealName = JRClassLoader.getClassRealName(this.incrementerFactoryClassName); 
    return this.incrementerFactoryClassRealName;
  }
  
  public byte getResetType() {
    return this.resetType;
  }
  
  public byte getIncrementType() {
    return this.incrementType;
  }
  
  public byte getCalculation() {
    return this.calculation;
  }
  
  public boolean isSystemDefined() {
    return this.isSystemDefined;
  }
  
  public JRExpression getExpression() {
    return this.expression;
  }
  
  public JRExpression getInitialValueExpression() {
    return this.initialValueExpression;
  }
  
  public JRGroup getResetGroup() {
    return this.resetGroup;
  }
  
  public JRGroup getIncrementGroup() {
    return this.incrementGroup;
  }
  
  public Object clone() {
    JRBaseVariable clone = null;
    try {
      clone = (JRBaseVariable)super.clone();
    } catch (CloneNotSupportedException e) {
      throw new JRRuntimeException(e);
    } 
    if (this.expression != null)
      clone.expression = (JRExpression)this.expression.clone(); 
    if (this.initialValueExpression != null)
      clone.initialValueExpression = (JRExpression)this.initialValueExpression.clone(); 
    return clone;
  }
  
  protected JRBaseVariable() {}
}
