package bx

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

type bitmapFile struct {
	FileType byte   //0x04
	FileName string //4byte Txxx
	FileLen  uint32
	LibData  []byte
	CHK      uint16
}

func NewBitmapFile(filename string, libdata []byte) bitmapFile {
	chk := CRC16(libdata, 0, len(libdata))
	fmt.Printf("位图文件校验:% 02x\n", chk)
	return bitmapFile{
		FileType: 0x04,
		FileName: filename,
		FileLen:  uint32(len(libdata)),
		LibData:  libdata,
		CHK:      chk,
	}
}

func (bf *bitmapFile) NewCmd() *CmdWriteBitmapFile {
	return &CmdWriteBitmapFile{
		baseBxCmd:     newBaseCmd(CMD_WRITE_FILE.group, CMD_WRITE_FILE.code),
		file:          bf,
		LastBlockFlag: 1,
	}
}

type CmdWriteBitmapFile struct {
	baseBxCmd
	state         byte
	file          *bitmapFile
	LastBlockFlag byte
	BlockNum      uint16 //包号，如果是单包发送，则默认为 0x00。
	BlockLen      uint16 //包长，若是单包发送，此处为文件长度。
	BlockAddr     uint32 //本包数据在文件中的起始位置，如果是单包发送，此处默认为 0。
	temp          []byte
}

func (cmd *CmdWriteBitmapFile) Build() []byte {
	if cmd.state == 0 {
		//Write File
		w1 := bytes.NewBuffer(make([]byte, 0, 1024))
		//文件描述数据
		binary.Write(w1, binary.LittleEndian, cmd.Group())
		binary.Write(w1, binary.LittleEndian, cmd.Cmd())
		binary.Write(w1, binary.LittleEndian, byte(0x01))
		binary.Write(w1, binary.LittleEndian, []byte{0x00, 0x00})
		binary.Write(w1, binary.BigEndian, []byte(cmd.file.FileName))
		binary.Write(w1, binary.LittleEndian, cmd.LastBlockFlag) //是否是最后一包,0x00——不是最后一包 0x01——最后一包。
		binary.Write(w1, binary.LittleEndian, cmd.BlockNum)      //包号,单包为0x00
		binary.Write(w1, binary.LittleEndian, cmd.file.FileLen)  //包长，若是单包发送，此处为文件长度。
		binary.Write(w1, binary.LittleEndian, cmd.BlockAddr)     //本包数据在文件中的偏移量,单包为0x00
		//文件内容数据
		w2 := bytes.NewBuffer(make([]byte, 0, 1024))
		binary.Write(w2, binary.LittleEndian, cmd.file.FileType)
		binary.Write(w2, binary.BigEndian, []byte(cmd.file.FileName))
		binary.Write(w2, binary.LittleEndian, cmd.file.FileLen)
		binary.Write(w2, binary.BigEndian, cmd.file.LibData)
		data := w2.Bytes()
		crc := CRC16(data, 0, w2.Len())
		binary.Write(w1, binary.BigEndian, data)
		binary.Write(w1, binary.LittleEndian, crc)
		cmd.temp = w1.Bytes()
		//Start Write File "开始写文件",写文件前先检查内存是否够用
		w3 := bytes.NewBuffer(make([]byte, 0, 64))
		binary.Write(w3, binary.LittleEndian, CMD_START_WRITE_FILE.group)
		binary.Write(w3, binary.LittleEndian, CMD_START_WRITE_FILE.code)
		binary.Write(w3, binary.LittleEndian, byte(0x01))
		binary.Write(w3, binary.LittleEndian, []byte{0x00, 0x00})
		binary.Write(w3, binary.LittleEndian, byte(0x01)) //同名是否覆盖,0不覆盖,1覆盖
		binary.Write(w3, binary.BigEndian, []byte(cmd.file.FileName))
		binary.Write(w3, binary.LittleEndian, cmd.file.FileLen)
		cmd.state = 1
		return w3.Bytes()
	} else {
		return cmd.temp
	}
}
