package net.sf.jasperreports.engine.util;

import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class JRStyledText {
  private StringBuffer sbuffer = new StringBuffer();
  
  private List runs = new ArrayList();
  
  private AttributedString attributedString = null;
  
  private AttributedString awtAttributedString = null;
  
  private Map globalAttributes;
  
  public void append(String text) {
    this.sbuffer.append(text);
    this.attributedString = null;
    this.awtAttributedString = null;
  }
  
  public void addRun(Run run) {
    this.runs.add(run);
    this.attributedString = null;
    this.awtAttributedString = null;
  }
  
  public int length() {
    return this.sbuffer.length();
  }
  
  public String getText() {
    return this.sbuffer.toString();
  }
  
  public AttributedString getAttributedString() {
    if (this.attributedString == null) {
      this.attributedString = new AttributedString(this.sbuffer.toString());
      for (int i = this.runs.size() - 1; i >= 0; i--) {
        Run run = this.runs.get(i);
        if (run.startIndex != run.endIndex && run.attributes != null)
          this.attributedString.addAttributes(run.attributes, run.startIndex, run.endIndex); 
      } 
    } 
    return this.attributedString;
  }
  
  public AttributedString getAwtAttributedString() {
    if (this.awtAttributedString == null) {
      this.awtAttributedString = new AttributedString(this.sbuffer.toString());
      for (int i = this.runs.size() - 1; i >= 0; i--) {
        Run run = this.runs.get(i);
        if (run.startIndex != run.endIndex && run.attributes != null && !run.attributes.isEmpty()) {
          Iterator it = run.attributes.entrySet().iterator();
          while (it.hasNext()) {
            Map.Entry entry = it.next();
            AttributedCharacterIterator.Attribute attribute = (AttributedCharacterIterator.Attribute)entry.getKey();
            if (!(attribute instanceof JRTextAttribute)) {
              Object value = entry.getValue();
              this.awtAttributedString.addAttribute(attribute, value, run.startIndex, run.endIndex);
            } 
          } 
        } 
      } 
    } 
    return this.awtAttributedString;
  }
  
  public List getRuns() {
    return this.runs;
  }
  
  public static class Run {
    public Map attributes = null;
    
    public int startIndex = 0;
    
    public int endIndex = 0;
    
    public Run(Map attributes, int startIndex, int endIndex) {
      this.attributes = attributes;
      this.startIndex = startIndex;
      this.endIndex = endIndex;
    }
  }
  
  public void setGlobalAttributes(Map attributes) {
    this.globalAttributes = attributes;
    addRun(new Run(attributes, 0, length()));
  }
  
  public Map getGlobalAttributes() {
    return this.globalAttributes;
  }
}
