# /usr/bin/env python
# -*- coding: UTF-8 -*-
from __future__ import division
from numpy import floor, diff, array, mean, std


def filterSteadyData(data, length, ctnum):
    count_fluct_sum = 0
    max_current = 0
    current_stage2 = 0
    currentFlag = 0
    voltFlag = 0
    currentFlag2 = 0
    currentFlag3 = 0
    voltFlag2 = 0
    FLAG = 0
    FLAGCurrent = 0
    FLAGCurrentLevel2 = 0
    volt_fluct = 0
    maxCurrentDiffIndex = []
    indexcurrentSec = []
    maxDiffIndex = []
    indexvoltSec = []
    if length <= 6000:
        sep = 80
        points = int(floor(length / 80))
    elif length <= 12800:
        sep = 160
        points = int(floor(length / 160))
    elif length <= 20000:
        sep = 250
        points = int(floor(length / 250))
    else:
        sep = 330
        points = int(floor(length / 330))

    if ctnum == 3:

        for i in ['ia', 'ib', 'ic']:
            current = data[i]
            maxValues = [max(current[sep * j:sep * (j + 1)]) for j in range(points)]
            minValues = [min(current[sep * j:sep * (j + 1)]) for j in range(points)]

            maxdiff = abs(diff(array(maxValues))).tolist()

            maxCurrentDiffIndex.append(maxdiff.index(max(maxdiff)))
            indexcurrent = maxValues.index(max(maxValues))

            maxValuesConvert = maxdiff
            maxValuesConvert[maxCurrentDiffIndex[-1]] = 0
            indexcurrentSec.append(maxValuesConvert.index(max(maxValuesConvert)))

            if std(maxValues) / abs(mean(maxValues)) > 0.2:
                FLAGCurrentLevel2 += 1

            elif std(maxValues) / abs(mean(maxValues)) > 0.1 and std(maxValues) / abs(mean(maxValues)) < 1.5:
                FLAGCurrent += 1
            else:
                pass
            if max(maxValues) < 0.2:
                currentFlag3 += 1
                current_stage2 = current_stage2 + 1
            elif max(maxValues) < 0.4:
                current_stage2 = current_stage2 + 1
            elif max(maxValues) < 0.7:
                max_current = max_current + 1
            else:
                if max(maxValues) > 50:
                    for each in maxValues:
                        if each > 50:
                            currentFlag2 += 1
                if max(maxValues) > 0.1 * mean(maxValues[0:8]) and abs(
                                maxValues[indexcurrent] - maxValues[indexcurrent - 1]) < 0.03 * mean(
                    maxValues[0:1]) or min(
                    minValues) < 0.1 * mean(
                    minValues[0:8]) and abs(maxValues[indexcurrent - 2] - maxValues[indexcurrent - 1]) < 0.03 * mean(
                    maxValues[0:1]):
                    currentFlag += 1
                else:
                    currentFlag = currentFlag

        for i in ['ua', 'ub', 'uc']:
            count_fluct = 0
            currentList = data[i]
            abscurrent = [abs(x) for x in currentList]
            maxValues = [max(currentList[sep * j:sep * (j + 1)]) for j in range(points)]
            minValues = [min(currentList[sep * j:sep * (j + 1)]) for j in range(points)]
            maxdiff = abs(diff(array(maxValues))).tolist()
            peak_vall_diff = [max(currentList[sep * j:sep * (j + 1)]) - min(currentList[sep * j:sep * (j + 1)]) for j in
                              range(points)]
            peak_vall_diff_diff = abs(diff(array(peak_vall_diff))).tolist()
            indexvolt = maxValues.index(max(maxValues))
            maxDiffIndex.append(maxdiff.index(max(maxdiff)))
            maxValuesConvert = maxdiff
            maxValuesConvert[maxDiffIndex[-1]] = 0
            indexvoltSec.append(maxValuesConvert.index(max(maxValuesConvert)))

            for each in maxdiff:
                if each > 4:
                    count_fluct = count_fluct + 1

            if max(maxValues) < 120 and (max(peak_vall_diff_diff) < 0.2 * max(maxValues) or count_fluct >= 3) and max(
                    peak_vall_diff_diff) < 100:
                volt_fluct += 1

            if mean(maxValues) < 20:

                if std(maxValues) / mean(maxValues) > 8:
                    FLAG += 1
            else:
                if std(maxValues) / mean(maxValues) > 0.065:
                    FLAG += 1

            if currentFlag3 > 0 and max(abs(diff(array(maxValues)))) > 0.3 * max(maxValues):
                voltFlag2 += 1
            if max(abs(diff(array(maxValues)))) > 0.15 * max(maxValues) and max(
                    abs(diff(array(minValues)))) > 0.15 * abs(min(minValues)) and mean(abscurrent) > 30 and abs(
                        maxValues[indexvolt] - maxValues[indexvolt - 1]) < 0.05 * mean(maxValues[0:1]) and max(
                abs(diff(array(minValues)))) > 30 or max(
                abs(diff(array(maxValues)))) > 0.15 * max(maxValues) and max(
                abs(diff(array(minValues)))) > 0.15 * abs(min(minValues)) and abs(
                        maxValues[indexvolt - 2] - maxValues[indexvolt - 1]) < 0.05 * mean(maxValues[0:1]) and max(
                abs(diff(array(minValues)))) > 30:
                voltFlag += 1
            else:
                voltFlag = voltFlag
            if min(minValues) < -400 and max(maxValues) < 300 or max(maxValues) > 400 and min(minValues) > -300 or max(
                    maxValues) > 350 and min(minValues) > -350:
                currentFlag3 = 3
                break
            if max(maxdiff) < 15 and current_stage2 == 3 or max(maxValues) < 150 and current_stage2 == 3:
                currentFlag3 = 3
                break
        if count_fluct_sum >= 10 and max_current == 3:
            currentFlag3 = 3


    elif ctnum == 2:

        for i in ['iab', 'ibc']:
            current = data[i]
            maxValues = [max(current[sep * j:sep * (j + 1)]) for j in range(points)]
            minValues = [min(current[sep * j:sep * (j + 1)]) for j in range(points)]
            maxdiff = abs(diff(array(maxValues))).tolist()
            maxCurrentDiffIndex.append(maxdiff.index(max(maxdiff)))
            indexcurrent = maxValues.index(max(maxValues))
            maxValuesConvert = maxdiff
            maxValuesConvert[maxCurrentDiffIndex[-1]] = 0
            indexcurrentSec.append(maxValuesConvert.index(max(maxValuesConvert)))

            if std(maxValues) / abs(mean(maxValues)) > 0.2:
                FLAGCurrentLevel2 += 1

            elif std(maxValues) / abs(mean(maxValues)) > 0.1 and std(maxValues) / abs(mean(maxValues)) < 1.5:
                FLAGCurrent += 1
            else:
                pass
            if max(maxValues) < 0.2:
                current_stage2 = current_stage2 + 1
                currentFlag3 += 1
            elif max(maxValues) < 0.4:
                current_stage2 = current_stage2 + 1
            elif max(maxValues) < 0.7:
                max_current = max_current + 1
            else:
                if max(maxValues) > 50:
                    for each in maxValues:
                        if each > 50:
                            currentFlag2 += 1

                if max(maxValues) > 0.1 * mean(maxValues[0:8]) and abs(
                                maxValues[indexcurrent] - maxValues[indexcurrent - 1]) < 0.03 * mean(
                    maxValues[0:1]) or min(
                    minValues) < 0.1 * mean(
                    minValues[0:8]) and abs(maxValues[indexcurrent - 2] - maxValues[indexcurrent - 1]) < 0.03 * mean(
                    maxValues[0:1]):
                    currentFlag += 1
                else:
                    currentFlag = currentFlag

        for i in ['uab', 'ubc']:
            count_fluct = 0
            currentList = data[i]
            abscurrent = [abs(x) for x in currentList]
            maxValues = [max(currentList[sep * j:sep * (j + 1)]) for j in range(points)]
            minValues = [min(currentList[sep * j:sep * (j + 1)]) for j in range(points)]
            maxdiff = abs(diff(array(maxValues))).tolist()
            peak_vall_diff = [max(currentList[sep * j:sep * (j + 1)]) - min(currentList[sep * j:sep * (j + 1)]) for j in
                              range(points)]
            peak_vall_diff_diff = abs(diff(array(peak_vall_diff))).tolist()
            maxDiffIndex.append(maxdiff.index(max(maxdiff)))
            indexvolt = maxValues.index(max(maxValues))
            maxValuesConvert = maxdiff
            maxValuesConvert[maxDiffIndex[-1]] = 0
            indexvoltSec.append(maxValuesConvert.index(max(maxValuesConvert)))

            for each in maxdiff:
                if each > 2:
                    count_fluct = count_fluct + 1

            if max(maxValues) < 120 and (max(peak_vall_diff_diff) < 0.2 * max(maxValues) or count_fluct >= 3) and max(
                    peak_vall_diff_diff) < 100:
                volt_fluct += 1
            if mean(maxValues) < 20:

                if std(maxValues) / mean(maxValues) > 8:
                    FLAG += 1
            else:
                if std(maxValues) / mean(maxValues) > 0.065:
                    FLAG += 1

            if max(abs(diff(array(maxValues)))) > 0.15 * max(maxValues) and max(
                    abs(diff(array(minValues)))) > 0.15 * abs(min(minValues)) and mean(abscurrent) > 30 and abs(
                        maxValues[indexvolt] - maxValues[indexvolt - 1]) < 0.05 * mean(maxValues[0:1]) and max(
                abs(diff(array(minValues)))) > 30 or max(
                abs(diff(array(maxValues)))) > 0.15 * max(maxValues) and max(
                abs(diff(array(minValues)))) > 0.15 * abs(min(minValues)) and abs(
                        maxValues[indexvolt - 2] - maxValues[indexvolt - 1]) < 0.05 * mean(maxValues[0:1]) and max(
                abs(diff(array(minValues)))) > 30:
                voltFlag += 1
            else:
                voltFlag = voltFlag
            if min(minValues) < -400 and max(maxValues) < 300 or max(maxValues) > 400 and min(minValues) > -300 or max(
                    maxValues) > 350 and min(minValues) > -350:
                currentFlag3 = 2
                break
            if max(maxdiff) < 15 and current_stage2 == 2 or max(maxValues) < 150 and current_stage2 == 2:
                currentFlag3 = 2
                break
        if count_fluct >= 6 and max_current == 2:
            currentFlag3 = 2

    return volt_fluct, currentFlag, voltFlag, currentFlag2, currentFlag3, voltFlag2, FLAG, FLAGCurrent, FLAGCurrentLevel2


def testFeat(data, length, ctnum):
    average = []
    if length <= 6000:
        sep = 80
        points = int(floor(length / 80))
    elif length <= 12800:
        sep = 160
        points = int(floor(length / 160))
    elif length <= 20000:
        sep = 250
        points = int(floor(length / 250))
    else:
        sep = 330
        points = int(floor(length / 330))
    if ctnum == 3:
        for i in ['ia', 'ib', 'ic']:
            currentList = data[i]
            current = [x for x in currentList]
            maxValues = [max(current[sep * j:sep * (j + 1)]) for j in range(points)]
            if max(maxValues) <= 0:
                minValues = [min(current[sep * j:sep * (j + 1)]) for j in range(points)]
                average.append(max(maxValues) + min(minValues) / 2)
                average.append(min(minValues))
                average.append(max(maxValues) + min(minValues) / 2)
                average = [-x for x in average]
            else:
                average.append(maxValues[0])
                average.append(max(maxValues))
                average.append(maxValues[-1])

    if ctnum == 2:
        for i in ['iab', 'ibc']:
            currentList = data[i]
            current = [x for x in currentList]
            maxValues = [max(current[sep * j:sep * (j + 1)]) for j in range(points)]

            if max(maxValues) <= 0:
                minValues = [min(current[sep * j:sep * (j + 1)]) for j in range(points)]

                average.append(max(maxValues) + min(minValues) / 2)
                average.append(min(minValues))
                average.append(max(maxValues) + min(minValues) / 2)
                average = [-x for x in average]
            else:
                average.append(maxValues[0])
                average.append(max(maxValues))
                average.append(maxValues[-1])

    if sum(average) == 0:
        if ctnum == 2:
            percents = [0, 0, 0, 0, 0, 0]
        else:
            percents = [0, 0, 0, 0, 0, 0, 0, 0, 0]
    else:
        percents = [x / sum(average) for x in average]

    return percents
