/*
 * 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 hitmap;

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.graphic.IlvDataLabelAnnotation;
import ilog.views.chart.renderer.IlvPieChartRenderer;
import ilog.views.chart.renderer.IlvSinglePieRenderer;
import ilog.views.chart.servlet.IlvChartServletSupport;
import ilog.views.chart.servlet.IlvServletRequestParameters;
import ilog.views.util.IlvResourceUtil;

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

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.swing.BorderFactory;

import org.xml.sax.InputSource;

/**
 * An <code>IlvChartServletSupport</code> subclass that loads data from
 * an XML file. The XML file extends the chart DTD to add a custom <code>hrefs</code> element
 * to the property element in order to associate hyperlink references (hrefs)
 * to the data points of a series. These hrefs will be used as area attributes
 * of an Hitmap request.
 */
class ServletSupport extends IlvChartServletSupport {
  private IlvChart chart;

  /**
   * Creates a new <code>ServletSupport</code> object.
   * @param context The servlet context.
   */
  public ServletSupport(ServletConfig config) {
    ServletContext context = config.getServletContext();
    // Create the IlvChart.
    chart = new IlvChart(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(false);
    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 = config.getInitParameter("dataFile");
      System.out.println(url);
      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(ServletSupport.class,"notLoadFile");
      System.err.println(msg);
    }
    
    IlvLegend legend = new IlvLegend();
    legend.setBorder(new IlvLegendSeparator(borderColor, 2, 3, 1));
    chart.addLegend(legend, IlvChartLayout.WEST);
    
    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);
  }

  /**
   * Returns the chart used for the specified request. You can always return
   * the same chart, or you can return a chart for each request session if the
   * chart contents is session-specific.
   * @param params The parameters parsed from the request.
   */
  Override
  protected IlvChart getChart(IlvServletRequestParameters params)
      throws ServletException {
    return chart;
  }
  
  /**
   * Allows you to prepare the chart contents before the presentation is
   * generated. This default implementation does nothing.
   * @param params The parameters parsed from the request.
   * @param chart The chart returned by {@link #getChart}.
   */
  Override
  protected void prepareChart(IlvServletRequestParameters params, IlvChart chart)
      throws ServletException {
    HttpServletRequest request = params.getServletRequest();
    if (isVerbose(new IlvServletRequestParameters(request))){
      String msg=IlvResourceUtil.getServerLocaleString(ServletSupport.class,"failedInPrepareChart");
      System.out.println(msg);
    }
    int explodedDs = -1;
    try {
      explodedDs = Integer.parseInt(request.getParameter("explodedIdx"));
    } catch (NumberFormatException e) {
    }
    if (explodedDs == -1)
      return;
    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);
    }
  }  
}