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

import com.njcn.gather.tools.comtrade.comparewave.core.model.ClockStruct;
import com.njcn.gather.tools.comtrade.comparewave.core.model.Complex;
import com.njcn.gather.tools.comtrade.comparewave.core.model.DataPq;
import com.njcn.gather.tools.comtrade.comparewave.core.model.PqsDataStruct;
import lombok.extern.slf4j.Slf4j;

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


/**
 * 电能质量计算器
 * 对应C代码：cal.c
 * 
 * 极其重要：必须严格按照C代码的计算顺序和方法！
 * @author hongawen
 */
@Slf4j
public class PowerQualityCalculator {
    
    /**
     * FFT结果数据，对应C代码的全局变量
     * 多通道复数数据存储，用于存储各通道的FFT变换结果
     */
    private static Complex[][] fftXkData = new Complex[MAX_CH_NUM][5120 + 1024];
    
    /**
     * IB相FFT结果数据
     * 用于存储合成IB相的FFT变换结果
     */
    private static Complex[] fftXkDataIb = new Complex[5120 + 1024];
    
    static {
        // 初始化复数数组
        for (int i = 0; i < MAX_CH_NUM; i++) {
            for (int j = 0; j < 5120 + 1024; j++) {
                fftXkData[i][j] = new Complex();
            }
        }
        for (int i = 0; i < 5120 + 1024; i++) {
            fftXkDataIb[i] = new Complex();
        }
    }
    
    /**
     * 200ms数据计算
     * 对应C代码：pqs_200ms_data_cal
     */
    public static void pqs200msDataCal(DataPq pqsBuf, ClockStruct dataTime, int smpWrPoint) {
        log.debug("开始200ms计算 - 接线方式: {} ({})", 
            pqsBuf.getCfg().getLineConfig(), 
            pqsBuf.getCfg().getLineConfig() == 0 ? "星型" : "V型");
        
        /*
         * 局部变量声明（严格对应C代码）
         * 为确保与原C代码计算结果的一致性，这里的变量声明完全按照C代码结构
         */
        
        // FFT和采样相关变量
        int[][] fftSmpdataBuf = new int[8][5120 + 1024];
        Complex[] xkData;
        Complex[] vec = new Complex[8];
        Complex seq = new Complex();
        PqsDataStruct pqsDat;
        long intRms;
        long[] intUi = new long[3];
        int divNum;
        int pqsHarmTimes;
        int smpPoint;
        
        // 通道索引和计算参数
        int a, b, c, flagAddIb, flagAddUharm;
        int i, j, k, ch, chNum, num, smpdata;
        int uaIdx, ubIdx, ucIdx, iaIdx, ibIdx, icIdx;
        int FFT_N_NUM, curFreq;
        float smpRate;
        
        // 谐波计算相关变量
        float[] harmRmsVal = new float[6];
        float harmA, harmB, harmC;
        float frA, fxA, frB, fxB, frC, fxC;
        float ftemp, ffreq, rms, ang, con;
        float harmRms, iharmRms, Un, Ux, uiXs;
        float ang1Ref = 0, uiMkVal = 0;
        float[] oharm = new float[8];
        float[] eharm = new float[8];
        boolean ang1Flg = false;
        boolean[] angFlg = new boolean[128];
        
        // 功率计算相关变量
        float[] S = new float[5];
        float[] P = new float[5];
        float[] Q = new float[5];
        float[] STotal = new float[5];
        float[] PTotal = new float[5];
        float[] QTotal = new float[5];
        float fw;
        float[] fwu = new float[4];
        float[] fws = new float[4];
        float fvar;
        float[] fvaru = new float[4];
        float[] fvars = new float[4];
        float fva;
        float[] fvau = new float[4];
        float[] fvas = new float[4];
        float diffIuAng = 0;
        float[] angRef = new float[128];
        float tempA, tempB, tempV = 0;
        
        // 初始化vec数组
        for (i = 0; i < 8; i++) {
            vec[i] = new Complex();
        }
        
        // 清零标志数组
        for (i = 0; i < 128; i++) {
            angFlg[i] = false;
        }
        
        smpRate = pqsBuf.getSmpRate();
        pqsDat = pqsBuf.getPqData()[pqsBuf.getDataPoint()];
        
        /*
         * 数据准备阶段
         * smpRate是每周波采样点数，乘以10得到10周波（200ms）的采样点数
         * 计算采样起始点，确保获取完整的10周波数据
         */
        smpPoint = smpWrPoint + pqsBuf.getSmpNum() - (int)(pqsBuf.getSmpRate() * 10);
        if (smpPoint >= pqsBuf.getSmpNum()) {
            smpPoint -= pqsBuf.getSmpNum();
        }
        if (smpPoint < 0) {
            smpPoint += pqsBuf.getSmpNum();
        }
        
        // 通道索引映射：UA、UB、UC、IA、IB、IC
        uaIdx = 0;
        ubIdx = 1;
        ucIdx = 2;
        iaIdx = 3;
        ibIdx = 4;
        icIdx = 5;
        
        // FFT参数设置：10个周波的采样点数
        FFT_N_NUM = (int)smpRate * 10;
        divNum = 1;
        
        // 标志位设置：是否合成IB相
        flagAddIb = 0;
        if (pqsBuf.getCfg().getIbAdd() == 1) {
            flagAddIb = 1;
        }
        
        // 标志位设置：是否合成线电压谐波
        flagAddUharm = 0;
        if (pqsBuf.getCfg().getUharmAdd() == 1) {
            flagAddUharm = 1;
        }
        
        // 复制采样数据
        for (i = 0; i < FFT_N_NUM; i++) {
            // 添加边界检查 - 使用smpNum而不是数组长度
            if (smpPoint < 0 || smpPoint >= pqsBuf.getSmpNum()) {
                throw new ArrayIndexOutOfBoundsException(
                    String.format("smpPoint越界: smpPoint=%d, smpNum=%d, i=%d, FFT_N_NUM=%d, smpRate=%f, smpWrPoint=%d", 
                        smpPoint, pqsBuf.getSmpNum(), i, FFT_N_NUM, pqsBuf.getSmpRate(), smpWrPoint));
            }
            
            fftSmpdataBuf[0][i] = pqsBuf.getSmpData()[uaIdx][smpPoint];
            fftSmpdataBuf[1][i] = pqsBuf.getSmpData()[ubIdx][smpPoint];
            fftSmpdataBuf[2][i] = pqsBuf.getSmpData()[ucIdx][smpPoint];
            fftSmpdataBuf[3][i] = pqsBuf.getSmpData()[iaIdx][smpPoint];
            fftSmpdataBuf[4][i] = pqsBuf.getSmpData()[ibIdx][smpPoint];
            fftSmpdataBuf[5][i] = pqsBuf.getSmpData()[icIdx][smpPoint];
            
            if (flagAddIb == 1) {
                fftSmpdataBuf[4][i] = (0 - fftSmpdataBuf[3][i]);
                fftSmpdataBuf[4][i] += (0 - fftSmpdataBuf[5][i]);
            }
            
            smpPoint = smpPoint + divNum;
            if (smpPoint >= pqsBuf.getSmpNum()) {
                smpPoint -= pqsBuf.getSmpNum();
            }
        }
        
        // 谐波计算次数
        pqsHarmTimes = pqsBuf.getCfg().getHarmTime();
        
        // 断言：谐波次数必须大于0，这样确保uiMkVal会被初始化
        // C代码假设pqsHarmTimes至少为1，否则uiMkVal未初始化
        assert pqsHarmTimes > 0 : "谐波计算次数必须大于0";
        
        // 运行时检查（即使断言未启用也会执行）
        if (pqsHarmTimes <= 0) {
            throw new IllegalArgumentException("谐波计算次数必须大于0，当前值：" + pqsHarmTimes);
        }
        
        // FFT计算
         for (i = 0; i < MAX_CH_NUM; i++) {
            smpPoint = smpWrPoint + pqsBuf.getSmpNum() - (int)(pqsBuf.getSmpRate() * 10);
            if (smpPoint >= pqsBuf.getSmpNum()) {
                smpPoint -= pqsBuf.getSmpNum();
            }
            // 注意：C代码这里看起来有bug，div_num总是1
            // C代码中divNum计算结果总是1：(int)pqsBuf.getSmpRate() / (int)pqsBuf.getSmpRate() = 1
            divNum = 1;
            
            for (j = 0; j < FFT_N_NUM; j++) {
                fftXkData[i][j].setReal((float)pqsBuf.getSmpData()[i][smpPoint]);
                fftXkData[i][j].setImag(0);
                smpPoint = smpPoint + divNum;
                if (smpPoint >= pqsBuf.getSmpNum()) {
                    smpPoint -= pqsBuf.getSmpNum();
                }
            }
            
            FFTProcessor.fftCal(fftXkData[i], FFT_N_NUM);
        }
        
        // 谐波分析
        for (ch = 0; ch < MAX_CH_NUM; ch++) {
            uiXs = pqsBuf.getUiGainXs()[ch];
            xkData = fftXkData[ch];
            
            // 合成IB相
            if ((flagAddIb == 1) && (ch == 4)) {
                for (i = 0; i < FFT_N_NUM; i++) {
                    fftXkDataIb[i].setReal(0 - (fftXkData[3][i].getReal() + fftXkData[5][i].getReal()));
                    fftXkDataIb[i].setImag(0 - (fftXkData[3][i].getImag() + fftXkData[5][i].getImag()));
                }
                xkData = fftXkDataIb;
            }
            
            // 计算基波矢量，对应基波频点（索引10）
            vec[ch].setReal(xkData[10].getReal() * uiXs);
            vec[ch].setImag(xkData[10].getImag() * uiXs);
            
            /*
             * 谐波分析计算
             * 采用子组方式计算谐波有效值，包含主频点及其邻近频点
             */
            harmRms = 0;
            iharmRms = 0;
            for (i = 10, num = 0; num < pqsHarmTimes; i += 10, num++) {
                /*
                 * 谐波有效值计算（子组方式）
                 * 包含主频点(i)及其左右邻近频点(i-1, i+1)的能量
                 */
                rms = sqrt(
                    xkData[i].getReal() * xkData[i].getReal() + xkData[i].getImag() * xkData[i].getImag() +
                    xkData[i - 1].getReal() * xkData[i - 1].getReal() + xkData[i - 1].getImag() * xkData[i - 1].getImag() +
                    xkData[i + 1].getReal() * xkData[i + 1].getReal() + xkData[i + 1].getImag() * xkData[i + 1].getImag()
                ) * uiXs;
                
                if (num > 0) {
                    harmRms += (rms * rms);
                }
                
                /*
                 * 谐波相位检测
                 * 根据通道类型设置检测门限：电压通道和线电压使用Un，电流通道使用In
                 */
                if ((ch < 3) || (ch == 6)) {
                    uiMkVal = 0.001f * pqsBuf.getUn();
                } else {
                    uiMkVal = 0.001f * pqsBuf.getIn();
                }
                
                if (rms > uiMkVal) {
                    // 计算谐波相位角度，转换为度数
                    ang = 360.0f * atan2(xkData[i].getImag(), xkData[i].getReal()) / (2 * PI);
                    
                    // 电流通道进行相位同步修正
                    if (ch >= 3) {
                        ang = ang - diffIuAng * (num + 1);
                    }
                    
                    // 设置相位基准（仅对基波进行一次）
                    if ((!ang1Flg) && (num == 0)) {
                        ang1Ref = ang;
                        ang1Flg = true;
                    }
                    
                    // 相位基准校正和90度偏移校正
                    ang = ang - ang1Ref * (num + 1) - num * 90;
                } else {
                    ang = 0;
                }
                
                // 将角度限制在-180到180度范围内
                while (ang > 180) {
                    ang = ang - 360;
                }
                while (ang < -180) {
                    ang = ang + 360;
                }
                
                // 存储谐波有效值和相位
                pqsDat.getFuHarm()[ch][num] = rms;
                pqsDat.getFuHarmPhase()[ch][num] = ang;
                
                /*
                 * 谐波含有率计算
                 * 设置基波门限：电压通道0.5V，电流通道0.01A
                 */
                if ((ch < 3) || (ch == 6)) {
                    uiMkVal = 0.500f;
                } else {
                    uiMkVal = 0.010f;
                }
                
                // 计算谐波含有率（谐波/基波 * 100%）
                if (pqsDat.getFuHarm()[ch][0] > uiMkVal) {
                    con = pqsDat.getFuHarm()[ch][num] * 100 / pqsDat.getFuHarm()[ch][0];
                } else {
                    con = 0;
                }
                if (con > 300) {
                    con = 300;
                }
                pqsDat.getFuHarmCON()[ch][num] = con;
                
                /*
                 * 间谐波有效值计算
                 * 统计谐波频点周围的非整次谐波分量能量
                 */
                rms = 0;
                for (j = 2; j < 9; j++) {
                    ftemp = xkData[i - j].getReal() * xkData[i - j].getReal() + 
                            xkData[i - j].getImag() * xkData[i - j].getImag();
                    
                    // 根据通道类型设置不同的门限值
                    if ((ftemp > 0.003) && (i < 3)) {
                        rms += ftemp;
                    }
                    if ((ftemp > 0.001) && (i >= 3)) {
                        rms += ftemp;
                    }
                }
                pqsDat.getInHarm()[ch][num] = sqrt(rms) * uiXs;
                iharmRms += (pqsDat.getInHarm()[ch][num] * pqsDat.getInHarm()[ch][num]);
                
                // 计算间谐波含有率
                if (pqsDat.getFuHarm()[ch][0] > uiMkVal) {
                    con = pqsDat.getInHarm()[ch][num] * 100 / pqsDat.getFuHarm()[ch][0];
                } else {
                    con = 0;
                }
                if (con > 300) {
                    con = 300;
                }
                pqsDat.getInHarmCON()[ch][num] = con;
            }
            
            /*
             * 总谐波畸变率计算
             * THD = 所有谐波RMS / 基波RMS * 100%
             */
            pqsDat.getIHarmRMS()[ch] = sqrt(iharmRms);
            pqsDat.getHarmRMS()[ch] = sqrt(harmRms);
            
            // 计算总谐波畸变率THD
            if (pqsDat.getFuHarm()[ch][0] > uiMkVal) {
                con = pqsDat.getHarmRMS()[ch] * 100 / pqsDat.getFuHarm()[ch][0];
            } else {
                con = 0;
            }
            if (con > 300) {
                con = 300;
            }
            pqsDat.getHarmTHD()[ch] = con;
        }
        
        /*
         * 有效值计算（6通道相电压和相电流）
         * 采用时域均方根计算方法
         */
        for (ch = 0; ch < MAX_CH_NUM; ch++) {
            uiXs = pqsBuf.getUiGainXs()[ch];
            intRms = 0;
            for (i = 0; i < FFT_N_NUM; i++) {
                smpdata = fftSmpdataBuf[ch][i];
                intRms += (((long)smpdata) * smpdata);
            }
            rms = sqrt((float)intRms / FFT_N_NUM);
            rms = rms * uiXs;
            pqsDat.getRms()[ch] = rms;
        }
        
        /*
         * 线电压计算（UAB、UBC、UCA）
         * 线电压 = 相电压差值的有效值
         */
        for (i = 0; i < 3; i++) {
            intUi[i] = 0;
        }
        for (i = 0; i < FFT_N_NUM; i++) {
            // 读取三相电压采样数据
            // UA相电压
            a = fftSmpdataBuf[0][i];
            // UB相电压  
            b = fftSmpdataBuf[1][i];
            // UC相电压
            c = fftSmpdataBuf[2][i];
            
            // 计算线电压：UAB = UA - UB
            smpdata = (a - b);
            intUi[0] += (((long)smpdata) * smpdata);
            
            // 计算线电压：UBC = UB - UC
            smpdata = (b - c);
            intUi[1] += (((long)smpdata) * smpdata);
            
            // 计算线电压：UCA = UC - UA
            smpdata = (c - a);
            intUi[2] += (((long)smpdata) * smpdata);
        }
        
        // 存储线电压有效值
        // UAB线电压
        rms = sqrt(intUi[0] / FFT_N_NUM) * pqsBuf.getUiGainXs()[0];
        pqsDat.getRms()[6] = rms;
        // UBC线电压
        rms = sqrt(intUi[1] / FFT_N_NUM) * pqsBuf.getUiGainXs()[1];
        pqsDat.getRms()[7] = rms;
        // UCA线电压
        rms = sqrt(intUi[2] / FFT_N_NUM) * pqsBuf.getUiGainXs()[2];
        pqsDat.getRms()[8] = rms;
        
        // V型接线特殊处理：线电压直接使用相电压值
        if (pqsBuf.getCfg().getLineConfig() == 1) {
            pqsDat.getRms()[6] = pqsDat.getRms()[0];
            pqsDat.getRms()[7] = pqsDat.getRms()[1];
            pqsDat.getRms()[8] = pqsDat.getRms()[2];
            log.debug("V型接线 - 线电压RMS值已更新");
        } else {
            log.debug("星型接线 - 保持原始线电压RMS值");
        }
        
        // 电压偏差计算
        uDevCal(pqsBuf, pqsDat);
        
        // 序分量计算
        sequenceComponentCal(pqsDat, vec);
        
        // 功率计算
        powerCalculation(pqsDat, pqsBuf);
        
        // 线电压谐波计算
        if (flagAddUharm == 1) {
            lineVoltageHarmonicCal(pqsDat, pqsHarmTimes, pqsBuf);
        }
        
        // 奇偶次谐波畸变率计算
        oddEvenHarmonicCal(pqsDat, pqsHarmTimes, pqsBuf);
        
        /*
         * 频率计算
         * 使用A相电压数据进行频率检测
         */
        ftemp = LibraryFunctions.smpToFreq(
            pqsBuf.getSmpData()[0], 
            (int)smpRate, 
            (int)(smpRate * 10)
        );
        // 实际频率值
        pqsDat.getFreq()[0] = ftemp;
        // 频率偏差（相对于50Hz基准）        
        pqsDat.getFreq()[1] = ftemp - 50;
        
        // 更新数据指针和时间戳
        pqsBuf.setDataPoint(pqsBuf.getDataPoint() + 1);
        pqsDat.setClocktime(dataTime);
    }
    
    /**
     * 电压偏差计算
     * 对应C代码：U_Dev_cal
     */
    private static void uDevCal(DataPq pqsBuf, PqsDataStruct pqsDat) {
        int ch, rmsC;
        float Ux, Un, Udin;
        
        // 额定电压Udin
        Ux = pqsBuf.getUn();
        if ((Ux < 10) || (Ux > 500)) {
            Ux = 100;
        }
        
        // 根据接线方式计算相电压标准值
        if (pqsBuf.getCfg().getLineConfig() == 0) {
            // 星型接线：相电压 = 线电压 / √3
            Un = Ux * 0.57735f;
        } else {
            // V型接线：相电压 = 线电压
            Un = Ux;
        }
        
        // 电压偏差计算
        for (ch = 0; ch < 6; ch++) {
            if (ch < 3) {
                rmsC = ch + 0;
                Udin = Un;
            } else {
                rmsC = ch + 3;
                Udin = Ux;
            }
            
            // 正偏差和负偏差RMS记录
            if (pqsDat.getRms()[rmsC] >= Udin) {
                pqsDat.getRmsPos()[ch] = pqsDat.getRms()[rmsC];
            } else {
                pqsDat.getRmsPos()[ch] = Udin;
            }
            
            if (pqsDat.getRms()[rmsC] <= Udin) {
                pqsDat.getRmsNeg()[ch] = pqsDat.getRms()[rmsC];
            } else {
                pqsDat.getRmsNeg()[ch] = Udin;
            }
            
            pqsDat.getUDev()[ch] = 0;
            pqsDat.getUPosDev()[ch] = 0;
            pqsDat.getUNegDev()[ch] = 0;
            
            if (pqsDat.getRms()[rmsC] > 0.5) {
                pqsDat.getUDev()[ch] = (pqsDat.getRms()[rmsC] - Udin) * 100 / Udin;
            }
            if (pqsDat.getRmsPos()[ch] > 0.5) {
                pqsDat.getUPosDev()[ch] = (pqsDat.getRmsPos()[ch] - Udin) * 100 / Udin;
            }
            if (pqsDat.getRmsNeg()[ch] > 0.5) {
                pqsDat.getUNegDev()[ch] = (Udin - pqsDat.getRmsNeg()[ch]) * 100 / Udin;
            }
        }
    }
    
    /**
     * 序分量计算
     * 对应C代码中的序分量计算部分
     */
    private static void sequenceComponentCal(PqsDataStruct pqsDat, Complex[] vec) {
        Complex seq = new Complex();
        float rms;
        
        /*
         * 电压序分量计算
         * 零序分量：u0 = (ua + ub + uc) / 3
         */
        seq.setReal(vec[0].getReal() + vec[1].getReal() + vec[2].getReal());
        seq.setImag(vec[0].getImag() + vec[1].getImag() + vec[2].getImag());
        rms = sqrt(seq.getReal() * seq.getReal() + seq.getImag() * seq.getImag()) * (1.0f / 3.0f);
        pqsDat.getUiSeq()[0][0] = rms;
        
        /*
         * 正序分量：u1 = (ua + ub*a + uc*a²) / 3
         * 其中a = e^(j2π/3) = -0.5 + j0.866
         */
        seq.setReal(vec[0].getReal() + 
                   (vec[1].getReal() * (-0.5f) - vec[1].getImag() * 0.866f) + 
                   (vec[2].getReal() * (-0.5f) - vec[2].getImag() * (-0.866f)));
        seq.setImag(vec[0].getImag() + 
                   (vec[1].getImag() * (-0.5f) + vec[1].getReal() * 0.866f) + 
                   (vec[2].getImag() * (-0.5f) + vec[2].getReal() * (-0.866f)));
        rms = sqrt(seq.getReal() * seq.getReal() + seq.getImag() * seq.getImag()) * (1.0f / 3.0f);
        pqsDat.getUiSeq()[0][1] = rms;
        
        /*
         * 负序分量：u2 = (ua + uc*a + ub*a²) / 3
         * 交换ub和uc的位置
         */
        seq.setReal(vec[0].getReal() + 
                   (vec[2].getReal() * (-0.5f) - vec[2].getImag() * 0.866f) + 
                   (vec[1].getReal() * (-0.5f) - vec[1].getImag() * (-0.866f)));
        seq.setImag(vec[0].getImag() + 
                   (vec[2].getImag() * (-0.5f) + vec[2].getReal() * 0.866f) + 
                   (vec[1].getImag() * (-0.5f) + vec[1].getReal() * (-0.866f)));
        rms = sqrt(seq.getReal() * seq.getReal() + seq.getImag() * seq.getImag()) * (1.0f / 3.0f);
        pqsDat.getUiSeq()[0][2] = rms;
        
        // 不平衡度
        pqsDat.getUiSeq()[0][3] = 0;
        pqsDat.getUiSeq()[0][4] = 0;
        if (pqsDat.getUiSeq()[0][1] > 0.5) {
            pqsDat.getUiSeq()[0][3] = pqsDat.getUiSeq()[0][0] * 100 / pqsDat.getUiSeq()[0][1];
            pqsDat.getUiSeq()[0][4] = pqsDat.getUiSeq()[0][2] * 100 / pqsDat.getUiSeq()[0][1];
            if (pqsDat.getUiSeq()[0][3] > 1000) {
                pqsDat.getUiSeq()[0][3] = 100;
            }
            if (pqsDat.getUiSeq()[0][4] > 1000) {
                pqsDat.getUiSeq()[0][4] = 100;
            }
        }
        
        // 电流序分量（类似计算）
        // 零序分量
        seq.setReal(vec[3].getReal() + vec[4].getReal() + vec[5].getReal());
        seq.setImag(vec[3].getImag() + vec[4].getImag() + vec[5].getImag());
        rms = sqrt(seq.getReal() * seq.getReal() + seq.getImag() * seq.getImag()) * (1.0f / 3.0f);
        pqsDat.getUiSeq()[1][0] = rms;
        
        // 正序分量
        seq.setReal(vec[3].getReal() + 
                   (vec[4].getReal() * (-0.5f) - vec[4].getImag() * 0.866f) + 
                   (vec[5].getReal() * (-0.5f) - vec[5].getImag() * (-0.866f)));
        seq.setImag(vec[3].getImag() + 
                   (vec[4].getImag() * (-0.5f) + vec[4].getReal() * 0.866f) + 
                   (vec[5].getImag() * (-0.5f) + vec[5].getReal() * (-0.866f)));
        rms = sqrt(seq.getReal() * seq.getReal() + seq.getImag() * seq.getImag()) * (1.0f / 3.0f);
        pqsDat.getUiSeq()[1][1] = rms;
        
        // 负序分量
        seq.setReal(vec[3].getReal() + 
                   (vec[5].getReal() * (-0.5f) - vec[5].getImag() * 0.866f) + 
                   (vec[4].getReal() * (-0.5f) - vec[4].getImag() * (-0.866f)));
        seq.setImag(vec[3].getImag() + 
                   (vec[5].getImag() * (-0.5f) + vec[5].getReal() * 0.866f) + 
                   (vec[4].getImag() * (-0.5f) + vec[4].getReal() * (-0.866f)));
        rms = sqrt(seq.getReal() * seq.getReal() + seq.getImag() * seq.getImag()) * (1.0f / 3.0f);
        pqsDat.getUiSeq()[1][2] = rms;
        
        // 不平衡度
        pqsDat.getUiSeq()[1][3] = 0;
        pqsDat.getUiSeq()[1][4] = 0;
        if (pqsDat.getUiSeq()[1][1] > 0.1) {
            pqsDat.getUiSeq()[1][3] = pqsDat.getUiSeq()[1][0] * 100 / pqsDat.getUiSeq()[1][1];
            pqsDat.getUiSeq()[1][4] = pqsDat.getUiSeq()[1][2] * 100 / pqsDat.getUiSeq()[1][1];
            if (pqsDat.getUiSeq()[1][3] > 1000) {
                pqsDat.getUiSeq()[1][3] = 100;
            }
            if (pqsDat.getUiSeq()[1][4] > 1000) {
                pqsDat.getUiSeq()[1][4] = 100;
            }
        }
    }
    
    /**
     * 功率计算
     */
    private static void powerCalculation(PqsDataStruct pqsDat, DataPq pqsBuf) {
        float[] S = new float[5];
        float[] P = new float[5];
        float[] Q = new float[5];
        float[] STotal = new float[5];
        float[] PTotal = new float[5];
        float[] QTotal = new float[5];
        int pqsHarmTimes = pqsBuf.getCfg().getHarmTime();
        
        // 清零总功率
        for (int j = 0; j < 4; j++) {
            STotal[j] = 0;
            PTotal[j] = 0;
            QTotal[j] = 0;
        }
        
        // 各次谐波功率计算
        for (int i = 0; i < pqsHarmTimes; i++) {
            S[0] = pqsDat.getFuHarm()[0][i] * pqsDat.getFuHarm()[3][i];
            S[1] = pqsDat.getFuHarm()[1][i] * pqsDat.getFuHarm()[4][i];
            S[2] = pqsDat.getFuHarm()[2][i] * pqsDat.getFuHarm()[5][i];
            // 三相总视在功率
            S[3] = S[0] + S[1] + S[2];
            
            // 根据接线方式计算功率
            if (pqsBuf.getCfg().getLineConfig() == 0) {
                P[0] = S[0] * cos((PI / 180) * (pqsDat.getFuHarmPhase()[0][i] - pqsDat.getFuHarmPhase()[3][i]));
                P[1] = S[1] * cos((PI / 180) * (pqsDat.getFuHarmPhase()[1][i] - pqsDat.getFuHarmPhase()[4][i]));
                P[2] = S[2] * cos((PI / 180) * (pqsDat.getFuHarmPhase()[2][i] - pqsDat.getFuHarmPhase()[5][i]));
                P[3] = P[0] + P[1] + P[2];
                
                Q[0] = S[0] * sin((PI / 180) * (pqsDat.getFuHarmPhase()[0][i] - pqsDat.getFuHarmPhase()[3][i]));
                Q[1] = S[1] * sin((PI / 180) * (pqsDat.getFuHarmPhase()[1][i] - pqsDat.getFuHarmPhase()[4][i]));
                Q[2] = S[2] * sin((PI / 180) * (pqsDat.getFuHarmPhase()[2][i] - pqsDat.getFuHarmPhase()[5][i]));
                Q[3] = Q[0] + Q[1] + Q[2];
            } else {
                // V型接线功率计算：UAB*IA + UCB*IC
                P[0] = S[0] * cos((PI / 180) * (pqsDat.getFuHarmPhase()[0][i] - pqsDat.getFuHarmPhase()[3][i]));
                P[1] = 0;
                P[2] = S[2] * cos((PI / 180) * (pqsDat.getFuHarmPhase()[1][i] - pqsDat.getFuHarmPhase()[5][i] - 180));
                P[3] = P[0] + P[1] + P[2];
                
                Q[0] = S[0] * sin((PI / 180) * (pqsDat.getFuHarmPhase()[0][i] - pqsDat.getFuHarmPhase()[3][i]));
                Q[1] = 0;
                Q[2] = S[2] * sin((PI / 180) * (pqsDat.getFuHarmPhase()[1][i] - pqsDat.getFuHarmPhase()[5][i] - 180));
                Q[3] = Q[0] + Q[1] + Q[2];
                
                // 视在功率重新计算
                S[1] = 0;
                S[3] = sqrt((P[0] + P[2]) * (P[0] + P[2]) + (Q[0] + Q[2]) * (Q[0] + Q[2]));
            }
            
            for (int j = 0; j < 4; j++) {
                PTotal[j] += P[j];
                QTotal[j] += Q[j];
                STotal[j] += S[j];
                // 第i次谐波有功功率
                pqsDat.getHarmP()[j][i] = P[j];
                // 第i次谐波无功功率
                pqsDat.getHarmQ()[j][i] = Q[j];
                // 第i次谐波视在功率
                pqsDat.getHarmS()[j][i] = S[j];
            }
        }
        
        for (int j = 0; j < 4; j++) {
            // 各次谐波总有功功率
            pqsDat.getTotalP()[j] = PTotal[j];
            // 各次谐波总无功功率
            pqsDat.getTotalQ()[j] = QTotal[j];
            // 各次谐波总视在功率
            pqsDat.getTotalS()[j] = STotal[j];
            
            // 计算功率因数：P/S
            if (pqsDat.getTotalS()[j] > 0.1) {
                pqsDat.getCosPF()[j] = pqsDat.getTotalP()[j] / pqsDat.getTotalS()[j];
            } else {
                pqsDat.getCosPF()[j] = 1;
            }
            
            // 计算位移功率因数：P1/S1（基波功率因数）
            if (pqsDat.getHarmS()[j][0] > 0.1) {
                pqsDat.getCosDF()[j] = pqsDat.getHarmP()[j][0] / pqsDat.getHarmS()[j][0];
            } else {
                pqsDat.getCosDF()[j] = 1;
            }
        }
        
        // 谐波功率统计
        harmonicPowerStatistics(pqsDat, pqsHarmTimes);
    }
    
    /**
     * 谐波功率统计
     */
    private static void harmonicPowerStatistics(PqsDataStruct pqsDat, int pqsHarmTimes) {
        float[] fws = new float[4];
        float[] fwu = new float[4];
        float[] fvars = new float[4];
        float[] fvaru = new float[4];
        float[] fvas = new float[4];
        float[] fvau = new float[4];
        
        // 清零
        for (int i = 0; i < 4; i++) {
            fws[i] = 0;
            fwu[i] = 0;
            fvars[i] = 0;
            fvaru[i] = 0;
            fvas[i] = 0;
            fvau[i] = 0;
        }
        
        // 统计各谐波功率
        for (int i = 0; i < 3; i++) {
            for (int k = 1; k < pqsHarmTimes; k++) {
                float fw = pqsDat.getHarmP()[i][k];
                fws[i] += fw;
                if (fw < 0) {
                    fw = 0 - fw;
                }
                fwu[i] += fw;
                
                float fvar = pqsDat.getHarmQ()[i][k];
                fvars[i] += fvar;
                if (fvar < 0) {
                    fvar = 0 - fvar;
                }
                fvaru[i] += fvar;
                
                float fva = pqsDat.getHarmS()[i][k];
                fvas[i] += fva;
                if (fva < 0) {
                    fva = 0 - fva;
                }
                fvau[i] += fva;
            }
        }
        
        for (int i = 0; i < 3; i++) {
            pqsDat.getHwTotalS()[i] = fws[i];
            pqsDat.getHwTotalU()[i] = fwu[i];
            pqsDat.getHvarTotalS()[i] = fvars[i];
            pqsDat.getHvarTotalU()[i] = fvaru[i];
            pqsDat.getHvaTotalS()[i] = fvas[i];
            pqsDat.getHvaTotalU()[i] = fvau[i];
        }
        
        // 总计
        pqsDat.getHwTotalS()[3] = pqsDat.getHwTotalS()[0] + pqsDat.getHwTotalS()[1] + pqsDat.getHwTotalS()[2];
        pqsDat.getHwTotalU()[3] = pqsDat.getHwTotalU()[0] + pqsDat.getHwTotalU()[1] + pqsDat.getHwTotalU()[2];
        pqsDat.getHvarTotalS()[3] = pqsDat.getHvarTotalS()[0] + pqsDat.getHvarTotalS()[1] + pqsDat.getHvarTotalS()[2];
        pqsDat.getHvarTotalU()[3] = pqsDat.getHvarTotalU()[0] + pqsDat.getHvarTotalU()[1] + pqsDat.getHvarTotalU()[2];
        pqsDat.getHvaTotalS()[3] = pqsDat.getHvaTotalS()[0] + pqsDat.getHvaTotalS()[1] + pqsDat.getHvaTotalS()[2];
        pqsDat.getHvaTotalU()[3] = pqsDat.getHvaTotalU()[0] + pqsDat.getHvaTotalU()[1] + pqsDat.getHvaTotalU()[2];
    }
    
    /**
     * 线电压谐波计算
     */
    private static void lineVoltageHarmonicCal(PqsDataStruct pqsDat, int pqsHarmTimes, DataPq pqsBuf) {
        float[] harmRmsVal = new float[6];
        float harmA, harmB, harmC;
        float frA, fxA, frB, fxB, frC, fxC;
        float con;
        float uiMkVal = 0.100f;
        int i, ch;
        
        for (i = 0; i < pqsHarmTimes; i++) {
            // 谐波幅值
            harmA = pqsDat.getFuHarm()[0][i];
            harmB = pqsDat.getFuHarm()[1][i];
            harmC = pqsDat.getFuHarm()[2][i];
            frA = harmA * cos((PI / 180) * pqsDat.getFuHarmPhase()[0][i]);
            fxA = harmA * sin((PI / 180) * pqsDat.getFuHarmPhase()[0][i]);
            frB = harmB * cos((PI / 180) * pqsDat.getFuHarmPhase()[1][i]);
            fxB = harmB * sin((PI / 180) * pqsDat.getFuHarmPhase()[1][i]);
            frC = harmC * cos((PI / 180) * pqsDat.getFuHarmPhase()[2][i]);
            fxC = harmC * sin((PI / 180) * pqsDat.getFuHarmPhase()[2][i]);
            harmA = sqrt(((frA - frB) * (frA - frB)) + ((fxA - fxB) * (fxA - fxB)));
            harmB = sqrt(((frB - frC) * (frB - frC)) + ((fxB - fxC) * (fxB - fxC)));
            harmC = sqrt(((frC - frA) * (frC - frA)) + ((fxC - fxA) * (fxC - fxA)));
            pqsDat.getPpvFuHarm()[0][i] = harmA;
            pqsDat.getPpvFuHarm()[1][i] = harmB;
            pqsDat.getPpvFuHarm()[2][i] = harmC;
            
            // 谐波含有率、谐波有效值
            for (ch = 0; ch < 3; ch++) {
                if (pqsDat.getPpvFuHarm()[ch][0] > uiMkVal) {
                    con = pqsDat.getPpvFuHarm()[ch][i] * 100 / pqsDat.getPpvFuHarm()[ch][0];
                } else {
                    con = 0;
                }
                if (con > 300) {
                    con = 300;
                }
                pqsDat.getPpvFuHarmCON()[ch][i] = con;
                if (i != 0) {
                    harmRmsVal[ch] += (pqsDat.getPpvFuHarm()[ch][i] * pqsDat.getPpvFuHarm()[ch][i]);
                } else {
                    harmRmsVal[ch] = 0;
                }
            }
        }
        
        // V型接线特殊处理
        if (pqsBuf.getCfg().getLineConfig() == 1) {
            for (i = 0; i < pqsHarmTimes; i++) {
                for (ch = 0; ch < 3; ch++) {
                    pqsDat.getPpvFuHarm()[ch][i] = pqsDat.getFuHarm()[ch][i];
                    pqsDat.getPpvFuHarmCON()[ch][i] = pqsDat.getFuHarmCON()[ch][i];
                }
            }
        }
        
        // 谐波总有效值、总畸变率
        for (ch = 0; ch < 3; ch++) {
            pqsDat.getPpvHarmRMS()[ch] = sqrt(harmRmsVal[ch]);
            if (pqsDat.getPpvFuHarm()[ch][0] > uiMkVal) {
                con = pqsDat.getPpvHarmRMS()[ch] * 100 / pqsDat.getPpvFuHarm()[ch][0];
            } else {
                con = 0;
            }
            if (con > 300) {
                con = 300;
            }
            pqsDat.getPpvHarmTHD()[ch] = con;
        }
    }
    
    /**
     * 奇偶次谐波畸变率计算
     */
    private static void oddEvenHarmonicCal(PqsDataStruct pqsDat, int pqsHarmTimes, DataPq pqsBuf) {
        float[] oharm = new float[6];
        float[] eharm = new float[6];
        float uiMkVal;
        float fw;
        
        // 清零
        for (int i = 0; i < 6; i++) {
            oharm[i] = 0;
            eharm[i] = 0;
        }
        
        // 相电压和电流
        for (int i = 0; i < 6; i++) {
            if ((i < 3) || (i == 6)) {
                uiMkVal = 0.10f;
            } else {
                uiMkVal = 0.01f;
            }
            
            // 奇次
            for (int k = 1; k < (pqsHarmTimes / 2); k++) {
                fw = pqsDat.getFuHarm()[i][2 * k];
                oharm[i] += fw * fw;
            }
            
            // 偶次
            for (int k = 0; k < (pqsHarmTimes / 2); k++) {
                fw = pqsDat.getFuHarm()[i][2 * k + 1];
                eharm[i] += fw * fw;
            }
            
            if (pqsDat.getFuHarm()[i][0] > uiMkVal) {
                oharm[i] = sqrt(oharm[i]) / pqsDat.getFuHarm()[i][0];
            } else {
                oharm[i] = 0;
            }
            if (oharm[i] > 10) {
                oharm[i] = 1;
            }
            
            if (pqsDat.getFuHarm()[i][0] > uiMkVal) {
                eharm[i] = sqrt(eharm[i]) / pqsDat.getFuHarm()[i][0];
            } else {
                eharm[i] = 0;
            }
            if (eharm[i] > 10) {
                eharm[i] = 1;
            }
            
            pqsDat.getHarmOTHD()[i] = oharm[i] * 100;
            pqsDat.getHarmETHD()[i] = eharm[i] * 100;
        }
        
        // 线电压奇偶次谐波畸变率
        for (int i = 0; i < 6; i++) {
            oharm[i] = 0;
            eharm[i] = 0;
        }
        
        for (int i = 0; i < 3; i++) {
            if ((i < 3) || (i == 6)) {
                uiMkVal = 0.10f;
            } else {
                uiMkVal = 0.01f;
            }
            
            // 奇次
            for (int k = 1; k < (pqsHarmTimes / 2); k++) {
                fw = pqsDat.getPpvFuHarm()[i][2 * k];
                oharm[i] += fw * fw;
            }
            
            // 偶次
            for (int k = 0; k < (pqsHarmTimes / 2); k++) {
                fw = pqsDat.getPpvFuHarm()[i][2 * k + 1];
                eharm[i] += fw * fw;
            }
            
            if (pqsDat.getPpvFuHarm()[i][0] > uiMkVal) {
                oharm[i] = sqrt(oharm[i]) / pqsDat.getPpvFuHarm()[i][0];
            } else {
                oharm[i] = 0;
            }
            if (oharm[i] > 10) {
                oharm[i] = 1;
            }
            
            if (pqsDat.getPpvFuHarm()[i][0] > uiMkVal) {
                eharm[i] = sqrt(eharm[i]) / pqsDat.getPpvFuHarm()[i][0];
            } else {
                eharm[i] = 0;
            }
            if (eharm[i] > 10) {
                eharm[i] = 1;
            }
            
            pqsDat.getPpvHarmOTHD()[i] = oharm[i] * 100;
            pqsDat.getPpvHarmETHD()[i] = eharm[i] * 100;
        }
        
        // 相电压谐波转线电压谐波
        if (pqsBuf.getCfg().getUharmAdd() == 1) {
            for (int i = 1; i < pqsHarmTimes; i++) {
                for (int ch = 0; ch < 3; ch++) {
                    pqsDat.getFuHarm()[ch][i] = pqsDat.getPpvFuHarm()[ch][i];
                    pqsDat.getFuHarmCON()[ch][i] = pqsDat.getPpvFuHarmCON()[ch][i];
                }
            }
            for (int ch = 0; ch < 3; ch++) {
                pqsDat.getHarmRMS()[ch] = pqsDat.getPpvHarmRMS()[ch];
                pqsDat.getHarmTHD()[ch] = pqsDat.getPpvHarmTHD()[ch];
                pqsDat.getHarmOTHD()[ch] = pqsDat.getPpvHarmOTHD()[ch];
                pqsDat.getHarmETHD()[ch] = pqsDat.getPpvHarmETHD()[ch];
            }
        }
    }
}