/**
 * Copyright (C) 2009, 2010 SC 4ViewSoft SRL
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.cherry.lib.doc.office.thirdpart.achartengine.chart;

import java.util.List;

import com.cherry.lib.doc.office.thirdpart.achartengine.model.XYMultipleSeriesDataset;
import com.cherry.lib.doc.office.thirdpart.achartengine.model.XYSeries;
import com.cherry.lib.doc.office.thirdpart.achartengine.renderers.SimpleSeriesRenderer;
import com.cherry.lib.doc.office.thirdpart.achartengine.renderers.XYMultipleSeriesRenderer;
import com.cherry.lib.doc.office.thirdpart.achartengine.renderers.XYMultipleSeriesRenderer.Orientation;

import android.graphics.Canvas;
import android.graphics.Paint;

/**
 * The combined XY chart rendering class.
 */
public class CombinedXYChart extends XYChart {
  /** The embedded XY charts. */
  private XYChart[] mCharts;
  /** The supported charts for being combined. */
  private Class[] xyChartTypes = new Class[] { TimeChart.class, LineChart.class, ColumnBarChart.class,
      BubbleChart.class, LineChart.class, ScatterChart.class, RangeBarChart.class };

  /**
   * Builds a new combined XY chart instance.
   * 
   * @param dataset the multiple series dataset
   * @param renderer the multiple series renderer
   * @param types the XY chart types
   */
  public CombinedXYChart(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer,
      String[] types) {
    super(dataset, renderer);
    int length = types.length;
    mCharts = new XYChart[length];
    for (int i = 0; i < length; i++) {
      try {
        mCharts[i] = getXYChart(types[i]);
      } catch (Exception e) {
        // ignore
      }
      if (mCharts[i] == null) {
        throw new IllegalArgumentException("Unknown chart type " + types[i]);
      } else {
        XYMultipleSeriesDataset newDataset = new XYMultipleSeriesDataset();
        newDataset.addSeries(dataset.getSeriesAt(i));
        XYMultipleSeriesRenderer newRenderer = new XYMultipleSeriesRenderer();
        // TODO: copy other parameters here
        newRenderer.setBarSpacing(renderer.getBarSpacing());
        newRenderer.setPointSize(renderer.getPointSize());
        int scale = dataset.getSeriesAt(i).getScaleNumber();
        if (renderer.isMinXSet(scale)) {
          newRenderer.setXAxisMin(renderer.getXAxisMin(scale));
        }
        if (renderer.isMaxXSet(scale)) {
          newRenderer.setXAxisMax(renderer.getXAxisMax(scale));
        }
        if (renderer.isMinYSet(scale)) {
          newRenderer.setYAxisMin(renderer.getYAxisMin(scale));
        }
        if (renderer.isMaxYSet(scale)) {
          newRenderer.setYAxisMax(renderer.getYAxisMax(scale));
        }
        newRenderer.addSeriesRenderer(renderer.getSeriesRendererAt(i));
        mCharts[i].setDatasetRenderer(newDataset, newRenderer);
      }
    }
  }

  private XYChart getXYChart(String type) throws IllegalAccessException, InstantiationException {
    XYChart chart = null;
    int length = xyChartTypes.length;
    for (int i = 0; i < length && chart == null; i++) {
      XYChart newChart = (XYChart) xyChartTypes[i].newInstance();
      if (type.equals(newChart.getChartType())) {
        chart = newChart;
      }
    }
    return chart;
  }

  /**
   * The graphical representation of a series.
   * 
   * @param canvas the canvas to paint to
   * @param paint the paint to be used for drawing
   * @param points the array of points to be used for drawing the series
   * @param seriesRenderer the series renderer
   * @param yAxisValue the minimum value of the y axis
   * @param seriesIndex the index of the series currently being drawn
   */
  public void drawSeries(Canvas canvas, Paint paint, float[] points,
      SimpleSeriesRenderer seriesRenderer, float yAxisValue, int seriesIndex) {
    mCharts[seriesIndex].setScreenR(getScreenR());
    mCharts[seriesIndex].setCalcRange(getCalcRange(mDataset.getSeriesAt(seriesIndex).getScaleNumber()), 0);
    mCharts[seriesIndex].drawSeries(canvas, paint, points, seriesRenderer, yAxisValue, 0);
  }

  @Override
  protected void drawSeries(XYSeries series, Canvas canvas, Paint paint, List<Float> pointsList,
      SimpleSeriesRenderer seriesRenderer, float yAxisValue, int seriesIndex, Orientation or) {
    mCharts[seriesIndex].setScreenR(getScreenR());
    mCharts[seriesIndex].setCalcRange(getCalcRange(mDataset.getSeriesAt(seriesIndex).getScaleNumber()), 0);
    mCharts[seriesIndex].drawSeries(series, canvas, paint, pointsList, seriesRenderer, yAxisValue,
        0, or);
  }

  /**
   * Returns the legend shape width.
   * 
   * @param seriesIndex the series index
   * @return the legend shape width
   */
  public int getLegendShapeWidth(int seriesIndex) {
    return mCharts[seriesIndex].getLegendShapeWidth(0);
  }

  /**
   * The graphical representation of the legend shape.
   * 
   * @param canvas the canvas to paint to
   * @param renderer the series renderer
   * @param x the x value of the point the shape should be drawn at
   * @param y the y value of the point the shape should be drawn at
   * @param seriesIndex the series index
   * @param paint the paint to be used for drawing
   */
  public void drawLegendShape(Canvas canvas, SimpleSeriesRenderer renderer, float x, float y,
      int seriesIndex, Paint paint) {
    mCharts[seriesIndex].drawLegendShape(canvas, renderer, x, y, 0, paint);
  }

  /**
   * Returns the chart type identifier.
   * 
   * @return the chart type
   */
  public String getChartType() {
    return "Combined";
  }

}
