package net.sf.jasperreports.engine.fill;

import java.awt.Color;
import java.io.Serializable;
import java.util.Random;
import net.sf.jasperreports.engine.JRCommonElement;
import net.sf.jasperreports.engine.JRDefaultStyleProvider;
import net.sf.jasperreports.engine.JRElement;
import net.sf.jasperreports.engine.JROrigin;
import net.sf.jasperreports.engine.JRPropertiesHolder;
import net.sf.jasperreports.engine.JRPropertiesMap;
import net.sf.jasperreports.engine.JRStyle;
import net.sf.jasperreports.engine.util.JRStyleResolver;

public abstract class JRTemplateElement implements JRCommonElement, Serializable, JRPropertiesHolder {
  private static final long serialVersionUID = 10200L;
  
  private static final Random randomId = new Random();
  
  private String key;
  
  private Byte mode = null;
  
  private Color forecolor = null;
  
  private Color backcolor = null;
  
  protected JROrigin origin = null;
  
  protected JRDefaultStyleProvider defaultStyleProvider;
  
  protected JRStyle parentStyle = null;
  
  private final String id;
  
  private JRPropertiesMap propertiesMap;
  
  protected JRTemplateElement(JROrigin origin, JRDefaultStyleProvider defaultStyleProvider) {
    this.origin = origin;
    this.defaultStyleProvider = defaultStyleProvider;
    this.id = createId();
  }
  
  protected JRTemplateElement(JROrigin origin, JRElement element) {
    this.origin = origin;
    setElement(element);
    this.id = createId();
  }
  
  protected JRTemplateElement(String id) {
    this.id = id;
  }
  
  private String createId() {
    return System.identityHashCode(this) + "_" + System.currentTimeMillis() + "_" + randomId.nextInt();
  }
  
  protected void setElement(JRElement element) {
    this.parentStyle = element.getStyle();
    setKey(element.getKey());
    this.mode = element.getOwnMode();
    this.forecolor = element.getOwnForecolor();
    this.backcolor = element.getOwnBackcolor();
  }
  
  public JROrigin getOrigin() {
    return this.origin;
  }
  
  public JRDefaultStyleProvider getDefaultStyleProvider() {
    return this.defaultStyleProvider;
  }
  
  public JRStyle getStyle() {
    return this.parentStyle;
  }
  
  protected JRStyle getBaseStyle() {
    if (this.parentStyle != null)
      return this.parentStyle; 
    if (this.defaultStyleProvider != null)
      return this.defaultStyleProvider.getDefaultStyle(); 
    return null;
  }
  
  public byte getMode() {
    return JRStyleResolver.getMode(this, (byte)1);
  }
  
  public Byte getOwnMode() {
    return this.mode;
  }
  
  protected void setMode(byte mode) {
    this.mode = new Byte(mode);
  }
  
  protected void setMode(Byte mode) {
    this.mode = mode;
  }
  
  public Color getForecolor() {
    return JRStyleResolver.getForecolor(this);
  }
  
  public Color getOwnForecolor() {
    return this.forecolor;
  }
  
  protected void setForecolor(Color forecolor) {
    this.forecolor = forecolor;
  }
  
  public Color getBackcolor() {
    return JRStyleResolver.getBackcolor(this);
  }
  
  public Color getOwnBackcolor() {
    return this.backcolor;
  }
  
  protected void setBackcolor(Color backcolor) {
    this.backcolor = backcolor;
  }
  
  public String getId() {
    return this.id;
  }
  
  public String getKey() {
    return this.key;
  }
  
  public void setKey(String key) {
    this.key = key;
  }
  
  public String getStyleNameReference() {
    return null;
  }
  
  public synchronized boolean hasProperties() {
    return (this.propertiesMap != null && this.propertiesMap.hasProperties());
  }
  
  public synchronized JRPropertiesMap getPropertiesMap() {
    if (this.propertiesMap == null)
      this.propertiesMap = new JRPropertiesMap(); 
    return this.propertiesMap;
  }
  
  public JRPropertiesHolder getParentProperties() {
    return null;
  }
}
