using MECF.Framework.Common.CommonData;
using MECF.Framework.Common.Communications;
using MECF.Framework.Common.Equipment;
using System;

namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.Sunway
{
    public abstract class SunwayRobotHandler : HandlerBase
    {
        public SunwayRobot Device { get; }
        public bool HasResponse { get; set; } = true;

        protected string _command;
        protected string _parameter;
        protected string _target;
        protected RobotArmEnum _blade;
        /// <summary>
        /// Handler执行完毕后执行的任务。
        /// </summary>
        protected Action _onHandlerEndTask;

        protected string _requestResponse = "";

        protected SunwayRobotHandler(SunwayRobot device, string command, string parameter = null, Action onHandlerEndTask = null)
            : base(BuildMessage(command, parameter))
        {
            Device = device;
            _command = command;
            _parameter = parameter;
            Name = command;
            _onHandlerEndTask = onHandlerEndTask;
        }
        private static string BuildMessage(string command, string parameter)
        {
            string msg = parameter == null ? $"{command}" : $"{command} {parameter}";

            return msg + "\r\n";
        }

        public override bool HandleMessage(MessageBase msg, out bool transactionComplete)
        {
            var response = msg as SunwayRobotMessage;
            ResponseMessage = msg;

            if (response.IsError)
            {
                Device.NoteError(response.Data);
            }

            if (response.IsComplete)
            {
                SetState(EnumHandlerState.Completed);
                transactionComplete = true;
                return true;
            }
            if (response.IsResponse)
            {
                _requestResponse = response.Data;
            }

            transactionComplete = false;
            return false;
        }
    }

    public class SunwayRobotHomeHandler : SunwayRobotHandler
    {
        //HOM
        public SunwayRobotHomeHandler(SunwayRobot device, int timeout = 60, Action onHandlerEndTask = null)
            : base(device, $"HOME ALL", onHandlerEndTask: onHandlerEndTask)
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.Both,
                BladeTarget = "ArmA.System",
            };
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot HOM Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {
                Device.IsBusy = false;
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot HOME Response Error");
                return false;
            }
            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };
            ResponseMessage = msg;
            handled = true;
            _onHandlerEndTask?.Invoke();
            Device.NoteActionCompleted();
            return true;
        }
    }

    public class SunwayRobotRQLoadHandler : SunwayRobotHandler
    {
        // RQ LOAD 
        public SunwayRobotRQLoadHandler(SunwayRobot device, int timeout = 5)
            : base(device, "RQ LOAD A")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot RQ LOAD Timeout");
                return true;
            }

            if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot RQ LOAD Error");
                return false;
            }
            else
            {
                Device.SetWaferData(result.Data);
            }

            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };

            ResponseMessage = msg;
            Device.IsBusy = false;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotGotoMapHandler : SunwayRobotHandler
    {
        //GOTO N station [MAP (EX|RE)] [[RX] R1|R2|R3]
        public SunwayRobotGotoMapHandler(SunwayRobot device, string module, bool isRetract,int timeout = 60)
            : base(device, "GOTO", $"N {device.ModuleAssociateStationDic[module]} MAP {(isRetract ? "RE" : "EX")}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.Both,
                BladeTarget = "ArmA.System",
            };
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot Goto Map Timeout");
                return true;
            }

            if (result.Data == "_RDY")
            {
                Device.IsBusy = false;
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot Goto Map Response Error");
                return false;
            }

            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };

            ResponseMessage = msg;
            handled = true;
            _onHandlerEndTask?.Invoke();
            Device.NoteActionCompleted();
            return true;
        }
    }

    public class SunwayRobotMapHandler : SunwayRobotHandler
    {
        //MAP station
        public SunwayRobotMapHandler(SunwayRobot device, string module, int timeout = 60)
            : base(device, $"MAP {device.ModuleAssociateStationDic[module]}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.Both,
                BladeTarget = "ArmA.System",
            };
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot Goto Map Timeout");
                return true;
            }

            if (result.Data == "_RDY")
            {
                Device.IsBusy = false;
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot Goto Map Response Error");
                return false;
            }

            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };

            ResponseMessage = msg;
            handled = true;
            _onHandlerEndTask?.Invoke();
            Device.NoteActionCompleted();
            return true;
        }
    }

    public class SunwayRobotRSRHandler : SunwayRobotHandler
    {
        //RSR station
        public SunwayRobotRSRHandler(SunwayRobot device, string module, int timeout = 60)
            : base(device, $"RSR {device.ModuleAssociateStationDic[module]}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot RSR Timeout");
                return true;
            }

            if (result.Data.Length == 53 || result.Data.Length == 19)
            {
                Device.SetWaferData(result.Data);
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot RSR Response Error");
                return false;
            }

            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };
            ResponseMessage = msg;
            Device.NoteActionCompleted();
            handled = true;
            return true;
        }
    }

    public class SunwayRobotGotoHandler : SunwayRobotHandler
    {
        //GOTO N station [R (EX|RE)] [Z (UP|DN)] [SLOT num] [[ARM] arm]
        public SunwayRobotGotoHandler(SunwayRobot device, string module, int slot, RobotArmEnum blade,
            bool isRetract = true, bool isZaxisDown = true, int timeout = 60)
            : base(device, "GOTO", $"N {device.ModuleAssociateStationDic[module]} R {(isRetract ? "RE" : "EX")}" +
                  $" Z {(isZaxisDown ? "DN" : "UP")} SLOT {slot} ARM {(blade == RobotArmEnum.Blade1 ? "A" : "B")}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot GoTo Command Timeout");
                return true;
            }

            if (result.Data == "_RDY")
            {
                Device.IsBusy = false;
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot Goto Command Error");

                Device.MoveInfo = new RobotMoveInfo()
                {
                    Action = RobotAction.Moving,
                    ArmTarget = RobotArm.ArmA,
                    BladeTarget = ModuleName.System.ToString(),
                };
                return false;
            }

            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotPickHandler : SunwayRobotHandler
    {
        private bool isRetract;
        private string cModule;

        //PICK station [SLOT slot] [[ARM] arm] [ENRT|STRT NR]
        public SunwayRobotPickHandler(SunwayRobot device, string module, int slot, RobotArmEnum blade, bool isRetract = true, int timeout = 60)
            : base(device, "PICK", $"{device.ModuleAssociateStationDic[module]} SLOT {slot}" +
                  $" ARM {(blade == RobotArmEnum.Blade1 ? "A" : "B")}" + $" {(isRetract ? "STRT" : "ENRT")}" + " NR")
        {
            this.isRetract = isRetract;
            this.cModule = module;  

            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            //伸出时的动画
            if (!isRetract)
            {
                device.MoveInfo = new RobotMoveInfo()
                {
                    Action = RobotAction.Picking,
                    ArmTarget = RobotArm.ArmA,
                    BladeTarget = module,
                };
            }
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot Pick Command Timeout");
                return true;
            }

            if (result.Data == "_RDY")
            {
                if (!isRetract)
                {
                    //将Robot的状态从ExtendingForPick转到Idle
                    Device.NoteActionCompleted();

                    //伸出
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Picking,
                        ArmTarget = _blade == RobotArmEnum.Blade1 ? RobotArm.ArmA : RobotArm.ArmB,
                        BladeTarget = cModule,
                    };
                }
                else
                {
                    //将Robot的状态从Picking转到Idle
                    Device.NoteActionCompleted();

                    //缩回
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Moving,
                        ArmTarget = RobotArm.ArmA,
                        BladeTarget = ModuleName.System.ToString(),
                    };
                }
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot Pick Command Response Error");

                if (!isRetract) // 伸出手臂
                {
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Extending,
                        ArmTarget = RobotArm.ArmA,
                        BladeTarget = cModule,
                    };
                }
                else 
                {
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Moving,
                        ArmTarget = RobotArm.ArmA,
                        BladeTarget = ModuleName.System.ToString(),
                    };
                }
                return false;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotPlaceHandler : SunwayRobotHandler
    {
        private bool isRetract;
        private string cModule;

        //Place station [SLOT slot] [[ARM] arm] [ENRT|STRT NR]
        public SunwayRobotPlaceHandler(SunwayRobot device, string module, int slot, RobotArmEnum blade, bool isRetract = true, int timeout = 60)
            : base(device, "PLACE", $"{device.ModuleAssociateStationDic[module]} SLOT {slot}" +
                  $" ARM {(blade == RobotArmEnum.Blade1 ? "A" : "B")}" + $" {(isRetract ? "STRT" : "ENRT")}" + " NR")
        {
            this.isRetract = isRetract;
            this.cModule = module;

            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            //伸出时的动画
            if (!isRetract)
            {
                device.MoveInfo = new RobotMoveInfo()
                {
                    Action = RobotAction.Placing,
                    ArmTarget = RobotArm.ArmA,
                    BladeTarget = module,
                };
            }
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot Place Command Timeout");
                return true;
            }

            if (result.Data == "_RDY")
            {
                if (!isRetract)
                {
                    //将Robot的状态从ExtendingForPlace转到Idle
                    Device.NoteActionCompleted();

                    //伸出
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Placing,
                        ArmTarget = _blade == RobotArmEnum.Blade1 ? RobotArm.ArmA : RobotArm.ArmB,
                        BladeTarget = cModule,
                    };
                }
                else
                {
                    //将Robot的状态从Placeing转到Idle
                    Device.NotePlaceCompleted();

                    //缩回
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Moving,
                        ArmTarget = RobotArm.ArmA,
                        BladeTarget = ModuleName.System.ToString(),
                    };
                }
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot Place Command Response Error");

                if (!isRetract) // 伸出手臂
                {
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Extending,
                        ArmTarget = RobotArm.ArmA,
                        BladeTarget = cModule,
                    };
                }
                else
                {
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Moving,
                        ArmTarget = RobotArm.ArmA,
                        BladeTarget = ModuleName.System.ToString(),
                    };
                }
                return false;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotVacHandler : SunwayRobotHandler
    {
        //VAC ON|OFF ARM A|B
        public SunwayRobotVacHandler(SunwayRobot device,bool isOpen, RobotArmEnum blade,int timeout = 5)
            : base(device, $"VAC {(isOpen ? "ON" : "OFF")} ARM {(blade == RobotArmEnum.Blade1 ? "A" : "B")}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot VAC Command Timeout");
                return true;
            }

            if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot VAC Command Error");
                return false;
            }

            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };

            ResponseMessage = msg;
            Device.IsBusy = false;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotGripHandler : SunwayRobotHandler
    {
        //GRIP ON|OFF ARM A|B
        public SunwayRobotGripHandler(SunwayRobot device, bool isOpen, RobotArmEnum blade, int timeout = 5)
            : base(device, $"GRIP {(isOpen ? "ON" : "OFF")} ARM {(blade == RobotArmEnum.Blade1 ? "A" : "B")}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot GRIP Command Timeout");
                return true;
            }

            if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot GRIP Command Error");
                return false;
            }

            ResponseMessage = msg;
            Device.IsBusy = false;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotSetEchoHandler : SunwayRobotHandler
    {
        //SET IO ECHO Y|N
        public SunwayRobotSetEchoHandler(SunwayRobot device, bool isOpen, int timeout = 5)
            : base(device, $"SET IO ECHO {(isOpen ? "Y" : "N")}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot Set IO Echo Command Timeout");
                return true;
            }

            if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot Set IO Echo Command Error");
                return false;
            }

            ResponseMessage = msg;
            Device.IsBusy = false;
            handled = true;
            return true;
        }
    }


    public class SunwayRobotSTATHandler : SunwayRobotHandler
    {
        // STAT
        public SunwayRobotSTATHandler(SunwayRobot device, int timeout = 5, Action onHandlerEndTask = null)
           : base(device, $"RQ STATE", onHandlerEndTask: onHandlerEndTask)
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot STAT Timeout");
                return true;
            }

            if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot STAT Response Error");
                return false;
            }

            //Wafer位置从机械手和Station之间转换
            if (Device.ParseStatusData(result.Data))
                _onHandlerEndTask?.Invoke();



            handled = true;
            return true;
        }
    }

    public class SunwayRobotERRHandler : SunwayRobotHandler
    {
        // STAT
        public SunwayRobotERRHandler(SunwayRobot device, int timeout = 5, Action onHandlerEndTask = null)
           : base(device, $"ERR 0", onHandlerEndTask: onHandlerEndTask)
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot ERR Timeout", false);
                return true;
            }

            if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot ERR Response Error", false);
                return false;
            }

            if (Device.ParseErrData(result.Data))
                _onHandlerEndTask?.Invoke();

            handled = true;
            return true;
        }
    }


    public class SunwayRobotGETAHandler : SunwayRobotHandler
    {
        //GETA [module],[slot]
        public SunwayRobotGETAHandler(SunwayRobot device, string module, int slot, int timeout = 60)
            : base(device, $"GETA {device.ModuleAssociateStationDic[module]} {slot + 1}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Picking,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = module,
            };
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot GETA Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {
                //Wafer位置从机械手和Station之间转换
                Device.PrasePutWaferData();
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot GETA Response Error");
                return false;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotGETBHandler : SunwayRobotHandler
    {
        //GETB [module],[slot]
        public SunwayRobotGETBHandler(SunwayRobot device, string module, int slot, int timeout = 60)
            : base(device, $"GETB {device.ModuleAssociateStationDic[module]} {slot + 1}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = module,
            };
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot GETB Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {
                //Wafer位置从机械手和Station之间转换
                Device.PraseGetWaferData();
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot GETB Response Error");
                return false;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotBGETBHandler : SunwayRobotHandler
    {
        //GETB [module],[slot]
        string cModule = "";

        public SunwayRobotBGETBHandler(SunwayRobot device, string module, int slot, int timeout = 60)
            : base(device, $"GETB {device.ModuleAssociateStationDic[module]} {slot + 1}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            cModule = module;

            device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Picking,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = module,
            };
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot GETB Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {
                Device.GetWaferData();
                Device.NotePickCompleted();

                Device.MoveInfo = new RobotMoveInfo()
                {
                    Action = RobotAction.Moving,
                    ArmTarget = RobotArm.ArmA,
                    BladeTarget = ModuleName.System.ToString(),
                };
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot GETB Response Error");
                return true;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotPUTAHandler : SunwayRobotHandler
    {
        //PUTA [module],[slot]
        public SunwayRobotPUTAHandler(SunwayRobot device, string module, int slot, int timeout = 60)
            : base(device, $"PUTA {device.ModuleAssociateStationDic[module]} {slot + 1}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Placing,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = module,
            };
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot PUTA Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {
                //Wafer位置从机械手和Station之间转换
                //Device.PraseWaferData(result.Data);
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot PUTA Response Error");
                return false;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotPUTBHandler : SunwayRobotHandler
    {
        //PUTA [module],[slot]
        public SunwayRobotPUTBHandler(SunwayRobot device, string module, int slot, int timeout = 60)
            : base(device, $"PUTB {device.ModuleAssociateStationDic[module]} {slot + 1}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = module,
            };
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot PUTB Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {
                //Wafer位置从机械手和Station之间转换
                //Device.PraseWaferData(result.Data);
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot PUTB Response Error");
                return false;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotBPUTBHandler : SunwayRobotHandler
    {
        //PUTA [module],[slot]
        string cModule = "";

        public SunwayRobotBPUTBHandler(SunwayRobot device, string module, int slot, int timeout = 60)
            : base(device, $"PUTB {device.ModuleAssociateStationDic[module]} {slot + 1}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            cModule = module;

            device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Placing,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = module,
            };
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot PUTB Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {
                Device.PutWaferData();
                Device.NotePlaceCompleted();

                Device.MoveInfo = new RobotMoveInfo()
                {
                    Action = RobotAction.Moving,
                    ArmTarget = RobotArm.ArmA,
                    BladeTarget = ModuleName.System.ToString(),
                };

            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot PUTB Response Error");
                return false;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotPUTSPHandler : SunwayRobotHandler
    {
        //PUTSP [module],[slot],[step]
        //step:1:初始化位置  2:伸出  3:开真空并抬升  4:到位回缩
        string cModule = "";
        int cSlot = 0;
        int cStep = 0;
        public SunwayRobotPUTSPHandler(SunwayRobot device, string module, int slot, int step, int timeout = 60)
            : base(device, $"PUTSP {device.ModuleAssociateStationDic[module]} {slot + 1} {step}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            cModule = module;
            cSlot = slot;
            cStep = step;
            if (cStep == 2)
            {
                device.MoveInfo = new RobotMoveInfo()
                {
                    Action = RobotAction.Placing,
                    ArmTarget = RobotArm.ArmA,
                    BladeTarget = module,
                };
            }
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot PUTSP Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {
                if (cStep == 2)
                {
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Placing,
                        ArmTarget = _blade == RobotArmEnum.Blade1 ? RobotArm.ArmA : RobotArm.ArmB,
                        BladeTarget = cModule,
                    };
                }
                else if (cStep == 3)
                {
                    Device.NoteActionCompleted();
                }
                else if (cStep == 4)
                {
                    Device.NotePlaceCompleted();
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Moving,
                        ArmTarget = RobotArm.ArmA,
                        BladeTarget = ModuleName.System.ToString(),
                    };
                }
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot PUTSP Response Error");

                if (cStep == 2) // 伸出手臂
                {
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Extending,
                        ArmTarget = RobotArm.ArmA,
                        BladeTarget = cModule,
                    };
                }
                else if (cStep == 3) // 開啟真空並抬升取片
                {
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Picking,
                        ArmTarget = RobotArm.ArmA,
                        BladeTarget = cModule,
                    };
                }
                else //  1 = 縮回手臂至縮回位置並移動至取片的預備位置; 4 = 縮回手臂
                {
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Moving,
                        ArmTarget = RobotArm.ArmA,
                        BladeTarget = ModuleName.System.ToString(),
                    };
                }
                return false;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotGETSPHandler : SunwayRobotHandler
    {
        //PUTSP [module],[slot],[step]
        //step:1:初始化位置  2:伸出  3:关真空并抬升  4:到位回缩        
        string cModule = "";
        int cSlot = 0;
        int cStep = 0;
        public SunwayRobotGETSPHandler(SunwayRobot device, string module, int slot, int step, int timeout = 60)
            : base(device, $"GETSP {device.ModuleAssociateStationDic[module]} {slot + 1} {step}")
        {
            cModule = module;
            cSlot = slot;
            cStep = step;
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            if (cStep == 2)
            {
                device.MoveInfo = new RobotMoveInfo()
                {
                    Action = RobotAction.Picking,
                    ArmTarget = RobotArm.ArmA,
                    BladeTarget = module,
                };
            }
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot GETSP Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {
                if (cStep == 2)
                {
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Picking,
                        ArmTarget = _blade == RobotArmEnum.Blade1 ? RobotArm.ArmA : RobotArm.ArmB,
                        BladeTarget = cModule,
                    };
                    Device.NoteActionCompleted();
                }
                else if (cStep == 3)
                {
                    Device.NotePickCompleted();
                }
                else if (cStep == 4)
                {
                    Device.NoteActionCompleted();
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Moving,
                        ArmTarget = RobotArm.ArmA,
                        BladeTarget = ModuleName.System.ToString(),
                    };
                }
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot GETSP Response Error");

                if (cStep == 2) // 伸出手臂
                {
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Extending,
                        ArmTarget = RobotArm.ArmA,
                        BladeTarget = cModule,
                    };
                }
                else if (cStep == 3) // 開啟真空並抬升取片
                {
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Picking,
                        ArmTarget = RobotArm.ArmA,
                        BladeTarget = cModule,
                    };
                }
                else //  1 = 縮回手臂至縮回位置並移動至取片的預備位置; 4 = 縮回手臂
                {
                    Device.MoveInfo = new RobotMoveInfo()
                    {
                        Action = RobotAction.Moving,
                        ArmTarget = RobotArm.ArmA,
                        BladeTarget = ModuleName.System.ToString(),
                    };
                }
                return false;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotINPUTHandler : SunwayRobotHandler
    {
        // INPUT A 3
        public SunwayRobotINPUTHandler(SunwayRobot device, int timeout = 5, string com = "INPUT A 1")
            : base(device, com)
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot INPUT Timeout");
                return true;
            }
            if (result.Data.Length == 1)
            {
                Device.SetWaferData(result.Data);
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot INPUT Response Error");
                return false;
            }

            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };

            ResponseMessage = msg;
            //Device.NoteActionCompleted();
            handled = true;
            return true;
        }
    }

    public class SunwayRobotBINPUTHandler : SunwayRobotHandler
    {
        // INPUT A 3
        public SunwayRobotBINPUTHandler(SunwayRobot device, int timeout = 5)
            : base(device, $"INPUT A 6")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot INPUT Timeout");
                return true;
            }
            if (result.Data.Length == 1)
            {
                Device.SetWaferData(result.Data);
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot INPUT Response Error");
                return false;
            }

            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };

            ResponseMessage = msg;
            Device.NoteActionCompleted();
            handled = true;
            return true;
        }
    }

    public class SunwayRobotOutpOpenHandler : SunwayRobotHandler
    {
        //开真空
        public SunwayRobotOutpOpenHandler(SunwayRobot device, int timeout = 5)
            : base(device, $"OUTP 1 1")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot OutP Timeout");
                return true;
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot OutP Response Error");
                return false;
            }

            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };

            ResponseMessage = msg;
            //Device.NoteActionCompleted();
            handled = true;
            return true;
        }
    }
    public class SunwayRobotBOPTClosePHandler : SunwayRobotHandler
    {
        //打开夹爪
        public SunwayRobotBOPTClosePHandler(SunwayRobot device, int timeout = 60)
            : base(device, $"OUTP 1 1")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot OUTP Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {

            }
            else if (result.Data.Contains("ERR"))
            {
                return false;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }
    public class SunwayRobotOutpCloseHandler : SunwayRobotHandler
    {
        //关真空
        public SunwayRobotOutpCloseHandler(SunwayRobot device, int timeout = 5)
            : base(device, $"OUTP 1 0")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot OutP Timeout");
                return true;
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot OutP Response Error");
                return false;
            }

            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };

            ResponseMessage = msg;
            Device.NoteActionCompleted();
            handled = true;
            return true;
        }
    }
    public class SunwayRobotBOPTPHandler : SunwayRobotHandler
    {
        //打开夹爪
        public SunwayRobotBOPTPHandler(SunwayRobot device, int timeout = 60)
            : base(device, $"OUTP 1 0")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot OUTP Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {

            }
            else if (result.Data.Contains("ERR"))
            {
                return false;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotBRSRHandler : SunwayRobotHandler
    {
        //RSR
        public SunwayRobotBRSRHandler(SunwayRobot device, int timeout = 60)
            : base(device, $"RSR")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot RSR Timeout");
                return true;
            }
            if (result.Data.Length > 5)
            {
                Device.SetWaferData(result.Data);
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot RSR Response Error");
                return false;
            }

            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };

            ResponseMessage = msg;
            Device.NoteActionCompleted();
            handled = true;
            return true;
        }
    }

    public class SunwayRobotRespHandler : SunwayRobotHandler
    {
        //RESP 确认控制器是否成功建立与主控电脑的通信
        public SunwayRobotRespHandler(SunwayRobot device, int timeout = 60)
            : base(device, $"RESP")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot RESP Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {

            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot RESP Response Error");
                return false;
            }
            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotRemsHandler : SunwayRobotHandler
    {
        //RESP 确认控制器是否成功建立与主控电脑的通信
        public SunwayRobotRemsHandler(SunwayRobot device, int timeout = 60)
            : base(device, $"REMS")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot REMS Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot REMS Response Error");
                return false;
            }
            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }

    public class SunwayRobotSVONHandler : SunwayRobotHandler
    {
        //SVON 用以激磁位于机械手臂内之伺服马达
        public SunwayRobotSVONHandler(SunwayRobot device, int timeout = 60)
            : base(device, $"SET SERVOS ON")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot SVON Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot SVON Response Error");
                return false;
            }
            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }
    public class SunwayRobotMTCSPHandler : SunwayRobotHandler
    {
        //前往位置
        public SunwayRobotMTCSPHandler(SunwayRobot device, string module, string strAction, int timeout = 60)
            : base(device, $"MTCS {device.ModuleAssociateStationDic[$"{module}.{strAction}"]}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = module,
            };
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot MTCS Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {

            }
            else if (result.Data.Contains("ERR"))
            {
                return false;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }
    public class SunwayRobotMOVRGHandler : SunwayRobotHandler
    {
        //抬升或下降 一定距离
        public SunwayRobotMOVRGHandler(SunwayRobot device, int rDistance, int timeout = 60)
            : base(device, $"MOVR Z {rDistance}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot MOVR Z Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {
                Device.GetWaferData();
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot MOVR Z Response Error");
                return false;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }
    public class SunwayRobotMOVRPHandler : SunwayRobotHandler
    {
        //抬升或下降 一定距离
        public SunwayRobotMOVRPHandler(SunwayRobot device, int rDistance, int timeout = 60)
            : base(device, $"MOVR Z {rDistance}")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot MOVR Z Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {
                Device.PutWaferData();
            }
            else if (result.Data.Contains("ERR"))
            {
                Device.NoteError("Robot MOVR Z Response Error");
                return false;
            }
            ResponseMessage = msg;
            handled = true;
            return true;
        }
    }
    public class SunwayRobotRETHHandler : SunwayRobotHandler
    {
        //缩回
        public SunwayRobotRETHHandler(SunwayRobot device, int timeout = 60)
            : base(device, $"RETH")
        {
            AckTimeout = TimeSpan.FromSeconds(timeout);
            CompleteTimeout = TimeSpan.FromSeconds(timeout);

            device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = "ArmA.System",
            };
        }

        public override bool HandleMessage(MessageBase msg, out bool handled)
        {
            var result = msg as SunwayRobotMessage;
            handled = false;
            if (!result.IsResponse)
            {
                Device.NoteError("Robot RETH Timeout");
                return true;
            }
            if (result.Data == "_RDY")
            {
                Device.NotePickCompleted();
            }
            else if (result.Data.Contains("ERR"))
            {
                return false;
            }
            Device.MoveInfo = new RobotMoveInfo()
            {
                Action = RobotAction.Moving,
                ArmTarget = RobotArm.ArmA,
                BladeTarget = ModuleName.System.ToString(),
            };
            ResponseMessage = msg;
            handled = true;
            Device.NoteActionCompleted();
            return true;
        }
    }
}
