/**
 * Copyright (C) 2009 - 2013 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.qiyou.mb.android.ui.charts;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.achartengine.chart.PointStyle;
import org.achartengine.model.CategorySeries;
import org.achartengine.model.MultipleCategorySeries;
import org.achartengine.model.TimeSeries;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.DefaultRenderer;
import org.achartengine.renderer.SimpleSeriesRenderer;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;
import com.qiyou.mb.android.beans.Track;
import com.qiyou.mb.android.beans.basic.CItem;
import com.qiyou.mb.android.beans.basic.TypeStatistics;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint.Align;
import android.util.TypedValue;
import android.view.View;

/**
 * An abstract class for the demo charts to extend. It contains some methods for
 * building datasets and renderers.
 */
public abstract class AbstractChart implements IChart {
	public static final String TAG ="com.qiyou.AbstractChart";
	public static final String dTAG ="com.qiyou";
	  protected int Xcnt =100;
	  protected double XstepValue;
	  protected double maxXvalue;
	  protected XYMultipleSeriesDataset dataset;
	  protected XYMultipleSeriesRenderer renderer;
	  protected ArrayList<Track> trs = new ArrayList<Track>();
	  protected double minY;
	  protected double minX;
	  protected double maxY =0;
	  protected String[] titles ;
	  protected List<double[]> xValues ;  
	  protected List<double[]> yValues ;
	  protected TypeStatistics mTypeStatistics; 
	  protected int CYRAN =Color.parseColor("#00FFFF");
	  protected int LIGHTCYRAN =Color.parseColor("#E0FFFF");//#E0FFFF
	  protected int WHITE =Color.parseColor("#FFFFFF");//#E0FFFF
	  protected int DARKCYRAN =Color.parseColor("#008B8B");
//	  protected int renderCnt;
	  /*
	   * 
	   */
	  
	  public  XYMultipleSeriesRenderer getRender(int cnt,String title, String xTitle, String yTitle, boolean  isBarRender )  {
		  
		  
//	 	    int[] allColors = new int[] {Color.MAGENTA,Color.BLUE ,Color.DKGRAY , Color.CYAN,Color.GREEN, Color.GRAY ,Color.RED, Color.YELLOW,Color.DKGRAY};
		  int[] allColors = {  Color.parseColor("#FF8497"), DARKCYRAN, 
				  Color.parseColor("#948D8B"),Color.parseColor("#F59331"),   
				   Color.parseColor("#00BFC0"), CYRAN,Color.parseColor("#95AC5F"),
		            Color.parseColor("#56ADDB"),
		            Color.parseColor("#73C83C"),
		             Color.parseColor("#E54273"),
		            Color.parseColor("#FFD34E"), Color.parseColor("#2A86D6"),
		            };  
		   
	 	    
	 	    PointStyle[] allStyles = new PointStyle[] { PointStyle.CIRCLE, PointStyle.DIAMOND,
	 	        PointStyle.TRIANGLE, PointStyle.SQUARE ,PointStyle.POINT,PointStyle.POINT,PointStyle.POINT,PointStyle.POINT};
	 	    
	 	    int num =trs.size()>0?trs.size():1;
	 	    
		    int[] colors = new int[num*cnt]  ;
		    PointStyle[] styles = new PointStyle[num*cnt]  ;
		    
		 
		    for(int i=0;i<num*cnt;i++){ 
		    	 colors[i]=  allColors[i];
				 styles[i]=allStyles[i];
		    } 
		    	    
		    XYMultipleSeriesRenderer renderer;
		    if(isBarRender ){
		    	renderer= buildBarRenderer(colors );
//		        renderer.setBarSpacing(1);
		        renderer.setBarSpacing(0.5);
		    }
		    else 
		    {
		    	renderer = buildRenderer(colors, styles);
			    
			    int length = renderer.getSeriesRendererCount();
			    for (int i = 0; i < length; i++) {
			      ((XYSeriesRenderer) renderer.getSeriesRendererAt(i)).setFillPoints(true);
			    }
		    }
		    
//		    setChartSettings(renderer,"Distance - time chart", "Time", "Distance", 0.5, 12.5, -10, 40,
//			        Color.LTGRAY, Color.LTGRAY);
		
//		    maxXvalue =maxXvalue>getMaxTime()?maxXvalue:getMaxTime();
		    maxXvalue =maxXvalue*1.01;
		    
		    
		    setChartSettings(renderer, title, xTitle, yTitle, minX, maxXvalue,  minY*1.1, getMaxY()*1.1,
			        Color.LTGRAY, Color.LTGRAY);
		    
		    renderer.setInScroll(true); //http://zhirong.iteye.com/blog/1629781
		    
//		    renderer.setXLabels((int) getMaxTime()); 
//		    renderer.setYLabels((int) getMaxDist());
		    renderer.setXLabels(20);
		    renderer.setYLabels(10);
		    renderer.setShowGrid(true);
		    renderer.setXLabelsAlign(Align.RIGHT);
		    renderer.setYLabelsAlign(Align.RIGHT);
		    renderer.setZoomButtonsVisible(true);
		    renderer.setZoomEnabled(true, false);
//		    renderer.setBackgroundColor(Color.LTGRAY);
//		    renderer.setApplyBackgroundColor(true);
		    
//		    renderer.setMarginsColor(Color.argb(0, 220, 228, 234));
		    renderer.setMarginsColor(WHITE);//周边背景色
		    renderer.setGridColor(Color.LTGRAY); //栅格颜色
 		    renderer.setLabelsColor(Color.DKGRAY); //周边标签字体颜色
 		    renderer.setAxesColor(Color.DKGRAY);//轴颜色
 		    renderer.setLabelFormat(NumberFormat.getNumberInstance());// NumberFormat.getIntegerInstance());
 		    renderer.setXLabelsColor(Color.BLACK);
 		    renderer.setYLabelsColor(0, Color.BLACK); 
 		    renderer.setMargins(new int[] { 1, 50,20, 0 });//top,left,bottom,right
 		    
 		    renderer.setAxisTitleTextSize(tFontSize);
// 		    renderer.setBackgroundColor(color.lightgray); 
 		    renderer.setAxisTitleTextSize(tFontSize);
 		    renderer.setChartTitleTextSize(tFontSize); 
 		    renderer.setLabelsTextSize(tFontSize);
 		    renderer.setLegendTextSize(tFontSize);//距离--，速度--
 		   renderer.setPointSize(2f);
//		    renderer.setShowAxes(true);
		    renderer.setShowLegend(true);
//		    renderer.setShowAxes(false);
//		    renderer.setShowLegend(false);
//		    renderer.setShowLabels(false);
//		    renderer.setPanLimits(new double[] { 0,  getMaxTime()*2, 0, getMaxDist()*2 });
//		    renderer.setZoomLimits(new double[] { 0,  getMaxTime()/2, 0, getMaxDist()/2 });
		    renderer.setPanLimits(new double[] { minX,  maxXvalue, 0, getMaxY() });
		    renderer.setZoomLimits(new double[] { minX,  maxXvalue, 0, getMaxY()}); 
		    return renderer;
	  }
	  
	public  XYMultipleSeriesRenderer getRender(int cnt,String title, String xTitle, String yTitle  )
	  { 	  
// 	    int[] allColors = new int[] { Color.BLUE, Color.GREEN, Color.CYAN, Color.YELLOW  };
		return getRender(  cnt,  title,   xTitle,   yTitle,  false ); 
	  }  
	  /*
	   * return max time of minutes
	   */
	public  double getMaxTime()
	  {
		  double maxSportTime =0.0;
	 	  for(Track tr:trs){
	 		 if(tr ==null)continue;
//	 		  maxSportTime = tr.getTrackBean().getSportTime()>maxSportTime? tr.getTrackBean().getSportTime():maxSportTime;
//	 		  long sptime =tr.getTrackBean().getEndTime() -  tr.getTrackBean().getStartTime();
	 		 long sptime =tr.getTrackBean().getSportTime();
	 		  maxSportTime = sptime>maxSportTime? sptime:maxSportTime;
	 	  } 
	 	 maxSportTime = maxSportTime/1000/60.0;
	 	 
		  return maxSportTime ;
	  }
	
	public  double getMaxDist()
	  {
		  double max  =0.0;
	 	  for(Track tr:trs){
	 		 if(tr ==null)continue;
//	 		  maxSportTime = tr.getTrackBean().getSportTime()>maxSportTime? tr.getTrackBean().getSportTime():maxS 
	 		 max = tr.getTrackBean().getDistance()>max? tr.getTrackBean().getDistance():max;
	 	  } 
	 	 max = max/1000.0;
	 	 
		  return max ;
	  }
	  
	 public double getMaxSpTime()
	  {
		  double maxSportTime =0.0;
	 	  for(Track tr:trs){
	 		 if(tr ==null)continue;
	 		  maxSportTime = tr.getTrackBean().getSportTime()>maxSportTime? tr.getTrackBean().getSportTime():maxSportTime;
 	 	  } 
	 	 maxSportTime = maxSportTime/1000/60.0;
		  return maxSportTime ;
	  }
	 
	public abstract double getMaxY();
	
		   
  /**
   * Builds an XY multiple dataset using the provided values.
   * 
   * @param titles the series titles
   * @param xValues the values for the X axis
   * @param yValues the values for the Y axis
   * @return the XY multiple dataset
   */
  protected XYMultipleSeriesDataset buildDataset(String[] titles, List<double[]> xValues,
      List<double[]> yValues) {
    XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
    addXYSeries(dataset, titles, xValues, yValues, 0);
    return dataset;
  }

  public void addXYSeries(XYMultipleSeriesDataset dataset, String[] titles, List<double[]> xValues,
      List<double[]> yValues, int scale) {
    int length = titles.length;
    for (int i = 0; i < length; i++) {
      XYSeries series = new XYSeries(titles[i], scale);
      double[] xV = xValues.get(i);
      double[] yV = yValues.get(i);
      
//      QLog.getLogger().d(dTAG,TAG +" xV: "+ xV.toString());
//      QLog.getLogger().d(dTAG,TAG +" yV: "+ yV.toString());

      int seriesLength = xV.length;
//      int seriesLength = yV.length;
      for (int k = 0; k < seriesLength; k++) {
        series.add(xV[k], yV[k]);
      }
      dataset.addSeries(series);
    }
  }

  /**
   * Builds an XY multiple series renderer.
   * 
   * @param colors the series rendering colors
   * @param styles the series point styles
   * @return the XY multiple series renderers
   */
  protected XYMultipleSeriesRenderer buildRenderer(int[] colors, PointStyle[] styles) {
    XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
    setRenderer(renderer, colors, styles);
    return renderer;
  }

  protected void setRenderer(XYMultipleSeriesRenderer renderer, int[] colors, PointStyle[] styles) {
    renderer.setAxisTitleTextSize(16);
    renderer.setChartTitleTextSize(20);
    renderer.setLabelsTextSize(15);
    renderer.setLegendTextSize(15);
    renderer.setPointSize(3f);
    renderer.setMargins(new int[] { 40, 40, 35, 20 });
    int length = colors.length;
    for (int i = 0; i < length; i++) {
      XYSeriesRenderer r = new XYSeriesRenderer();
      r.setColor(colors[i]);
      r.setPointStyle(styles[i]);
      renderer.addSeriesRenderer(r);
    }
  }

  /**
   * Sets a few of the series renderer settings.
   * 
   * @param renderer the renderer to set the properties to
   * @param title the chart title
   * @param xTitle the title for the X axis
   * @param yTitle the title for the Y axis
   * @param xMin the minimum value on the X axis
   * @param xMax the maximum value on the X axis
   * @param yMin the minimum value on the Y axis
   * @param yMax the maximum value on the Y axis
   * @param axesColor the axes color
   * @param labelsColor the labels color
   */
  protected void setChartSettings(XYMultipleSeriesRenderer renderer, String title, String xTitle,
      String yTitle, double xMin, double xMax, double yMin, double yMax, int axesColor,
      int labelsColor) {
    renderer.setChartTitle(title);
    renderer.setXTitle(xTitle);
    renderer.setYTitle(yTitle);
    renderer.setXAxisMin(xMin);
    renderer.setXAxisMax(xMax);
    renderer.setYAxisMin(yMin);
    renderer.setYAxisMax(yMax);
    renderer.setAxesColor(axesColor);
    renderer.setLabelsColor(labelsColor);
  }

  /**
   * Builds an XY multiple time dataset using the provided values.
   * 
   * @param titles the series titles
   * @param xValues the values for the X axis
   * @param yValues the values for the Y axis
   * @return the XY multiple time dataset
   */
  protected XYMultipleSeriesDataset buildDateDataset(String[] titles, List<Date[]> xValues,
      List<double[]> yValues) {
    XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
    int length = titles.length;
    for (int i = 0; i < length; i++) {
      TimeSeries series = new TimeSeries(titles[i]);
      Date[] xV = xValues.get(i);
      double[] yV = yValues.get(i);
      int seriesLength = xV.length;
      for (int k = 0; k < seriesLength; k++) {
        series.add(xV[k], yV[k]);
      }
      dataset.addSeries(series);
    }
    return dataset;
  }

  /**
   * Builds a category series using the provided values.
   * 
   * @param titles the series titles
   * @param values the values
   * @return the category series
   */
  protected CategorySeries buildCategoryDataset(String title, HashMap<String,Double> values) {
    CategorySeries series = new CategorySeries(title);
   
    for (String key:values.keySet()) {
      
    	
    	series.add(key, values.get(key));
    }

    return series;
  }
 
  
  protected CategorySeries buildCategoryDataset(String title, List<CItem> Citems) {
	    CategorySeries series = new CategorySeries(title);
	    
	    for (CItem citem:Citems) {  
	    	
	    	series.add(citem.getValue(),  citem.getCnt() );
	    }

	    return series;
	  }

  /**
   * Builds a multiple category series using the provided values.
   * 
   * @param titles the series titles
   * @param values the values
   * @return the category series
   */
  protected MultipleCategorySeries buildMultipleCategoryDataset(String title,
      List<String[]> titles, List<double[]> values) {
    MultipleCategorySeries series = new MultipleCategorySeries(title);
    int k = 0;
    for (double[] value : values) {
      series.add(2007 + k + "", titles.get(k), value);
      k++;
    }
    return series;
  }

  /**
   * Builds a category renderer to use the provided colors.
   * 
   * @param colors the colors
   * @return the category renderer
   */
  protected DefaultRenderer buildCategoryRenderer(int[] colors) {
    DefaultRenderer renderer = new DefaultRenderer();
    renderer.setLabelsTextSize(25);
    renderer.setLegendTextSize(18);
    renderer.setMargins(new int[] { 20, 30, 15, 0 });
    for (int color : colors) {
      SimpleSeriesRenderer r = new SimpleSeriesRenderer();
      r.setColor(color);
      renderer.addSeriesRenderer(r);
    }
    return renderer;
  }

  /**
   * Builds a bar multiple series dataset using the provided values.
   * 
   * @param titles the series titles
   * @param values the values
   * @return the XY multiple bar dataset
   */
  protected XYMultipleSeriesDataset buildBarDataset(String[] titles, List<double[]> values) {
    XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
    int length = titles.length;
    for (int i = 0; i < length; i++) {
      CategorySeries series = new CategorySeries(titles[i]);
      double[] v = values.get(i);
      int seriesLength = v.length;
      for (int k = 0; k < seriesLength; k++) {
        series.add(v[k]);
      }
      dataset.addSeries(series.toXYSeries());
    }
    return dataset;
  }

  /**
   * Builds a bar multiple series renderer to use the provided colors.
   * 
   * @param colors the series renderers colors
   * @return the bar multiple series renderer
   */
  protected XYMultipleSeriesRenderer buildBarRenderer(int[] colors) {
    XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
    renderer.setAxisTitleTextSize(16);
    renderer.setChartTitleTextSize(20);
    renderer.setLabelsTextSize(15);
    renderer.setLegendTextSize(15);
    int length = colors.length;
    for (int i = 0; i < length; i++) {
      SimpleSeriesRenderer r = new SimpleSeriesRenderer();
      r.setColor(colors[i]);
//      r.setDisplayChartValues(true); 
      renderer.addSeriesRenderer(r);
    }
    return renderer;
  }
  
  protected void buildBarRenderer(XYMultipleSeriesRenderer renderer,int[] colors) { 	  
	    int length = colors.length;
	    for (int i = 0; i < length; i++) {
	      SimpleSeriesRenderer r = new SimpleSeriesRenderer();
	      r.setColor(colors[i]);
	      renderer.addSeriesRenderer(r);
	    }
//	    renderer.setBarSpacing(0.5);
	    renderer.setBarSpacing(1);
	     
	  }
  
  public abstract View getChartView(Context context);  
  public abstract void buildChartData();
  public void setTrs(ArrayList<Track> trs) {
		
		if(trs.size()>4) 
		{ 	
			this.trs.clear();
			 for(int i =0;i<=3;i++){
				 this.trs.add(trs.get(i));
			 }
		}else
	 this.trs = trs;		 
	}

protected double[] getDv( ArrayList<Double> D ){
		return getDv(D,false);
	}

 protected double[] getDv( ArrayList<Double> D,boolean checkMax){
	   int i =0;
	   double[]  Dv = new double[D.size()];
       for (Double d :D){
     	  Dv[i] =d.doubleValue();
     	 if(checkMax){
     		 maxXvalue =maxXvalue< Dv[i]? Dv[i]:maxXvalue; 
     	  }
     	  i++;     	 
       }
       return Dv; 
    		 
}

public TypeStatistics getStrack() {
	return mTypeStatistics;
}

public void setStrack(TypeStatistics mTypeStatistics) {
	this.mTypeStatistics = mTypeStatistics;
}
protected float mFontSize=24;
protected float sFontSize=10;
protected float tFontSize=8;
protected float ttFontSize=6;
public void setFontSize(Context context){
	mFontSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mFontSize, context.getResources().getDisplayMetrics());
	sFontSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sFontSize, context.getResources().getDisplayMetrics());
	tFontSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tFontSize, context.getResources().getDisplayMetrics());
	tFontSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, ttFontSize, context.getResources().getDisplayMetrics());

}

}

