package net.sf.jasperreports.charts.fill;

import java.util.HashMap;
import java.util.Map;
import net.sf.jasperreports.charts.JRPieDataset;
import net.sf.jasperreports.charts.util.PieLabelGenerator;
import net.sf.jasperreports.engine.JRChartDataset;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExpression;
import net.sf.jasperreports.engine.JRExpressionCollector;
import net.sf.jasperreports.engine.JRHyperlink;
import net.sf.jasperreports.engine.JRHyperlinkHelper;
import net.sf.jasperreports.engine.JRPrintHyperlink;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.design.JRVerifier;
import net.sf.jasperreports.engine.fill.JRCalculator;
import net.sf.jasperreports.engine.fill.JRExpressionEvalException;
import net.sf.jasperreports.engine.fill.JRFillChartDataset;
import net.sf.jasperreports.engine.fill.JRFillExpressionEvaluator;
import net.sf.jasperreports.engine.fill.JRFillHyperlinkHelper;
import net.sf.jasperreports.engine.fill.JRFillObjectFactory;
import org.jfree.data.general.Dataset;
import org.jfree.data.general.DefaultPieDataset;

public class JRFillPieDataset extends JRFillChartDataset implements JRPieDataset {
  private DefaultPieDataset dataset = new DefaultPieDataset();
  
  private Map labels = null;
  
  private Comparable key = null;
  
  private Number value = null;
  
  private String label = null;
  
  private Map sectionHyperlinks;
  
  private JRPrintHyperlink sectionHyperlink;
  
  public JRFillPieDataset(JRPieDataset pieDataset, JRFillObjectFactory factory) {
    super((JRChartDataset)pieDataset, factory);
  }
  
  public JRExpression getKeyExpression() {
    return ((JRPieDataset)this.parent).getKeyExpression();
  }
  
  public JRExpression getValueExpression() {
    return ((JRPieDataset)this.parent).getValueExpression();
  }
  
  public JRExpression getLabelExpression() {
    return ((JRPieDataset)this.parent).getLabelExpression();
  }
  
  protected void customInitialize() {
    this.dataset = new DefaultPieDataset();
    this.labels = new HashMap();
    this.sectionHyperlinks = new HashMap();
  }
  
  protected void customEvaluate(JRCalculator calculator) throws JRExpressionEvalException {
    this.key = (Comparable)calculator.evaluate(getKeyExpression());
    this.value = (Number)calculator.evaluate(getValueExpression());
    this.label = (String)calculator.evaluate(getLabelExpression());
    if (hasSectionHyperlinks())
      evaluateSectionHyperlink(calculator); 
  }
  
  protected void evaluateSectionHyperlink(JRCalculator calculator) throws JRExpressionEvalException {
    try {
      this.sectionHyperlink = JRFillHyperlinkHelper.evaluateHyperlink(getSectionHyperlink(), (JRFillExpressionEvaluator)calculator, (byte)3);
    } catch (JRExpressionEvalException e) {
      throw e;
    } catch (JRException e) {
      throw new JRRuntimeException(e);
    } 
  }
  
  protected void customIncrement() {
    this.dataset.setValue(this.key, this.value);
    this.labels.put(this.key, this.label);
    if (hasSectionHyperlinks())
      this.sectionHyperlinks.put(this.key, this.sectionHyperlink); 
  }
  
  public Dataset getCustomDataset() {
    return (Dataset)this.dataset;
  }
  
  public byte getDatasetType() {
    return 1;
  }
  
  public PieLabelGenerator getLabelGenerator() {
    return (getLabelExpression() == null) ? null : new PieLabelGenerator(this.labels);
  }
  
  public void collectExpressions(JRExpressionCollector collector) {
    collector.collect(this);
  }
  
  public JRHyperlink getSectionHyperlink() {
    return ((JRPieDataset)this.parent).getSectionHyperlink();
  }
  
  public boolean hasSectionHyperlinks() {
    return !JRHyperlinkHelper.isEmpty(getSectionHyperlink());
  }
  
  public Map getSectionHyperlinks() {
    return this.sectionHyperlinks;
  }
  
  public void validate(JRVerifier verifier) {
    verifier.verify(this);
  }
}
