package com.desfate.chart.ui.old.OTC.controls;

import com.desfate.chart.ui.old.OTC.datas.HistoryCycle;

import java.util.ArrayList;
import java.util.Date;

public abstract class BaseKLineControl {

    public abstract long getStep();

    private long timeArea = 0;// 时间宽度
    //region 如果是把历史行情往后一个周期累加时，nextDate < firstDate;如果是把历史行情往前一个周期累加时，firstDate < nextDate
    private Date nextDate = null;// 下一个周期的时间
    private Date firstDate = null;// 上一个周期的时间
    //endregion
    private ArrayList<HistoryCycle> historyCycles = new ArrayList<>();
    private HistoryCycle historyCycle = null;
    private boolean isFront;

    /**
     * 30分钟线转化为小时线
     *
     * @param cycleList 30分钟线的周期数据
     * @param per       倍数，比如2倍，就是2 * 30，返回为1小时线， 4返回2小时， 8返回4小时
     */
    public ArrayList<HistoryCycle> thirdToHourLine(ArrayList<HistoryCycle> cycleList, int per, boolean isFront) {

        timeArea = per * getStep() * 60 * 1000;// 时间宽度
        this.isFront = isFront;
        // 处理数据宗旨：处理数据的时候，当出现没有以整时开始的数据段，都要新建一个小时数据点
        groupingHistryCycles(cycleList);

        //倒序
        ArrayList<HistoryCycle> tem = new ArrayList<>();
        for (int a = historyCycles.size() - 1; a >= 0; a--) {
            if (historyCycles.get(a) != null) {
                tem.add(historyCycles.get(a));
            }
        }
        return tem;
    }

    /**
     * 分组，将得到的30分钟线，按照
     *
     * @return
     */
    private void groupingHistryCycles(ArrayList<HistoryCycle> cycleList) {
        for (int a = cycleList.size(); a > 0; a = a - 1) {
            if (this.isFront) {
                make(cycleList.get(a - 1));
            } else {
                makeToEnd(cycleList.get(a - 1));
            }
        }

        // 运行完毕以后，会出现一个现象，就是最后一个周期还没有找到下一个周期的情况下，数据不会被保存，所以这个时候需要考虑到
        historyCycles.add(this.historyCycle);
        this.historyCycle = null;
    }

    /**
     * 处理数据
     * <li>往前累加</li>
     * @param historyCycle
     */
    private void make(HistoryCycle historyCycle) {
        // 检查是否符合其实数据的标准
        if (this.historyCycle == null) {// 处理起始位置的数据
            // 找出起始位置
            Date startTime = historyCycle.getStartTime();
            long remainder = startTime.getTime() % timeArea; // 求余，有两中情况
            if (remainder != 0) {// 起始数据的时间不符合周期时间，需要新建一个周期数据，
                long firstTime = startTime.getTime() - remainder;// 这个就是起始时间 10:30~11:00
                historyCycle.setStartTime(new Date(firstTime));
            } else {// 起始数据刚好是与周期匹配， 不做处理，直接赋值

            }
            this.historyCycle = historyCycle;
            nextDate = new Date(this.historyCycle.getStartTime().getTime() + timeArea);// 下一个周期的起始时间，只提供给计算使用，
        } else { // 对比，是否该条数据在他们的周期内。在，就累加进去；如果不在，就需要新建一条小时线
            // 根据起始时间，算出下一个周期的起始时间
            if (historyCycle.getStartTime().compareTo(nextDate) < 0) {// 在周期内，合并数据
                double highest = historyCycle.getHighest();
                double lowest = historyCycle.getLowest();
                if (this.historyCycle.getHighest() == 0 || this.historyCycle.getHighest() < highest) {
                    this.historyCycle.setHighest(highest);
                }
                if (this.historyCycle.getLowest() == 0 || this.historyCycle.getLowest() > lowest) {
                    this.historyCycle.setLowest(lowest);
                }
                //不管是不是最后一个，将收盘价格赋值给
                this.historyCycle.setClosed(historyCycle.getClosed());
                this.historyCycle.setTotleVolume(this.historyCycle.getTotleVolume() + historyCycle.getTotleVolume());// 成交量相加
                this.historyCycle.setTotleTurnover(this.historyCycle.getTotleTurnover() + historyCycle.getTotleTurnover());// 成交额相加
            }
            if (historyCycle.getStartTime().compareTo(nextDate) >= 0) {// 本周期外，将本周起的数据保存，新建下一个周期
                historyCycles.add(this.historyCycle);
                this.historyCycle = null;
                make(historyCycle);
            }
        }
    }

    /**
     * 处理数据
     * <li>历史行情往后累加</li>
     *
     * @param historyCycle
     */
    private void makeToEnd(HistoryCycle historyCycle) {
        // 检查是否符合其实数据的标准
        if (this.historyCycle == null) {// 处理起始位置的数据
            // 找出起始位置
            Date startTime = historyCycle.getStartTime();
            long remainder = startTime.getTime() % timeArea; // 求余，有两中情况
            if (remainder != 0) {// 起始数据的时间不符合周期时间，需要新建一个周期数据，
                long firstTime = startTime.getTime() - remainder + timeArea;// 这个就是起始时间 10:30
                firstDate = new Date(firstTime);// 这个应该比nextDate大
                historyCycle.setStartTime(new Date(firstTime));
                nextDate/*fixme 起始这个数据是他的上一个周期,因为现在要往后累加*/ = new Date(firstDate.getTime() - timeArea);// 下一个周期的起始时间，只提供给计算使用，10:00
            } else {// 起始数据刚好是与周期匹配， 不做处理，直接赋值
                firstDate = new Date(startTime.getTime() + timeArea);
                nextDate/*fixme 起始这个数据是他的上一个周期,因为现在要往后累加*/ = startTime;// 下一个周期的起始时间，只提供给计算使用，10:00
                historyCycle.setStartTime(firstDate);
                historyCycles.add(this.historyCycle);
                this.historyCycle = null;
                return;
            }
            this.historyCycle = historyCycle;
        } else { // 对比，是否该条数据在他们的周期内。在，就累加进去；如果不在，就需要新建一条小时线
            // 根据起始时间，算出下一个周期的起始时间
            if (historyCycle.getStartTime().compareTo(firstDate) <= 0) {// 在周期内，合并数据
                double highest = historyCycle.getHighest();
                double lowest = historyCycle.getLowest();
                if (this.historyCycle.getHighest() == 0 || this.historyCycle.getHighest() < highest) {
                    this.historyCycle.setHighest(highest);
                }
                if (this.historyCycle.getLowest() == 0 || this.historyCycle.getLowest() > lowest) {
                    this.historyCycle.setLowest(lowest);
                }
                //不管是不是最后一个，将收盘价格赋值给
                this.historyCycle.setClosed(historyCycle.getClosed());
                this.historyCycle.setTotleVolume(this.historyCycle.getTotleVolume() + historyCycle.getTotleVolume());// 成交量相加
                this.historyCycle.setTotleTurnover(this.historyCycle.getTotleTurnover() + historyCycle.getTotleTurnover());// 成交额相加
            }
            if (historyCycle.getStartTime().compareTo(firstDate) > 0) {// 本周期外，将本周起的数据保存，新建下一个周期
                historyCycles.add(this.historyCycle);
                this.historyCycle = null;
                makeToEnd(historyCycle);
            }
        }
    }


}
