package bx

import (
	"encoding/binary"
	"encoding/hex"
	"fmt"
)

type BxResp struct {
	group, cmd, Err, r0, r1 byte
	Data                    []byte
	//StateInfo               *StateInfo
}

func parse_(pack BxDataPack) *BxResp {
	var offset int
	resp := &BxResp{}
	resp.group = pack.data[offset]
	offset++
	resp.cmd = pack.data[offset]
	offset++
	resp.Err = pack.data[offset]
	offset++
	resp.r0 = pack.data[offset]
	offset++
	resp.r1 = pack.data[offset]
	offset++
	resp.Data = pack.data[offset:(offset + int(pack.dataLen) - 5)]
	//if !resp.IsInfo() {
	//	return resp
	//}
	//offset = 0
	//resp.StateInfo = &StateInfo{}
	//resp.StateInfo.OnOff = resp.Data[offset]
	//offset++
	//resp.StateInfo.Brightness = resp.Data[offset]
	//offset++
	//t := resp.Data[offset : offset+8]
	//resp.StateInfo.SystemTime = hex.EncodeToString(t)
	//offset += 8
	//resp.StateInfo.ProgramNum = resp.Data[offset]
	//offset++
	//resp.StateInfo.CruFileName = string(resp.Data[offset : offset+4])
	//offset += 4
	//resp.StateInfo.SpecialDynaArea = resp.Data[offset]
	//offset++
	//resp.StateInfo.PageNum = resp.Data[offset]
	//offset++
	//resp.StateInfo.DynaAreaNum = resp.Data[offset]
	//offset++
	//for i := byte(0); i < resp.StateInfo.ProgramNum; i++ {
	//	resp.StateInfo.DynaAreaIDs = append(resp.StateInfo.DynaAreaIDs, resp.Data[offset])
	//	offset++
	//}
	//resp.StateInfo.BarCode = string(resp.Data[offset : offset+16])
	return resp
}

func (r BxResp) Parse(src []byte, len int) *BxResp {
	dp := dpParse(src, len)
	if dp == nil {
		return nil
	} else {
		return parse_(*dp)
	}
}

func (r BxResp) IsAck() bool {
	if r.group == CMD_ACK.group && r.cmd == CMD_ACK.code {
		return true
	} else {
		return false
	}
}

func (r BxResp) NoError() bool {
	return r.Err == 0
}

func (r BxResp) Error() BxError {
	return bxErrors[r.Err]
}

// IsInfo 是否是返回"控制器状态"信息
func (r BxResp) IsInfo() bool {
	if r.group == CMD_SYSTEM_STATE.group && r.cmd == CMD_SYSTEM_STATE.code {
		return true
	} else {
		return false
	}
}

type StateInfo struct {
	OnOff           byte
	Brightness      byte
	SystemTime      string //年(2)+月(1)+日(1)+星期(1)+时(1)+分(1)+秒(1)
	ProgramNum      byte
	CruFileName     string
	SpecialDynaArea byte
	PageNum         byte
	DynaAreaNum     byte
	DynaAreaIDs     []byte
	BarCode         string
	//CustomId        string
}

func (s *StateInfo) Print(name string) {
	info :=
		`==== %s ====
电源状态: %s
系统时间: %s
节目数量: %d
当前播放: %s
动态区数: %d
条码: %s
===============
`
	onoff := ""
	if s.OnOff == 1 {
		onoff = "开机"
	} else {
		onoff = "关机"
	}
	fmt.Printf(info, name, onoff, s.SystemTime, s.ProgramNum, s.CruFileName, s.DynaAreaNum, s.BarCode)
}

func (s *StateInfo) Parse(data []byte) {
	offset := 0
	s.OnOff = data[offset]
	offset++
	s.Brightness = data[offset]
	offset++
	t := data[offset : offset+8]
	s.SystemTime = hex.EncodeToString(t)
	offset += 8
	s.ProgramNum = data[offset]
	offset++
	s.CruFileName = string(data[offset : offset+4])
	offset += 4
	s.SpecialDynaArea = data[offset]
	offset++
	s.PageNum = data[offset]
	offset++
	s.DynaAreaNum = data[offset]
	offset++
	for i := byte(0); i < s.DynaAreaNum; i++ {
		s.DynaAreaIDs = append(s.DynaAreaIDs, data[offset])
		offset++
	}
	s.BarCode = string(data[offset : offset+16])
}

type Params struct {
	Address      uint16
	DeviceType   byte
	BaudRate     byte
	ScreenWidth  uint16
	ScreenHeight uint16
	Color        byte
	DA           byte
	OE           byte
	FreqPar      byte
	RowOrder     byte
	MirrorMode   byte
	OEAngle      byte
	ScanMode     byte
	ScanConfNum  byte
	LatticeMode  byte
	//Reserved []byte
}

func (p *Params) Parse(data []byte) {
	offset := 0
	addr, err := BIN2Uint64(data[offset:offset+2], binary.LittleEndian)
	if err == nil {
		p.Address = uint16(addr)
	}
	offset += 2
	p.DeviceType = data[offset]
	offset++
	p.BaudRate = data[offset]
	offset++
	w, err := BIN2Uint64(data[offset:offset+2], binary.LittleEndian)
	if err == nil {
		p.ScreenWidth = uint16(w)
	}
	offset += 2
	h, err := BIN2Uint64(data[offset:offset+2], binary.LittleEndian)
	if err == nil {
		p.ScreenHeight = uint16(h)
	}
	offset += 2
	p.Color = data[offset]
	offset++
	p.DA = data[offset]
	offset++
	p.OE = data[offset]
	offset++
	p.FreqPar = data[offset]
	offset++
	p.RowOrder = data[offset]
	offset++
	p.MirrorMode = data[offset]
	offset++
	p.OEAngle = data[offset]
	offset++
	p.ScanMode = data[offset]
	offset++
	p.ScanConfNum = data[offset]
	offset++
	//p.LatticeMode = data[offset]
	//offset++
}
