/*
 * Licensed Materials - Property of Perforce Software, Inc. 
 * © Copyright Perforce Software, Inc. 2014, 2021 
 * © Copyright IBM Corp. 2009, 2014
 * © Copyright ILOG 1996, 2009
 * All Rights Reserved.
 *
 * Note to U.S. Government Users Restricted Rights:
 * The Software and Documentation were developed at private expense and
 * are "Commercial Items" as that term is defined at 48 CFR 2.101,
 * consisting of "Commercial Computer Software" and
 * "Commercial Computer Software Documentation", as such terms are
 * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
 * as applicable.
 */
package imgmap;

import java.awt.Color;
import java.awt.Insets;
import java.util.Iterator;

import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.servlet.ServletContext;
import javax.swing.BorderFactory;

import org.xml.sax.InputSource;

import ilog.views.chart.IlvChart;
import ilog.views.chart.IlvChartLayout;
import ilog.views.chart.IlvChartRenderer;
import ilog.views.chart.IlvColor;
import ilog.views.chart.IlvLabelRenderer;
import ilog.views.chart.IlvLegend;
import ilog.views.chart.IlvLegendSeparator;
import ilog.views.chart.IlvStyle;
import ilog.views.chart.IlvValueFormat;
import ilog.views.chart.data.IlvDataSet;
import ilog.views.chart.data.xml.IlvXMLDataReader;
import ilog.views.chart.data.xml.IlvXMLDataSource;
import ilog.views.chart.faces.dhtml.IlvFacesChartImageMapGenerator;
import ilog.views.chart.faces.dhtml.interactor.IlvChartObjectSelectedFinder;
import ilog.views.chart.faces.servlet.IlvFacesChart;
import ilog.views.chart.faces.servlet.IlvFacesChartLegend;
import ilog.views.chart.graphic.IlvDataLabelAnnotation;
import ilog.views.chart.renderer.IlvPieChartRenderer;
import ilog.views.chart.renderer.IlvSinglePieRenderer;
import ilog.views.util.IlvResourceUtil;

/**
 * The bean of the image map sample.
 */
public class ImageMapBean {

  private IlvChart chart;

  private static IlvFacesChartImageMapGenerator imapGenerator = new ImageMapAreaGenerator();

  private static IlvChartObjectSelectedFinder finder = new ImageMapFinder();

  /**
   * Creates a new <code>ImageMapBean</code> instance.
   */
  public ImageMapBean() {
    chart = createChart();
  }

  /**
   * Creates the pie chart to display.
   * 
   * @return The Pie chart.
   */
  protected IlvChart createChart() {
    ServletContext context = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();

    // Create the IlvChart.
    IlvChart chart = new IlvFacesChart(IlvChart.PIE);
    chart.getChartArea().setMargins(new Insets(40, 40, 40, 40));
    chart.set3D(true);
    chart.get3DView().setDepth(10);
    chart.setAntiAliasing(true);
    chart.setAntiAliasingText(true);
    chart.setBackground(Color.white);
    chart.setOpaque(true);
    Color borderColor = new Color(153, 153, 204);
    chart.setBorder(BorderFactory.createLineBorder(borderColor, 2));
    // Set the format for y-value
    chart.setYValueFormat(0, new IlvValueFormat() {
      java.text.NumberFormat fmt = new java.text.DecimalFormat("##.0");

      Override
      public String formatValue(double value) {
        return fmt.format(value);
      }
    });

    // Initialize a new XML data source.
    IlvXMLDataSource ds = new IlvXMLDataSource();
    IlvXMLDataReader reader = new IlvXMLDataReader();
    // Register a custom IlvXMLPropertyReader subclass in order to read
    // href element.
    IlvXMLDataReader.registerPropertyReader(HREFPropertyReader.HREFS_TAG, new HREFPropertyReader());
    reader.setValidating(true);
    // Load the data.
    try {
      String url = context.getInitParameter("dataFile");
      InputSource inputsrc = new InputSource(context.getResource(url).openStream());
      // Bug with InputSource + custom EntityResolver : an URI needs to
      // be defined, even if not used later
      inputsrc.setSystemId("../");
      ds.load(inputsrc, reader);
    } catch (Exception e) {
      e.printStackTrace();
      String msg = IlvResourceUtil.getServerLocaleString(ImageMapBean.class, "notLoadFile");
      System.err.println(msg);
    }
    chart.setDataSource(ds);
    IlvPieChartRenderer r = (IlvPieChartRenderer) chart.getRenderer(0);
    Iterator<IlvDataSet> ite = ds.getDataSetIterator();
    while (ite.hasNext()) {
      IlvDataSet dataSet = ite.next();
      IlvSinglePieRenderer pie = r.getPie(dataSet);
      int count = dataSet.getDataCount();
      for (int i = 0; i < count; ++i) {
        IlvStyle style = pie.getSliceStyle(i);
        Color bg = style.getFillColor();
        bg = (bg == null) ? Color.white : IlvColor.brighter(bg);
        IlvLabelRenderer l = new IlvLabelRenderer(bg, Color.black);
        pie.setAnnotation(dataSet, i, new IlvDataLabelAnnotation(l));
      }
    }
    chart.getRenderer(0).setDataLabeling(IlvChartRenderer.PERCENT_LABEL);
    chart.getRenderer(0).setDataLabelLayout(IlvChartRenderer.OUTSIDE_LABEL_LAYOUT);
    IlvLegend legend = new IlvFacesChartLegend();
    legend.setBorder(new IlvLegendSeparator(borderColor, 2, 3, 1));
    chart.addLegend(legend, IlvChartLayout.WEST);
    return chart;
  }

  /**
   * Explodes the selected slice from the Pie.
   * 
   * @param event
   *          The value change event that contains the slice selected.
   */
  public void explode(ValueChangeEvent event) {
    Integer explodedIdx = (Integer) event.getNewValue();
    if (explodedIdx != null) {
      int explodedDs = explodedIdx.intValue();
      int count = chart.getDataSource().getDataSet(0).getDataCount();
      IlvSinglePieRenderer pie = (IlvSinglePieRenderer) ((IlvPieChartRenderer) chart.getRenderer(0)).getChild(0);
      for (int i = 0; i < count; ++i) {
        pie.setExploded(i, explodedDs == i);
      }
    }
  }

  /**
   * Returns the image map generator.
   * 
   * @return The image map generator.
   */
  public IlvFacesChartImageMapGenerator getImapGenerator() {
    return imapGenerator;
  }

  /**
   * Returns the chart to display.
   * 
   * @return The chart to display.
   */
  public IlvChart getChart() {
    return chart;
  }

  /**
   * Returns the finder that will return the value passed to the value change
   * event.
   * 
   * @return The finder.
   */
  public IlvChartObjectSelectedFinder getFinder() {
    return finder;
  }
}