using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using rokae.clr;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock;
using static rokae.clr.ArcWelding;
using static rokae.clr.xPanelOpt;
using EventInfos = System.Collections.Generic.Dictionary<System.String, System.Object>;


namespace xCoreSDK_CSharp.examples
{
    public class SchedDemo
    {
        internal xMateRobotDemo robotDemo;
        internal ErrorCode ec = new ErrorCode(0, "");
        internal bool toInfoBox = false;
        void printInfo(String info)
        {
            Debug.WriteLine(info);
            if (toInfoBox)
            {               
            }
        }

        void printErrorCode(String funcName, ErrorCode ec)
        {
            if (ec.value != 0)
            {
                String info = funcName + ": " + ec.message;
                Debug.WriteLine(info);
                if (toInfoBox)
                {
                }
            }
        }

        void printSchedInfo(EventInfos info)
        {
            printInfo("enter printSchedInfo");
            var enable = (bool)info["enable"];
            var registerEnable = (bool)info["register_enable"];
            var schedState = (List<SchedStatus>)info["sched_status"];
            printInfo($"enable: {enable}");
            printInfo($"registerEnable: {registerEnable}");
            printInfo($"schedState:");
            foreach (var item in schedState)
            {
                printInfo($"    id: {item.id}");
                printInfo($"    state: {item.state}");
                printInfo($"    rank: {item.rank}");
                printInfo($"    count: {item.count}");
            }
        }

        void SetCallBack(xMateRobot robot,ErrorCode ec)
        {
            robot.setEventWatcher(Event.schedState, printSchedInfo, out ec);
            printErrorCode("setEventWatcher", ec);
        }

        void Enable(xMateRobot robot, ErrorCode ec)
        {
            // 启用/停用预约
            printInfo("enter Enable");
            bool enable = true;
            bool enableStatus;
            robot.enableSched(enable,out ec);
            printErrorCode("enable sched", ec);
            enableStatus = robot.getSchedEnableStatus(out ec);
            printErrorCode("getSchedEnableStatus", ec);
            printInfo($"sched enable status: {enableStatus}");

            enable = false;
            robot.enableSched(enable, out ec);
            printErrorCode("enable sched", ec);
            enableStatus = robot.getSchedEnableStatus(out ec);
            printErrorCode("getSchedEnableStatus", ec);
            printInfo($"sched enable status: {enableStatus}");
        }

        void Register(xMateRobot robot, ErrorCode ec)
        {
            // 开始/停止预约 
            // 需要在启用预约，自动模式，上电之后才能开始预约
            printInfo("enter Register");
            robot.enableSched(true, out ec);
            robot.setOperateMode(OperateMode.automatic, out ec);
            robot.setPowerState(true, out ec);

            bool registerEnable = true;// 开始预约
            bool registerEnableStatus;
            robot.registerEnableSched(registerEnable, out ec);
            printErrorCode("registerEnableSched", ec);
            registerEnableStatus = robot.getSchedRegisterEnableStatus(out ec);
            printErrorCode("getSchedRegisterEnableStatus", ec);
            printInfo($"sched register enable status: {registerEnableStatus}");


            registerEnable = false;// 停止预约
            robot.registerEnableSched(registerEnable, out ec);
            printErrorCode("registerEnableSched", ec);
            registerEnableStatus = robot.getSchedRegisterEnableStatus(out ec);
            printErrorCode("getSchedRegisterEnableStatus", ec);
            printInfo($"sched register enable status: {registerEnableStatus}");
        }

        void Setting(xMateRobot robot, ErrorCode ec)
        {
            // 设置预约参数
            printInfo("enter Setting");
            // 可以使用projectsInfo获取控制器工程信息
            var projInfo = robot.projectsInfo(out ec);
            foreach (var info in projInfo)
            {
                printInfo($"project name: {info.name}");
            }

            Action<SchedSetting> printSched = (schedSetting) =>
            {
                foreach (var item in schedSetting.schedEntrys)
                {
                    printInfo($"id: {item.id}");
                    printInfo($"enable: {item.enable} name: {item.name} count: {item.count}");
                    printInfo($"register type: {item.register_binding.type} register name: {item.register_binding.name}");
                    printInfo($"register_cancel type: {item.register_cancel.type} register_cancel name: {item.register_cancel.name}");
                    printInfo($"register_status type: {item.register_status.type} register_status name: {item.register_status.name}");
                }
            };

            SchedSetting schedSetting = new SchedSetting();
            int id = 3;
            schedSetting.get(id).enable = true;
            schedSetting.get(id).name = projInfo[0].name;
            schedSetting.get(id).count = 3;
            schedSetting.get(id).register_binding.type = "DI";
            schedSetting.get(id).register_binding.name = "DI0_0";
            schedSetting.get(id).register_cancel.type = "DI";
            schedSetting.get(id).register_cancel.name = "DI0_1";
            schedSetting.get(id).register_status.type = "DO";
            schedSetting.get(id).register_status.name = "DO0_0";
            robot.setSched(schedSetting, out ec);// 设置
            printErrorCode("setSched", ec);

            var schedSettingReturn = robot.getSchedSetting(out ec); // 获取设置
            printErrorCode("getSchedSetting", ec);
            printSched(schedSettingReturn);
        }

        public void Sched(xMateRobot robot, ErrorCode ec)
        {
            // 预约/取消预约
            printInfo("enter Sched");
            // 需要在开始预约之后才能预约
            robot.enableSched(true, out ec);
            robot.setOperateMode(OperateMode.automatic, out ec);
            robot.setPowerState(true, out ec);
            robot.registerEnableSched(true, out ec);

            Action<List<SchedStatus>> printSchedStatus = (schedStatus)=>{
                foreach (var item in schedStatus){
                    printInfo($"id: {item.id} state: {item.state} rank: {item.rank} count: {item.count}");
                }
            };

            int id = 3;
            robot.registerSched(id, out ec);// 预约
            printErrorCode("registerSched", ec);

            var schedStatus = robot.getSchedStatus(out ec);// 获取预约状态
            printErrorCode("getSchedStatus", ec);
            printSchedStatus(schedStatus);
            
            robot.unregisterSched(id, out ec);// 取消预约
            printErrorCode("unregisterSched", ec);
            schedStatus = robot.getSchedStatus(out ec);// 获取预约状态
            printErrorCode("getSchedStatus", ec);
            printSchedStatus(schedStatus);

            robot.unregisterAllSched(out ec);// 取消所有预约
            printErrorCode("unregisterAllSched", ec);

            robot.clearSchedCount(out ec);// 清除累计预约计数
            printErrorCode("clearSchedCount", ec);
        }

        public void AdvancedSetting(xMateRobot robot, ErrorCode ec)
        {
            // 高级预约设置
            printInfo("enter AdvancedSetting");
            robot.schedAdvancedSetting("pause_project", out ec);
            printErrorCode("schedAdvancedSetting", ec);
            robot.schedAdvancedSetting("unregister", out ec);
            printErrorCode("schedAdvancedSetting", ec);
        }

        public void Demo()
        {
            try
            {
                xMateRobot robot = new xMateRobot("192.168.110.129");
                ErrorCode ec = new ErrorCode(0, "");
                SetCallBack(robot, ec);
                //while (true) { };
                Enable(robot, ec);
                Register(robot, ec);
                Setting(robot, ec);
                Sched(robot, ec);
                AdvancedSetting(robot, ec);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}
