package net.sf.jasperreports.engine.design;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import net.sf.jasperreports.engine.JRDefaultStyleProvider;
import net.sf.jasperreports.engine.JRElementGroup;
import net.sf.jasperreports.engine.JRExpression;
import net.sf.jasperreports.engine.JRGroup;
import net.sf.jasperreports.engine.JRPropertyExpression;
import net.sf.jasperreports.engine.JRStyle;
import net.sf.jasperreports.engine.base.JRBaseElement;

public abstract class JRDesignElement extends JRBaseElement {
  private static final long serialVersionUID = 10200L;
  
  public static final String PROPERTY_ELEMENT_GROUP = "elementGroup";
  
  public static final String PROPERTY_HEIGHT = "height";
  
  public static final String PROPERTY_KEY = "key";
  
  public static final String PROPERTY_PRINT_WHEN_EXPRESSION = "printWhenExpression";
  
  public static final String PROPERTY_PRINT_WHEN_GROUP_CHANGES = "printWhenGroupChanges";
  
  public static final String PROPERTY_PARENT_STYLE = "parentStyle";
  
  public static final String PROPERTY_PARENT_STYLE_NAME_REFERENCE = "parentStyleNameReference";
  
  public static final String PROPERTY_Y = "y";
  
  public static final String PROPERTY_PROPERTY_EXPRESSIONS = "propertyExpressions";
  
  private List propertyExpressions = new ArrayList();
  
  protected JRDesignElement(JRDefaultStyleProvider defaultStyleProvider) {
    super(defaultStyleProvider);
    this.positionType = 2;
  }
  
  public void setKey(String key) {
    Object old = this.key;
    this.key = key;
    getEventSupport().firePropertyChange("key", old, this.key);
  }
  
  public void setY(int y) {
    int old = this.y;
    this.y = y;
    getEventSupport().firePropertyChange("y", old, this.y);
  }
  
  public void setHeight(int height) {
    int old = this.height;
    this.height = height;
    getEventSupport().firePropertyChange("height", old, this.height);
  }
  
  public void setPrintWhenExpression(JRExpression expression) {
    Object old = this.printWhenExpression;
    this.printWhenExpression = expression;
    getEventSupport().firePropertyChange("printWhenExpression", old, this.printWhenExpression);
  }
  
  public void setPrintWhenGroupChanges(JRGroup group) {
    Object old = this.printWhenGroupChanges;
    this.printWhenGroupChanges = group;
    getEventSupport().firePropertyChange("printWhenGroupChanges", old, this.printWhenGroupChanges);
  }
  
  public void setElementGroup(JRElementGroup elementGroup) {
    Object old = this.elementGroup;
    this.elementGroup = elementGroup;
    getEventSupport().firePropertyChange("elementGroup", old, this.elementGroup);
  }
  
  public void setStyle(JRStyle style) {
    Object old = this.parentStyle;
    this.parentStyle = style;
    getEventSupport().firePropertyChange("parentStyle", old, this.parentStyle);
  }
  
  public void setStyleNameReference(String styleName) {
    Object old = this.parentStyleNameReference;
    this.parentStyleNameReference = styleName;
    getEventSupport().firePropertyChange("parentStyleNameReference", old, this.parentStyleNameReference);
  }
  
  private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
    stream.defaultReadObject();
    if (this.propertyExpressions == null)
      this.propertyExpressions = new ArrayList(); 
  }
  
  public void addPropertyExpression(JRPropertyExpression propertyExpression) {
    this.propertyExpressions.add(propertyExpression);
    getEventSupport().fireCollectionElementAddedEvent("propertyExpressions", propertyExpression, this.propertyExpressions.size() - 1);
  }
  
  public void removePropertyExpression(JRPropertyExpression propertyExpression) {
    int idx = this.propertyExpressions.indexOf(propertyExpression);
    if (idx >= 0) {
      this.propertyExpressions.remove(idx);
      getEventSupport().fireCollectionElementRemovedEvent("propertyExpressions", propertyExpression, idx);
    } 
  }
  
  public JRPropertyExpression removePropertyExpression(String name) {
    JRPropertyExpression removed = null;
    for (ListIterator it = this.propertyExpressions.listIterator(); it.hasNext(); ) {
      JRPropertyExpression prop = it.next();
      if (name.equals(prop.getName())) {
        removed = prop;
        int idx = it.previousIndex();
        it.remove();
        getEventSupport().fireCollectionElementRemovedEvent("propertyExpressions", removed, idx);
        break;
      } 
    } 
    return removed;
  }
  
  public List getPropertyExpressionsList() {
    return this.propertyExpressions;
  }
  
  public JRPropertyExpression[] getPropertyExpressions() {
    JRPropertyExpression[] props;
    if (this.propertyExpressions.isEmpty()) {
      props = null;
    } else {
      props = (JRPropertyExpression[])this.propertyExpressions.toArray((Object[])new JRPropertyExpression[this.propertyExpressions.size()]);
    } 
    return props;
  }
}
