package com.desfate.chart;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;

import com.desfate.chart.entity.LineEntity;

import java.util.ArrayList;
import java.util.List;


/**
 * <p>
 * MACandleStickChart is inherits from CandleStickChart which can display moving
 * average lines on this graph.
 * </p>
 * <p>
 * MACandleStickChartはグラフの一種です、移動平均線など分析線がこのグラフで表示は可能です。
 * </p>
 * <p>
 * MACandleStickChart继承于CandleStickChart的，可以在CandleStickChart基础上
 * 显示移动平均等各种分析指标数据。
 * </p>
 *
 * @see CandleStickChart
 * @see StickChart
 */
public class MACandleStickChart extends CandleStickChart {

    /**
     * <p>
     * data to draw lines
     * </p>
     * <p>
     * ラインを書く用データ
     * </p>
     * <p>
     * 绘制线条用的数据
     * </p>
     */
    private List<LineEntity> lineData;
    private List<LineEntity> newLineData;

    private boolean isChangeLineData = false;

    /*
     * (non-Javadoc)
     *
     * @param context
     *
     */
    public MACandleStickChart(Context context) {
        super(context);
    }

    /*
     * (non-Javadoc)
     *
     * @param context
     *
     * @param attrs
     *
     * @param defStyle
     *
     * AttributeSet, int)
     */
    public MACandleStickChart(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    /*
     * (non-Javadoc)
     *
     * @param context
     *
     * @param attrs
     *
     *
     *
     * AttributeSet)
     */
    public MACandleStickChart(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onUpdate() {
        updateLineData();
        super.onUpdate();
    }

    /**
     * (non-Javadoc)
     * <p>
     * <p>Called when is going to draw this chart<p> <p>チャートを書く前、メソッドを呼ぶ<p>
     * <p>绘制图表时调用<p>
     *
     * @param canvas
     * @see android.view.View#onDraw(Canvas)
     */
    @Override
    protected void drawChart(Canvas canvas) {
        super.drawChart(canvas);
        // draw lines
        if (null != this.lineData) {
            if (0 != this.lineData.size()) {
                drawLines(canvas);
            }
        }
    }

    @Override
    protected void initMaxAndMin() {
        super.initMaxAndMin();
        // calculate max value and min value
        if (null != this.lineData) {
            for (int i = 0; i < lineData.size(); i++) {
                LineEntity line = lineData.get(i);
                if (line.isDisplay()) {
                    List<Double> lineData = line.getLineData();

                    if (lineData != null) {
                        for (int j = this.getStartIndex(); j >= 0 && j < lineData.size() && j < this.getStartIndex() + this.getMaxSticksNum(); j++) {
                            float value = lineData.get(j).floatValue();
                            if (value > this.getMaxValue()) {
                                this.setMaxValue(value);
                            } else if (value < this.getMinValue()) {
                                this.setMinValue(value);
                            }
                        }
                    }
                }
            }
        }
    }

    public void setDeicmal(int decimal) {
        setDecimalNum(decimal);
    }

    /**
     * <p>
     * draw lines
     * </p>
     * <p>
     * ラインを書く
     * </p>
     * <p>
     * 绘制线条
     * </p>
     *
     * @param canvas
     */
    protected void drawLines(Canvas canvas) {
        // distance between two points
        float lineLength = getItemWidth();
        // start point‘s X
        float startX;

        // draw MA lines
        for (int i = 0; i < lineData.size(); i++) {
            LineEntity line = lineData.get(i);
            if (line.isDisplay()) {
                Paint mPaint = new Paint();
                mPaint.setColor(line.getLineColor());
                mPaint.setAntiAlias(true);
                mPaint.setStrokeWidth(2.0f);
                List<Double> lineData = line.getLineData();
                // set start point’s X
                // 设置画质图表的起点
//				startX = /*super.getAxisMarginLeft() + super.getAxisMarginRight()*/2f;
                startX = lineLength / 2;// 线条起始位置
                // start point
                PointF ptFirst = null;
                if (lineData != null) {

                    for (int j = this.getStartIndex(); j >= 0 && j < lineData.size() && j < this.getStartIndex() + this.getMaxSticksNum(); j++) {
                        float value = lineData.get(j).floatValue();
                        // calculate Y
                        float valueY = super.getAxisMarginTop() + (float) ((1f -
                                (value - super.getMinValue()) * 10000000 / ((super.getMaxValue() - super.getMinValue()) * 10000) / 1000)
                                * (super.getHeight() - super.getAxisMarginBottom() - 2 * super.getAxisMarginTop()));

                        // if is not last point connect to previous point
                        if (j > this.getStartIndex()) {
                            canvas.drawLine(ptFirst.x, ptFirst.y, startX,
                                    valueY, mPaint);
                        }
                        // reset
                        ptFirst = new PointF(startX, valueY);
                        startX = startX + lineLength;
                    }
                }
            }
        }
    }

    public void updateLineData() {
        if (this.lineData == null) {
            lineData = new ArrayList<LineEntity>();
        }
        if (isChangeLineData) {
            isChangeLineData = false;
            if (this.newLineData != null) {
                this.lineData.clear();
                this.lineData.addAll(newLineData);
            }
        }
    }

    /**
     * @return the lineData
     */
    public List<LineEntity> getLineData() {
        if (newLineData == null) {
            newLineData = new ArrayList<LineEntity>();
        }
        return newLineData;
    }

    /**
     * @param lineData the lineData to set
     */
    public void setLineData(List<LineEntity> lineData) {
        if (this.newLineData == null) {
            this.newLineData = new ArrayList<LineEntity>();
        }
        this.newLineData.clear();
        this.newLineData.addAll(lineData);
        isChangeLineData = true;
    }
}
