# -*- coding: UTF-8 -*-
import time
import re  # 正则表达式;
import numpy as np
import zipfile
import gzip
import autoGamma
from mokaSerail import MokaSerial

def readPartern():
    f = open(u"cfg.txt")  # 返回一个文件对象
    line = f.readline()  # 调用文件的 readline()方法，一次读取一行
    print(u"第一行", line)
    line = line.replace("\r", "")
    line = line.replace('\n', '')
    TV_COM = line.split(",")[0]
    CA_COM = line.split(",")[1]

    print("value", TV_COM, CA_COM)

    PAR_LIST = []
    while line:
        print(line)
        line = f.readline()
        if line.__len__() != 0:
            line = line.replace("\r", "")
            line = line.replace('\n', '')
            ls_d = line.split(',')
            # PAR_LIST.append(line.split(','))
            PAR_LIST.append([int(ls_d[0]), int(ls_d[1]), int(ls_d[2])])
    f.close()

    print(PAR_LIST)

    return TV_COM, CA_COM, PAR_LIST


def get_ca_data(data):
    # 正则表达式;
    # OK00,P1 3716;3956;.0091\r
    p = re.compile(r"(\D*)(\d+),P1 (.*);(.*);(.*)", re.DOTALL)
    mo = p.search(data)
    if mo is None:
        print("无匹配正则")
        pw = re.compile(r"(\D*)(\d+)", re.DOTALL)
        mo = pw.search(data)
        if mo is None:
            # print("短匹配失败")
            return None, None, None, None, None
        else:
            return mo.group(1), mo.group(2), None, None, None
    else:
        return mo.group(1), mo.group(2), mo.group(3), mo.group(4), mo.group(5)


def xyY_to_XYZ(x, y, Y):
    X = x * Y / y
    Z = (1 - x - y) * Y / y
    return X, Y, Z


def gen_gzip(gm_file, save_file):
    # 压缩gamma.ini成zip，再写入到TV?? 还是直接写入gamma.ini到TV ??
    fin = open(gm_file, 'rb')
    gf = gzip.open('gamma_org.gzip', 'wb')
    data = fin.read()
    gf.write(data)
    fin.close()
    gf.close()

    # 计算原始文件crc32;
    # crc32 = binascii.crc32(data)

    # 重新读取gzip，再切掉8个字节?后再保存
    fg = open('gamma_org.gzip', 'rb')
    g_data = fg.read()
    fg.close()

    # 生成新的gamma.zip.
    fg = open(save_file, 'wb+')
    start_index = 10 + 'gamma_org.gzip'.__len__() + 1
    data_save = g_data[start_index:-4]
    fg.write(g_data[8:10])
    fg.write(data_save)
    fg.close()

def test_all():
    # 读取配置文件;
    TV_COM, CA_COM, PAR_LIST = readPartern()
    NP_LIST = np.array(PAR_LIST)
    # 取第一列,再取第4位到末尾;
    Index11 = NP_LIST[:, 1][3:]
    print("11 pattern", Index11)

    # 打开CA310
    ca_port = MokaSerial()
    ca_port.open(CA_COM, 19200, 7, 'E', 2)
    # 开启CA310
    data = ca_port.sendcmd([0x43, 0x4F, 0x4D, 0x2C, 0x31, 0x0D])
    print("CA310 开启", data)

    if False:
        data = ca_port.sendcmd([0x4D, 0x44, 0x53, 0x2C, 0x30, 0x0D])
        print("CA310 显示模式", data)

        data = ca_port.sendcmd([0x53, 0x43, 0x53, 0x2C, 0x33, 0x0D])
        print("CA310 同步模式", data)

        data = ca_port.sendcmd([0x46, 0x53, 0x43, 0x2C, 0x32, 0x0D])
        print("CA310 测量速度", data)
        time.sleep(0.5)

        data = ca_port.sendcmd([0x5A, 0x52, 0x43, 0x0D])
        print("CA310 零校准", data)

    data = ca_port.sendcmd([0x4D, 0x43, 0x48, 0x2C, 0x30, 0x31, 0x0D])
    print("CA310 锁定键控", data)

    # 打开TV串口;
    tv_port = MokaSerial()
    tv_port.open(TV_COM)
    print("进工厂模式")
    data = tv_port.sendcmd([0xAA, 0x06, 0x10, 0x01, 0xA7, 0xEF])

    print("白平衡初始化")
    data = tv_port.sendcmd([0xAA, 0x06, 0x16, 0x01, 0x0D, 0x49])

    print("关闭Localdimming")
    data = tv_port.sendcmd([0xAA, 0x07, 0x9F, 0x07, 0x00, 0xE1, 0x74])

    print("打开内置pattern")
    data = tv_port.sendcmd([0xAA, 0x06, 0x27, 0x02, 0x0B, 0x8E])

    print("切换标准色温")
    data = tv_port.sendcmd([0xAA, 0x06, 0x31, 0x01, 0x92, 0x38])

    print("gamma初始化")
    data = tv_port.sendcmd([0xAA, 0x07, 0x9F, 0x09, 0x01, 0xD2, 0x5A])

    XYZ_ALL = []
    xyY_ALL = []
    print("内置pattern切换与CA310读取")
    for item in PAR_LIST:
        # print("item",item)
        if item.__len__() == 3:
            tv_port.send_parttern([int(item[0]), int(item[1]), int(item[2])])
            time.sleep(1)
            data = ca_port.sendcmd([0x4D, 0x45, 0x53, 0x0D])
            print("CA310数据读取",data)
            # bytes转成字符串;
            data = data.decode('utf-8')
            data = data.replace('\r', '')
            r1, r2, d1, d2, d3 = get_ca_data(data)
            # print("CA310数据:", d1, d2, d3)
            # X, Y, Z = xyY_to_XYZ(float(d1) / 10000, float(d2) / 10000, float(d3))

            print("CA410数据:", d1, d2, d3)
            X, Y, Z = xyY_to_XYZ(float(d1) / 1000, float(d2) / 1000, float(d3))

            print("XYZ", X, Y, Z)
            XYZ_ALL.append([X, Y, Z])
            xyY_ALL.append([d1, d2, d3])

    print("关闭内置pattern")
    data = tv_port.sendcmd([0xAA, 0x06, 0x27, 0x00, 0x2B, 0xCC])

    xyY_ALL = xyY_ALL[::-1]
    # for n in range(0, 11):
    #     xyY_ALL[n] = xyY_ALL[n].reverse()

    print(f"原始测量的xyY_11 is : \n")
    for i in range(0, 14):
        print(f"0.{xyY_ALL[i][0]}  0.{xyY_ALL[i][1]}  {xyY_ALL[i][2]}")

    # 关闭CA310
    data = ca_port.sendcmd([0x43, 0x4F, 0x4D, 0x2C, 0x30, 0x0D])

    # 调用gamma算法生成gamma.ini
    factory = autoGamma.FiretvFactory()
    RGBcalculator = factory.create()
    print("XYZ_ALL", XYZ_ALL)
    RGB255 = RGBcalculator.calRGB255_for_Debug(np.array(XYZ_ALL[0:3]).T, np.array(XYZ_ALL[3:]).T, np.array(Index11),
                                               0.313, 0.329, 2.2)
    autoGamma.dumpRGB2ini(RGB255)

    # 　生成切割文件；
    gen_gzip('gamma.ini', 'gamma_cut.zip')
    # 调用串口命令写入TV中;
    tv_port.send_gamma('gamma_cut.zip')
    # 使生效;
    tv_port.send_gamma_active('gamma.ini')

    autoGamma.showRGBcurve(RGB255)


def get_test_result():
    # 读取配置文件;
    TV_COM, CA_COM, PAR_LIST = readPartern()
    NP_LIST = np.array(PAR_LIST)
    # 取第一列,再取第4位到末尾;
    Index11 = NP_LIST[:, 1][3:]
    print("11 pattern", Index11)

    # 打开CA310
    ca_port = MokaSerial()
    ca_port.open(CA_COM, 19200, 7, 'E', 2)
    # 开启CA310
    data = ca_port.sendcmd([0x43, 0x4F, 0x4D, 0x2C, 0x31, 0x0D])
    print("CA310 开启", data)

    if True:
        data = ca_port.sendcmd([0x4D, 0x44, 0x53, 0x2C, 0x30, 0x0D])
        print("CA310 显示模式", data)

        data = ca_port.sendcmd([0x53, 0x43, 0x53, 0x2C, 0x33, 0x0D])
        print("CA310 同步模式", data)

        data = ca_port.sendcmd([0x46, 0x53, 0x43, 0x2C, 0x32, 0x0D])
        print("CA310 测量速度", data)
        time.sleep(1)

        data = ca_port.sendcmd([0x5A, 0x52, 0x43, 0x0D])
        print("CA310 零校准", data)

    data = ca_port.sendcmd([0x4D, 0x43, 0x48, 0x2C, 0x30, 0x31, 0x0D])
    print("CA310 锁定键控", data)

    # 打开TV串口;
    tv_port = MokaSerial()
    tv_port.open(TV_COM)
    print("进工厂模式")
    data = tv_port.sendcmd([0xAA, 0x06, 0x10, 0x01, 0xA7, 0xEF])

    print("打开内置pattern")
    data = tv_port.sendcmd([0xAA, 0x06, 0x27, 0x02, 0x0B, 0x8E])


    XYZ_ALL = []
    xyY_ALL = []
    print("内置pattern切换与CA310读取")
    for item in PAR_LIST:
        # print("item",item)
        if item.__len__() == 3:
            tv_port.send_parttern([int(item[0]), int(item[1]), int(item[2])])
            time.sleep(0.5)
            data = ca_port.sendcmd([0x4D, 0x45, 0x53, 0x0D])
            # bytes转成字符串;
            data = data.decode('utf-8')
            data = data.replace('\r', '')
            r1, r2, d1, d2, d3 = get_ca_data(data)
            # print("CA310数据:", d1, d2, d3)
            # X, Y, Z = xyY_to_XYZ(float(d1) / 10000, float(d2) / 10000, float(d3))

            print("CA410数据:", d1, d2, d3)
            X, Y, Z = xyY_to_XYZ(float(d1) / 1000, float(d2) / 1000, float(d3))

            print("XYZ", X, Y, Z)
            XYZ_ALL.append([X, Y, Z])
            xyY_ALL.append([d1, d2, d3])
    print("关闭内置pattern")
    data = tv_port.sendcmd([0xAA, 0x06, 0x27, 0x00, 0x2B, 0xCC])
    xyY_ALL = xyY_ALL[::-1]
    print(f"测量的xyY_11 is : \n")
    for i in range(0, 14):
        print(f"0.{xyY_ALL[i][0]}  0.{xyY_ALL[i][1]}  {xyY_ALL[i][2]}")

    # 关闭CA310
    data = ca_port.sendcmd([0x43, 0x4F, 0x4D, 0x2C, 0x30, 0x0D])


def test_zip():
    # 创建zip压缩包;
    zipFile = zipfile.ZipFile(r'gamma.zip', 'w')
    # 写入ini到zip中;
    zipFile.write(r'gamma.ini', 'gamma.ini', zipfile.ZIP_DEFLATED)
    zipFile.close()


def test_gzip():
    fin = open('gamma.ini', 'rb')
    gf = gzip.open('gamma.gzip', 'wb')
    data = fin.read()
    gf.write(data)
    fin.close()
    gf.close()


def test_result():
    # xyY_ALL = [[1,2,3],[4,5,6],[7,8,9]]
    # xyY_ALL = xyY_ALL[::-1]
    # for i in range(0, 3):
    #     print(f"0.{xyY_ALL[i][0]}  0.{xyY_ALL[i][1]}  {xyY_ALL[i][2]}")
    X = 7.82195
    Y = 3.78406
    Z = 2.37614
    x = X / (X + Y + Z)
    y = Y / (X + Y + Z)
    print(f"x={x} y= {y}")


if __name__ == "__main__":
    test_all()
    # test_result()
    # test_tv()
    # gen_gzip(r'F:\bin\TCLTools\gamma.ini', 'aaa.cut.zip')
    # test_ca310()
    # test_gzip()
