package main

import (
	"bytes"
	"encoding/binary"
	"flag"
	"fmt"
	"netease_control_center/interfaces/log"
	. "netease_control_center/modules/hardware/mcu_leds/atservice"
	"netease_control_center/nembd/evdev"
)

const (
	devpath = "/dev/input/event1"
)

var curVol uint8 = 0

func atCmdOKCallback(cmdId uint32, status AT_CMD_RSP, buf []byte) {
	if status == AT_CMD_RSP_OK {
		log.Println(log.DebugLog, "at is ready")
	} else {
		log.Println(log.DebugLog, "at is not ready err", status, buf)
	}
}

func atCmdVersionCallback(cmdId uint32, status AT_CMD_RSP, buf []byte) {
	if status == AT_CMD_RSP_OK {
		log.Printf(log.DebugLog, "ver:%s\n", buf)
	} else {
		log.Println(log.DebugLog, "AtCmdVersionCallback err:", status, buf)
	}
}

func atDefaultCallback(cmdId uint32, status AT_CMD_RSP, buf []byte) {
	if status == AT_CMD_RSP_OK {
		log.Printf(log.DebugLog, "atDefaultCallback, cmd: %d, data: %s\n", cmdId, buf)
	} else {
		log.Println(log.DebugLog, "atDefaultCallback err:", status, buf)
	}
}

func testFwdAt() {
	go SendAtCmd(AT_CMD, AT_CMD_FWD_PRI_NORMAL, []byte{}, nil)
	go SendAtCmd(AT_CMD_VERSION, AT_CMD_FWD_PRI_NORMAL, []byte{}, atCmdVersionCallback)
	go SendAtCmd(AT_CMD, AT_CMD_FWD_PRI_HIGH, []byte{}, atCmdOKCallback)
}

var (
	otaMCUImagePath string
)

func main() {
	flag.StringVar(&otaMCUImagePath, "o", "", "MCU OTA image path")
	testStr := flag.String("t", "", "test for flag")

	flag.Parse()
	log.Init()

	log.Println(log.DebugLog, "mcu OTA demo...")

	if *testStr != "" {
		log.Println(log.DebugLog, "test:", *testStr)
	}

	AtCmdInit(atStateCallback)

	if otaMCUImagePath != "" {
		log.Println(log.DebugLog, "OTA path:", otaMCUImagePath)
		McuOtaUpdate(otaMCUImagePath, otaFinishCallback)
	}

	go KeyApp()

	//testFwdAt()

	select {}
}

func atStateCallback(mcuStatus McuStatusT) {
	switch mcuStatus {
	case MCU_STATUS_AT_NOT_READY:
		log.Println(log.DebugLog, "mcu AT not ready!!!")
	case MCU_STATUS_AT_READY:
		log.Println(log.DebugLog, "mcu AT ready.")
		SendAtCmd(AT_CMD_VERSION, AT_CMD_FWD_PRI_NORMAL, []byte{}, atCmdVersionCallback)
	case MCU_STATUS_NEED_OTA:
		log.Println(log.ErrorLog, "+++++++mcu need OTA++++++")
		McuOtaUpdate("/usr/share/golang/mcu/mcufirmware", otaFinishCallback)
	case MCU_STATUS_BOOT_ERR:
		log.Println(log.ErrorLog, "+++++++mcu boot err++++++")
	default:
		log.Println(log.DebugLog, "err mcu status:", mcuStatus)
	}
}

func otaFinishCallback(isFinish bool, progress uint8, err error) {
	fmt.Printf("\r\033[35m OTA progress: %d%%\033[0m", progress)
	//os.Stdout.Sync()
	if isFinish {
		fmt.Printf("\n\033[32m MCU OTA successful\033[0m\n\n")
	}
}

func KeyApp() error {
	dev, err := evdev.Open(devpath)
	if err != nil {
		return err
	}

	for {
		if event, err := dev.ReadOne(); err == nil && event.Type == uint16(evdev.EV_KEY) {

			switch event.Code {
			case evdev.KEY_VOLUMEUP:
				log.Println(log.DebugLog, "KEY_VOLUMEUP")
				curVol++
				if curVol > 20 {
					curVol = 20
				}

				var v VolumeT = VolumeT{
					MaxVolume: 20,
					CurVolume: curVol,
				}

				buf := new(bytes.Buffer)
				binary.Write(buf, binary.LittleEndian, uint8(v.MaxVolume))
				binary.Write(buf, binary.LittleEndian, uint8(v.CurVolume))

				var volumeUp GuideLampEffectT = GuideLampEffectT{
					EffectID:     GUIDE_EFFECT_ID_VOLUME_ADJUST,
					Action:       GUIDE_ACTION_START,
					FadeIn:       FADE_NONE,
					FadeOut:      FADE_NONE,
					StartLampNum: 0,
					DataLen:      uint16(len(buf.Bytes())),
					Data:         buf.Bytes(),
				}
				GuideEffectControl(volumeUp, atDefaultCallback)
			case evdev.KEY_VOLUMEDOWN:
				log.Println(log.DebugLog, "KEY_VOLUMEDOWN")

				if curVol != 0 {
					curVol--
				}

				var v VolumeT = VolumeT{
					MaxVolume: 20,
					CurVolume: curVol,
				}

				buf := new(bytes.Buffer)
				binary.Write(buf, binary.LittleEndian, uint8(v.MaxVolume))
				binary.Write(buf, binary.LittleEndian, uint8(v.CurVolume))

				var volumeDown GuideLampEffectT = GuideLampEffectT{
					EffectID:     GUIDE_EFFECT_ID_VOLUME_ADJUST,
					Action:       GUIDE_ACTION_START,
					FadeIn:       FADE_NONE,
					FadeOut:      FADE_NONE,
					StartLampNum: 0,
					DataLen:      uint16(len(buf.Bytes())),
					Data:         buf.Bytes(),
				}
				GuideEffectControl(volumeDown, atDefaultCallback)
			case evdev.KEY_MUTE:
				//log.Println(log.DebugLog,"KEY_MUTE , ")
				//log.Println(log.DebugLog, "value:", event.Value)
				if event.Value == 0 {
					/*log.Println(log.DebugLog, "get id key:", GetGID())
					aniData := []byte{
						1, 0, 0, 0, 0, 0, 0, 0, 1,
						0, 1, 0, 0, 0, 0, 0, 1, 0,
						0, 0, 1, 0, 0, 0, 1, 0, 0,
						0, 0, 0, 1, 0, 1, 0, 0, 0,
						0, 0, 0, 0, 1, 0, 0, 0, 0,
						0, 0, 0, 1, 0, 1, 0, 0, 0,
						0, 0, 1, 0, 0, 0, 1, 0, 0,
						0, 1, 0, 0, 0, 0, 0, 1, 0,
						1, 0, 0, 0, 0, 0, 0, 0, 1,
					}
					gMAni := MatrixLampAnimationT{
						RepeatTimes: 0,
						FrameNums: 1,
						FrameBytes:MATRIX_LAMP_NUM,
						FrameDelay:MATRIX_ANIMATION_DELAY_FOREVER,
						Data:aniData,
					}

					MarixEffectAnimation(gMAni, atDefaultCallback)*/
					//McuOtaUpdate("/usr/share/golang/mcu/mcufirmware", otaFinishCallback)
					//LampBrightnessSet(LAMP_TYPE_ALL, 1, atDefaultCallback)

					/*log.Println(log.DebugLog, "get id key:", GetGID())
					aniData := []byte{
						0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0X00,0X00,0XFF,0X00,
						0X00,0X00,0X00,0X00,0XFF,0X00,0X00,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0X00,0X00,
						0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0X00,0X00,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,
						0X00,0X00,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0X00,0X00,0XFF,0X00,0X00,0X00,0X00,
						0X00,0XFF,0X00,0X00,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
						0X00,
					}
					gMAni := MatrixLampGradientT{
						RepeatTimes: 1,
						FrameNums: 1,
						FrameBytes:MATRIX_LAMP_NUM,
						InsertMode: NEW_ICON_MODE,
						T1:200,
						T2:2000,
						T3:200,
						T4:0,
						Data:aniData,
					}

					MarixEffectGradient(gMAni, atDefaultCallback)*/

					McuOtaUpdate("/tmp/lightMCU_F105RC.bin", otaFinishCallback)
				}

			case evdev.KEY_HOME:
				if event.Value == 0 {
					//McuOtaUpdate("/tmp/lightMCU_F105RC.bin", otaFinishCallback)
					//ResetMCU()
					log.Println(log.DebugLog, "KEY_HOME")
					go SendAtCmd(AT_CMD_MCU_ST, AT_CMD_FWD_PRI_NORMAL, []byte{}, nil)
				}
			default:
				log.Println(log.DebugLog, "Unknow key:", event.Code)
			}
		}
	}

}
