package net.sf.jasperreports.engine.base;

import java.awt.font.TextAttribute;
import java.io.Serializable;
import java.util.Map;
import net.sf.jasperreports.engine.JRDefaultFontProvider;
import net.sf.jasperreports.engine.JRDefaultStyleProvider;
import net.sf.jasperreports.engine.JRFont;
import net.sf.jasperreports.engine.JRReportFont;
import net.sf.jasperreports.engine.JRStyle;
import net.sf.jasperreports.engine.JRStyleContainer;
import net.sf.jasperreports.engine.design.events.JRChangeEventsSupport;
import net.sf.jasperreports.engine.design.events.JRPropertyChangeSupport;
import net.sf.jasperreports.engine.util.JRStyleResolver;
import net.sf.jasperreports.engine.util.JRTextAttribute;

public class JRBaseFont implements JRFont, Serializable, JRChangeEventsSupport {
  private static final long serialVersionUID = 10200L;
  
  public static final String PROPERTY_BOLD = "bold";
  
  public static final String PROPERTY_FONT_NAME = "fontName";
  
  public static final String PROPERTY_FONT_SIZE = "fontSize";
  
  public static final String PROPERTY_ITALIC = "italic";
  
  public static final String PROPERTY_PDF_EMBEDDED = "pdfEmbedded";
  
  public static final String PROPERTY_PDF_ENCODING = "pdfEncoding";
  
  public static final String PROPERTY_PDF_FONT_NAME = "pdfFontName";
  
  public static final String PROPERTY_REPORT_FONT = "reportFont";
  
  public static final String PROPERTY_STRIKE_THROUGH = "strikeThrough";
  
  public static final String PROPERTY_UNDERLINE = "underline";
  
  protected JRDefaultFontProvider defaultFontProvider = null;
  
  protected JRReportFont reportFont = null;
  
  protected JRStyleContainer styleContainer = null;
  
  protected String fontName = null;
  
  protected Boolean isBold = null;
  
  protected Boolean isItalic = null;
  
  protected Boolean isUnderline = null;
  
  protected Boolean isStrikeThrough = null;
  
  protected Integer fontSize = null;
  
  protected String pdfFontName = null;
  
  protected String pdfEncoding = null;
  
  protected Boolean isPdfEmbedded = null;
  
  private transient JRPropertyChangeSupport eventSupport;
  
  public JRBaseFont() {}
  
  public JRBaseFont(Map attributes) {
    String fontNameAttr = (String)attributes.get(TextAttribute.FAMILY);
    if (fontNameAttr != null)
      setFontName(fontNameAttr); 
    Object bold = attributes.get(TextAttribute.WEIGHT);
    if (bold != null)
      setBold(TextAttribute.WEIGHT_BOLD.equals(bold)); 
    Object italic = attributes.get(TextAttribute.POSTURE);
    if (italic != null)
      setItalic(TextAttribute.POSTURE_OBLIQUE.equals(italic)); 
    Float sizeAttr = (Float)attributes.get(TextAttribute.SIZE);
    if (sizeAttr != null)
      setFontSize(sizeAttr.intValue()); 
    Object underline = attributes.get(TextAttribute.UNDERLINE);
    if (underline != null)
      setUnderline(TextAttribute.UNDERLINE_ON.equals(underline)); 
    Object strikeThrough = attributes.get(TextAttribute.STRIKETHROUGH);
    if (strikeThrough != null)
      setStrikeThrough(TextAttribute.STRIKETHROUGH_ON.equals(strikeThrough)); 
    String pdfFontNameAttr = (String)attributes.get(JRTextAttribute.PDF_FONT_NAME);
    if (pdfFontNameAttr != null)
      setPdfFontName(pdfFontNameAttr); 
    String pdfEncodingAttr = (String)attributes.get(JRTextAttribute.PDF_ENCODING);
    if (pdfEncodingAttr != null)
      setPdfEncoding(pdfEncodingAttr); 
    Boolean isPdfEmbeddedAttr = (Boolean)attributes.get(JRTextAttribute.IS_PDF_EMBEDDED);
    if (isPdfEmbeddedAttr != null)
      setPdfEmbedded(isPdfEmbeddedAttr); 
  }
  
  protected JRBaseFont(JRDefaultFontProvider defaultFontProvider) {
    this.defaultFontProvider = defaultFontProvider;
  }
  
  public JRBaseFont(JRDefaultFontProvider defaultFontProvider, JRReportFont reportFont, JRFont font) {
    this(defaultFontProvider, reportFont, null, font);
  }
  
  public JRBaseFont(JRDefaultFontProvider defaultFontProvider, JRReportFont reportFont, JRStyleContainer styleContainer, JRFont font) {
    this.defaultFontProvider = defaultFontProvider;
    this.reportFont = reportFont;
    this.styleContainer = styleContainer;
    if (font != null) {
      this.fontName = font.getOwnFontName();
      this.isBold = font.isOwnBold();
      this.isItalic = font.isOwnItalic();
      this.isUnderline = font.isOwnUnderline();
      this.isStrikeThrough = font.isOwnStrikeThrough();
      this.fontSize = font.getOwnFontSize();
      this.pdfFontName = font.getOwnPdfFontName();
      this.pdfEncoding = font.getOwnPdfEncoding();
      this.isPdfEmbedded = font.isOwnPdfEmbedded();
    } 
  }
  
  public JRDefaultFontProvider getDefaultFontProvider() {
    return this.defaultFontProvider;
  }
  
  public JRDefaultStyleProvider getDefaultStyleProvider() {
    return (this.styleContainer == null) ? null : this.styleContainer.getDefaultStyleProvider();
  }
  
  public JRStyle getStyle() {
    return (this.styleContainer == null) ? null : this.styleContainer.getStyle();
  }
  
  public JRReportFont getReportFont() {
    return this.reportFont;
  }
  
  public void setReportFont(JRReportFont reportFont) {
    Object old = this.reportFont;
    this.reportFont = reportFont;
    getEventSupport().firePropertyChange("reportFont", old, this.reportFont);
  }
  
  public String getFontName() {
    return JRStyleResolver.getFontName(this);
  }
  
  public String getOwnFontName() {
    return this.fontName;
  }
  
  public void setFontName(String fontName) {
    Object old = this.fontName;
    this.fontName = fontName;
    getEventSupport().firePropertyChange("fontName", old, this.fontName);
  }
  
  public boolean isBold() {
    return JRStyleResolver.isBold(this);
  }
  
  public Boolean isOwnBold() {
    return this.isBold;
  }
  
  public void setBold(boolean isBold) {
    setBold(isBold ? Boolean.TRUE : Boolean.FALSE);
  }
  
  public void setBold(Boolean isBold) {
    Object old = this.isBold;
    this.isBold = isBold;
    getEventSupport().firePropertyChange("bold", old, this.isBold);
  }
  
  public boolean isItalic() {
    return JRStyleResolver.isItalic(this);
  }
  
  public Boolean isOwnItalic() {
    return this.isItalic;
  }
  
  public void setItalic(boolean isItalic) {
    setItalic(isItalic ? Boolean.TRUE : Boolean.FALSE);
  }
  
  public void setItalic(Boolean isItalic) {
    Object old = this.isItalic;
    this.isItalic = isItalic;
    getEventSupport().firePropertyChange("italic", old, this.isItalic);
  }
  
  public boolean isUnderline() {
    return JRStyleResolver.isUnderline(this);
  }
  
  public Boolean isOwnUnderline() {
    return this.isUnderline;
  }
  
  public void setUnderline(boolean isUnderline) {
    setUnderline(isUnderline ? Boolean.TRUE : Boolean.FALSE);
  }
  
  public void setUnderline(Boolean isUnderline) {
    Object old = this.isUnderline;
    this.isUnderline = isUnderline;
    getEventSupport().firePropertyChange("underline", old, this.isUnderline);
  }
  
  public boolean isStrikeThrough() {
    return JRStyleResolver.isStrikeThrough(this);
  }
  
  public Boolean isOwnStrikeThrough() {
    return this.isStrikeThrough;
  }
  
  public void setStrikeThrough(boolean isStrikeThrough) {
    setStrikeThrough(isStrikeThrough ? Boolean.TRUE : Boolean.FALSE);
  }
  
  public void setStrikeThrough(Boolean isStrikeThrough) {
    Object old = this.isStrikeThrough;
    this.isStrikeThrough = isStrikeThrough;
    getEventSupport().firePropertyChange("strikeThrough", old, this.isStrikeThrough);
  }
  
  public int getFontSize() {
    return JRStyleResolver.getFontSize(this);
  }
  
  public Integer getOwnFontSize() {
    return this.fontSize;
  }
  
  public void setFontSize(int fontSize) {
    setFontSize(new Integer(fontSize));
  }
  
  public void setFontSize(Integer fontSize) {
    Object old = this.fontSize;
    this.fontSize = fontSize;
    getEventSupport().firePropertyChange("fontSize", old, this.fontSize);
  }
  
  public int getSize() {
    return getFontSize();
  }
  
  public Integer getOwnSize() {
    return getOwnFontSize();
  }
  
  public void setSize(int size) {
    setFontSize(size);
  }
  
  public void setSize(Integer size) {
    setFontSize(size);
  }
  
  public String getPdfFontName() {
    return JRStyleResolver.getPdfFontName(this);
  }
  
  public String getOwnPdfFontName() {
    return this.pdfFontName;
  }
  
  public void setPdfFontName(String pdfFontName) {
    Object old = this.pdfFontName;
    this.pdfFontName = pdfFontName;
    getEventSupport().firePropertyChange("pdfFontName", old, this.pdfFontName);
  }
  
  public String getPdfEncoding() {
    return JRStyleResolver.getPdfEncoding(this);
  }
  
  public String getOwnPdfEncoding() {
    return this.pdfEncoding;
  }
  
  public void setPdfEncoding(String pdfEncoding) {
    Object old = this.pdfEncoding;
    this.pdfEncoding = pdfEncoding;
    getEventSupport().firePropertyChange("pdfEncoding", old, this.pdfEncoding);
  }
  
  public boolean isPdfEmbedded() {
    return JRStyleResolver.isPdfEmbedded(this);
  }
  
  public Boolean isOwnPdfEmbedded() {
    return this.isPdfEmbedded;
  }
  
  public void setPdfEmbedded(boolean isPdfEmbedded) {
    setPdfEmbedded(isPdfEmbedded ? Boolean.TRUE : Boolean.FALSE);
  }
  
  public void setPdfEmbedded(Boolean isPdfEmbedded) {
    Object old = this.isPdfEmbedded;
    this.isPdfEmbedded = isPdfEmbedded;
    getEventSupport().firePropertyChange("pdfEmbedded", old, this.isPdfEmbedded);
  }
  
  public String getStyleNameReference() {
    return (this.styleContainer == null) ? null : this.styleContainer.getStyleNameReference();
  }
  
  public JRPropertyChangeSupport getEventSupport() {
    synchronized (this) {
      if (this.eventSupport == null)
        this.eventSupport = new JRPropertyChangeSupport(this); 
    } 
    return this.eventSupport;
  }
}
