package ym485

import (
	"github.com/valyala/bytebufferpool"
)

// QueryAddr 查询单灯控制器的设备地址
type QueryAddr struct {
	Dp DataPack
}

func (o *QueryAddr) EnCode() (*bytebufferpool.ByteBuffer, error) {
	return o.Dp.EnCode("AAAAAAAAAAAA", 0x13, nil)
}
func (o *QueryAddr) DeCode(data []byte) error {
	return o.Dp.DeCode(data)
}

// QueryAddrACK 查询单灯控制器设备地址响应
type QueryAddrACK struct {
	Dp   DataPack
	Addr string //单灯地址
}

func (o *QueryAddrACK) EnCode(Addr string) (*bytebufferpool.ByteBuffer, error) {
	return o.Dp.EnCode(Addr, 0x93, EncodeAddr(Addr))
}
func (o *QueryAddrACK) DeCode(data []byte) error {
	if err := o.Dp.DeCode(data); err == nil {
		o.Addr = DecodeAddr(o.Dp.Data[0:6])
		return nil
	} else {
		return err
	}
}

// PackingBasic 1E，设置单灯控制器基本设置，平台下发
//9E，查询单灯控制器基本设置响应，终端上报
type PackingBasic struct {
	Dp      DataPack
	Mark    [4]byte
	Enabled uint8   //各路是否使用
	OnOff   uint8   //上电开灯/关灯
	Zn      []uint8 //路n所属组别
}

func (o *PackingBasic) EnCode(Addr string, Ctl uint8, Mark [4]byte, Enabled, OnOff uint8, Zn []uint8) (*bytebufferpool.ByteBuffer, error) {
	copy(o.Mark[0:], Mark[0:])
	o.Enabled = Enabled
	o.OnOff = OnOff
	o.Zn = Zn

	dataBuf := make([]byte, 0, 6+len(Zn))
	dataBuf = append(dataBuf, o.Mark[0:]...)
	dataBuf = append(dataBuf, o.Enabled, o.OnOff)
	if len(o.Zn) > 0 {
		dataBuf = append(dataBuf, o.Zn...)
	}

	return o.Dp.EnCode(Addr, Ctl, dataBuf)
}

func (o *PackingBasic) DeCode(data []byte) error {
	if err := o.Dp.DeCode(data); err == nil {
		len0 := len(o.Dp.Data)
		if len0 >= 6 {
			copy(o.Mark[0:], o.Dp.Data[0:4])
			o.Enabled = o.Dp.Data[4]
			o.OnOff = o.Dp.Data[5]
			copy(o.Zn, o.Dp.Data[6:])
		}
		return nil
	} else {
		return err
	}
}

// PackingMark 9E，查询单灯控制器基本设置，平台下发
//9E，查询单灯控制器软件版本，平台下发
//9E，查询单灯控制器当前运行状态，平台下发
type PackingMark struct {
	Dp   DataPack
	Mark [4]byte
}

func (o *PackingMark) EnCode(Addr string, Ctl uint8, Mark [4]byte) (*bytebufferpool.ByteBuffer, error) {
	copy(o.Mark[0:], Mark[0:])
	dataBuf := make([]byte, 0, 4)
	dataBuf = append(dataBuf, o.Mark[0:]...)
	return o.Dp.EnCode(Addr, Ctl, dataBuf)
}

func (o *PackingMark) DeCode(data []byte) error {
	if err := o.Dp.DeCode(data); err == nil {
		len0 := len(o.Dp.Data)
		if len0 >= 4 {
			copy(o.Mark[0:], o.Dp.Data[0:4])
		}
		return nil
	} else {
		return err
	}
}

// PackingResult 9E，设置单灯控制器基本设置响应，终端上报
//9E，单灯控制器按路遥控开关灯响应，终端上报
//9E，单灯控制器按组遥控开关灯响应，终端上报
//9E，单灯控制器按路遥控调光响应，终端上报
//9E，单灯控制器按组遥控调光响应，终端上报
//9E，单灯控制器按路遥控色温响应，终端上报
//9E，单灯控制器按组遥控色温响应，终端上报
type PackingResult struct {
	Dp     DataPack
	Mark   [4]byte
	Result byte //Y成功，N失败
}

func (o *PackingResult) EnCode(Addr string, Ctl uint8, Mark [4]byte, Result byte) (*bytebufferpool.ByteBuffer, error) {
	copy(o.Mark[0:], Mark[0:])
	o.Result = Result
	dataBuf := make([]byte, 0, 5)
	dataBuf = append(dataBuf, o.Mark[0:]...)
	dataBuf = append(dataBuf, o.Result)
	return o.Dp.EnCode(Addr, Ctl, dataBuf)
}

func (o *PackingResult) DeCode(data []byte) error {
	if err := o.Dp.DeCode(data); err == nil {
		len0 := len(o.Dp.Data)
		if len0 >= 5 {
			copy(o.Mark[0:], o.Dp.Data[0:4])
			o.Result = o.Dp.Data[4]
		}
		return nil
	} else {
		return err
	}
}
