package com.algobase.share.chart;

import java.util.ArrayList;

import android.content.Context;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;

import android.util.AttributeSet;

public class LineChartView extends ChartView {

  public LineChartView(Context context) {
    super(context);
  }

  public LineChartView(Context context, AttributeSet attr) {
    super(context,attr);
  }

  public LineChartView(Context context, AttributeSet attr, int defStyle) {
    super(context,attr,defStyle);
  }



  @Override
  public void drawChart(Canvas canvas, int s)
  {
    ChartViewSeries series = chartList.get(s);
    int line_clr = series.color;
    int fill_clr = series.fill_color;
    float line_w = series.line_width;

    ArrayList<ChartViewData> values = series.values;
    ArrayList<Point> points = new ArrayList<Point>();

  //if (values == null || values.size() == 0) return;

    int numValues = getNumValues(s);

    if (numValues == 0) return;

/*
    if (values != null)
    { if (series.current_point != null &&
          series.current_point.valueX > values.get(values.size()-1).valueX) 
      { values.add(series.current_point);
        numValues++;
       }
     }
*/

    Path path = new Path();
    float last_x=0;
    float last_y=0;

    int len = values.size();

    int p = 2;

    if (len < 256) p = 2;
    else
    if (len < 512) p = 4;
    else
    if (len < 1024) p = 8;
    else
    if (len < 2048) p = 16;
    else
    if (len < 4096) p = 32;
    else p = 64;

    int count = 0;

    for (int i = 0; i < numValues; i++) 
    { 
      if (i % (p/2) != 0) continue;

      double xx = chartWidth  * (getValueX(s,i) - xMin) / (xMax - xMin);
      double yy = chartHeight * (getValueY(s,i) - yMin) / (yMax - yMin);

      float x = (float)(xx + marginLeft);
      float y = (float)(chartHeight + marginTop - yy);

      if (i == 0) 
        path.moveTo(x,y);
      else
      {
        //path.lineTo(x,y);

        float x_mid = (last_x + x)/2;
        float y_mid = (last_y + y)/2;
        float cp_x1 = (x_mid + last_x)/2;
        float cp_x2 = (x_mid + x)/2;
        path.quadTo(cp_x1, last_y,x_mid,y_mid);
        path.quadTo(cp_x2, y,x,y);
      }

      points.add(new Point((int)x,(int)y));

      last_x = x;
      last_y = y;

      count++;
     }

/*
     // why ?
     path.lineTo(last_x,last_y);
     count++;
*/

     float last_x1 = last_x;

     if (values != null && series.current_point != null) 
     { double current_x = series.current_point.valueX;
       double current_y = series.current_point.valueY;
       double xx = chartWidth  * (current_x - xMin) / (xMax - xMin);
       double yy = chartHeight * (current_y - yMin) / (yMax - yMin);
       float x = (float)(xx + marginLeft);
       float y = (float)(chartHeight + marginTop - yy);
       canvas.drawLine(last_x,last_y,x,y,paint);
       path.lineTo(x,y);
       last_x1 = x;
       count++;
      }

     series.pathLength = count;

/*
     if (values != null && series.current_point != null) 
       values.remove(values.size()-1);
*/


     if (fill_clr != 0) 
     { Path fill_path = new Path(path);
       fill_path.lineTo(last_x1,chartHeight+marginTop);
       fill_path.lineTo(marginLeft,chartHeight+marginTop);
       fill_path.close();
       paint.setStyle(Paint.Style.FILL);
       paint.setColor(fill_clr);
       canvas.drawPath(fill_path,paint);
     }

     paint.setStyle(Paint.Style.STROKE);
     paint.setStrokeCap(Paint.Cap.ROUND);
     paint.setStrokeWidth(line_w); 
     paint.setColor(line_clr); 
     canvas.drawPath(path,paint);

     if (series.show_points)
     { for(Point q : points)
       { paint.setStyle(Paint.Style.FILL);
         paint.setColor(0xffffffff);
         canvas.drawCircle(q.x,q.y,line_w/2 + 4,paint);
         paint.setStyle(Paint.Style.STROKE);
         paint.setStrokeWidth(2); 
         paint.setColor(0xff000000);
         canvas.drawCircle(q.x,q.y,line_w/2 + 4,paint);
       }
     }

     if (values != null && series.current_point != null) 
     { paint.setStyle(Paint.Style.FILL);
       paint.setColor(line_clr);
       canvas.drawCircle(last_x,last_y,line_w/2 + 4,paint);
       paint.setStyle(Paint.Style.STROKE);
       paint.setStrokeWidth(2); 
       paint.setColor(line_clr);
       paint.setARGB(255,230,230,230);
       canvas.drawCircle(last_x,last_y,line_w/2 + 4,paint);
     }


     // draw max and min line

     float x1 = marginLeft;
     float x2 = chartWidth;

     double yy_min = chartHeight * (series.min_y - yMin) / (yMax - yMin);
     float ymin = (float)(chartHeight + marginTop - yy_min);

     double yy_max = chartHeight * (series.max_y - yMin) / (yMax - yMin);
     float ymax = (float)(chartHeight + marginTop - yy_max);

     paint.setColor(0xffff0000); 
     paint.setStrokeWidth(2); 

     if (series.show_min) canvas.drawLine(x1,ymin,x2,ymin,paint);
     if (series.show_max) canvas.drawLine(x1,ymax,x2,ymax,paint);

  }

}
