package auxilary

import (
	"encoding/binary"
	"errors"
)

// 每行传感器数据帧头信息长度为24字节
type AuxFrameHead struct {
	PkgHead   [4]byte // 包头头标识符，固定为0xD15BD15B
	FillByte0 byte    // 填充字节 0x00
	FrmHead   [6]byte // 帧头标识符，固定为0xEB90EB90EB90
	// 图像模式
	// B7	模式标识	000：为线阵模式
	// B6
	// B5
	// B4	B4谱状态	0：不输出1：输出
	// B3	B3谱状态	0：不输出1：输出
	// B2	B2谱状态	0：不输出1：输出
	// B1	B1谱状态	0：不输出1：输出
	// B0	全色状态	0：不输出1：输出
	ImgMode     byte
	SerialNo    uint32 //  当前流水号
	TimeSec     uint32 //  时间（秒）
	TimeSecFrac uint32 // 秒小数 量纲：1us/bit，十六进制无符号整型数
	FileNo      uint8  //  文件号

	IsValidFrmHead bool
	B0             bool
	B1             bool
	B2             bool
	B3             bool
	B4             bool
	IsLinerMatrix  bool
	RowLength      int
}

func (afh *AuxFrameHead) Decode(data []byte) error {
	if len(data) < 24 {
		return errors.New("length of AuxFrameHead is not 24")
	}

	afh.PkgHead = [4]byte{data[0], data[1], data[2], data[3]}
	afh.FillByte0 = data[4]
	afh.FrmHead = [6]byte{data[5], data[6], data[7], data[8], data[9], data[10]}
	afh.ImgMode = data[11]
	afh.B0 = (afh.ImgMode&(1<<0) != 0x0)
	afh.B1 = (afh.ImgMode&(1<<1) != 0x0)
	afh.B2 = (afh.ImgMode&(1<<2) != 0x0)
	afh.B3 = (afh.ImgMode&(1<<3) != 0x0)
	afh.B4 = (afh.ImgMode&(1<<4) != 0x0)
	afh.IsLinerMatrix = (afh.ImgMode&(1<<5) == 0x0 && afh.ImgMode&(1<<6) == 0x0 && afh.ImgMode&(1<<7) == 0x0)
	afh.SerialNo = binary.BigEndian.Uint32(data[12:16])
	afh.TimeSec = binary.BigEndian.Uint32(data[16:20])
	afh.TimeSecFrac = uint32(uint32(data[20])<<16 | uint32(data[21])<<8 | uint32(data[22]))
	afh.FileNo = data[23]

	afh.RowLength = afh.LengthOfRow()
	afh.IsValidFrmHead = afh.CheckFrmHead()

	return nil
}

// 计算一行数据长度：帧头+辅助数据+图像数据
func (afh AuxFrameHead) LengthOfRow() int {
	if !afh.IsLinerMatrix {
		return 14344
	}

	length := 64 // 帧头+辅助数据长度
	if afh.B0 {
		length += 19040
	}
	if afh.B1 {
		length += 1192
	}
	if afh.B2 {
		length += 1192
	}
	if afh.B3 {
		length += 1192
	}
	if afh.B4 {
		length += 1192
	}

	return length
}

func (afh AuxFrameHead) CheckFrmHead() bool {
	if afh.FrmHead[0] == 0xEB && afh.FrmHead[1] == 0x90 &&
		afh.FrmHead[2] == 0xEB && afh.FrmHead[3] == 0x90 &&
		afh.FrmHead[4] == 0xEB && afh.FrmHead[5] == 0x90 {
		return true
	}
	return false
}

func (afh AuxFrameHead) ImageMode() string {
	if afh.IsLinerMatrix {
		return "线阵模式"
	}
	return "面阵模式"
}

func (afh AuxFrameHead) BandStatus(b bool) string {
	if b {
		return "输出"
	}
	return "不输出"
}
