package com.njcn.gather.tools.comtrade.comparewave.core.model;

import lombok.Data;
import lombok.NoArgsConstructor;

import static com.njcn.gather.tools.comtrade.comparewave.core.Constants.*;


/**
 * 主数据缓冲区结构
 * <p>对应C代码：data_pq</p>
 * <p>用于存储和管理电能质量检测的采样数据和分析结果</p>
 * 
 * @author hongawen
 * @since 1.0
 */
@Data
@NoArgsConstructor
public class DataPq {
    
    /** 电能质量数据窗口数量 */
    private static final int PQ_DATA_WINDOW_SIZE = 100;
    
    /** 三相统计值数组大小 */
    private static final int THREE_PHASE_SIZE = 3;
    
    /** 默认系统频率 (Hz) */
    private static final float DEFAULT_FREQUENCY = 50.0f;
    
    /** 默认额定电压 (V) */
    private static final float DEFAULT_NOMINAL_VOLTAGE = 100.0f;
    
    /** 默认额定电流 (A) */
    private static final float DEFAULT_NOMINAL_CURRENT = 5.0f;
    
    /**
     * 采样数据数组
     * <p>第一维：通道索引 (0 ~ MAX_CH_NUM-1)</p>
     * <p>第二维：数据索引 (0 ~ MAX_DATA_LEN-1)</p>
     */
    private int[][] smpData = new int[MAX_CH_NUM][MAX_DATA_LEN];
    
    /** 实际采样点数 */
    private int smpNum;

    /** 每周波采样点数（对应C代码中的smp_rate） */
    private float smpRate;
    
    /** 段数量（用于多段采样率文件） */
    private int segmentCount = 0;
    
    /** 每个段的起始采样点索引（降采样后的索引） */
    private int[] segmentStartIndices = new int[10];
    
    /** 每个段的采样率（点/周波） */
    private float[] segmentSampleRates = new float[10];
    
    /** 系统频率 (Hz) */
    private float f;
    
    /** 额定电压 (V) */
    private float un;
    
    /** 额定电流 (A) */
    private float in;
    
    /** 电压电流增益系数数组 */
    private float[] uiGainXs = new float[MAX_CH_NUM];
    
    /** 系统配置信息 */
    private ConfigStruct cfg;
    
    /** 电能质量数据数组，存储多个时间窗口的分析结果 */
    private PqsDataStruct[] pqData = new PqsDataStruct[PQ_DATA_WINDOW_SIZE];
    
    /** 当前数据点位置索引 */
    private int dataPoint;
    
    /** 10分钟 PST (短时闪变) 统计值数组 */
    private float[] pstVal10Min = new float[THREE_PHASE_SIZE];
    
    /** 10分钟 PLT (长时闪变) 统计值数组 */
    private float[] pltVal10Min = new float[THREE_PHASE_SIZE];
    
    /** 10分钟 UDD (电压不平衡度) 统计值数组 */
    private float[] uddVal10Min = new float[THREE_PHASE_SIZE];
    
    /** 录波开始时间，从CFG文件中读取 */
    private ClockStruct lbStartTime;
    
    /** 计算开始位置，波形对齐后的起始位置 */
    private int startCalPos;
    
    /** 计算开始时间，波形对齐后的起始时间 */
    private ClockStruct startCalTime;
    
    /** 可计算的200ms窗口数量 */
    private int calNum;
    
    /**
     * 初始化数据结构
     * <p>设置默认值并初始化所有子结构</p>
     */
    public void init() {
        cfg = new ConfigStruct();
        cfg.setDefaults();
        
        // 初始化电能质量数据数组中的每个元素
        for (int i = 0; i < pqData.length; i++) {
            pqData[i] = new PqsDataStruct();
            pqData[i].init();
        }
        
        // 设置采样相关的默认参数
        smpRate = DEFAULT_SAMPLE_RATE;
        f = DEFAULT_FREQUENCY;
        un = DEFAULT_NOMINAL_VOLTAGE;
        in = DEFAULT_NOMINAL_CURRENT;
        
        // 初始化每个通道的增益系数为1.0
        for (int i = 0; i < MAX_CH_NUM; i++) {
            uiGainXs[i] = 1.0f;
        }
        
        dataPoint = 0;
        smpNum = 0;
    }
    
    /**
     * 添加采样数据到指定通道和位置
     * 
     * @param channel 通道索引 (0 ~ MAX_CH_NUM-1)
     * @param index 数据位置索引 (0 ~ MAX_DATA_LEN-1)
     * @param value 采样值
     */
    public void addSampleData(int channel, int index, int value) {
        if (channel >= 0 && channel < MAX_CH_NUM && 
            index >= 0 && index < MAX_DATA_LEN) {
            smpData[channel][index] = value;
        }
    }
    
    /**
     * 获取当前数据点位置的电能质量数据结构
     * 
     * @return 当前电能质量数据，如果索引无效则返回null
     */
    public PqsDataStruct getCurrentPqData() {
        if (dataPoint >= 0 && dataPoint < pqData.length) {
            return pqData[dataPoint];
        }
        return null;
    }
    
    /**
     * 移动到下一个数据点位置
     * <p>当超出数组范围时将循环到索引0</p>
     */
    public void nextDataPoint() {
        dataPoint++;
        if (dataPoint >= pqData.length) {
            dataPoint = 0;
        }
    }
}