using System;
using System.Text;

using Aitex.Core.RT.Device;
using Aitex.Sorter.Common;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.SubstrateTrackings;
using System.Text.RegularExpressions;
using Aitex.Core.Common;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Log;


namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot.MAG7
{
    public class Mag7RobotMotionHandler : ITransferMsg
    {
        public bool background { get; protected set; }
        public bool evt { get { return false; } }

        public string deviceID { private get; set; }

        public string _cmd = string.Empty;

        public IDevice Robot { set { _robot = (Robot)value; } }
        protected Robot _robot;

        public Mag7RobotMotionHandler()
        {
            background = false;
        }

        public virtual string package(params object[] args)
        {
            return "";
        }

        public bool unpackage(string type, string[] items)
        {
            if (type.Equals(ProtocolTag.resp_tag_excute))
            {
                update(items);  
 
                return true;
            }

            return !background;
        }


        protected virtual void update(string[] data)
        { 
        
        }
    }

 

    public class RbHomeHandler : Mag7RobotMotionHandler
    {
        public RbHomeHandler()
        {
            background = true;
        }

        public override string package(params object[] args)
        {
             updateBefore();
             return "HOME ALL";
        }

        protected void updateBefore()
        {
            _robot.Blade1Target = ModuleHelper.Converter(_robot.Name);
            _robot.Blade2Target = ModuleHelper.Converter(_robot.Name);

            _robot.CmdBladeTarget = $"{_robot.Name}.A";
            _robot.CmdBlade1Extend = "0";
            _robot.CmdBlade2Extend = "0";
        }

        protected override void update(string[] data)
        {
            _robot.Initalized = true;
            _robot.Swap = false;
        }
    }

    public class RbStopHandler : Mag7RobotMotionHandler
    {
        public RbStopHandler()
        {
            background = true;
        }
        //$,<UNo>(,<SeqNo>),CSTP,<Sw>(,<Sum>)<CR>
        public override string package(params object[] args)
        {
            return "PAUSE";
        }
    }

    public class PickHandler : Mag7RobotMotionHandler
    {
        private ModuleName _chamber;
        private int _slot;
        private Hand _hand;
        public PickHandler()
        {
            background = true;
        }
        /// <summary>
        /// PICK station [SLOT slot] <<(ARM)>[(A|B|AB)]> <PAN L|R> <CW|CCW>
        //[[RO r_offset] [TO t_offset] [ZO z_offset]]
        // [ALTWAFSPD(Y | N)]
        // [EX NO_VIA|RE NO_VIA]
        // [STRT(NR | R1 | R2 | VIA)]
        // [(GRIP(OFF | ON)]
        // [ENRT [(NR | R1 | R2 | VIA)]
        // [(GRIP(OFF | ON)]
        // In MAG6 Compatibility, entering the word ARM is optional and SLOT starts with 1; in VT5 Compatibility, ARM is required and SLOT starts with 0.


        public override string package(params object[] args)
        {
            // PICK<CR>
            _chamber = (ModuleName)args[0];
            _slot = (int)args[1];
            _hand = (Hand)args[2];

            updateBefore();

            return string.Format("PICK {0} ARM {1}",
                Mag7RobotConvertor.MapModuleSlot(_chamber, _slot),
                Mag7RobotConvertor.hand2string(_hand));
        }

        private void updateBefore()
        {
            _robot.Blade1Target = _chamber;
            _robot.Blade2Target = _chamber;

            string arm = _hand == Hand.Blade1 ? "A" : "B";
            _robot.CmdBladeTarget = $"{_chamber}.{arm}";
            _robot.CmdBlade1Extend = _hand==Hand.Blade1 ? "1" : "0";
            _robot.CmdBlade2Extend = _hand == Hand.Blade1 ? "0" : "1";
        }

        protected override void update(string[] data)
        {
            if (_hand == Hand.Both)
            {
                WaferManager.Instance.WaferMoved(_chamber, _slot, ModuleHelper.Converter(_robot.Name), (int)Hand.Blade1);
                WaferManager.Instance.WaferMoved(_chamber, _slot + 1, ModuleHelper.Converter(_robot.Name), (int)Hand.Blade2);
            }
            else
            {
                WaferManager.Instance.WaferMoved(_chamber, _slot, ModuleHelper.Converter(_robot.Name), (int)_hand);
            }


            string arm = _hand == Hand.Blade1 ? "A" : "B";
            _robot.CmdBladeTarget = $"{_chamber}.{arm}";
            _robot.CmdBlade1Extend = "0";
            _robot.CmdBlade2Extend = "0";

            _robot.Blade1Target = ModuleHelper.Converter(_robot.Name);
            _robot.Blade2Target = ModuleHelper.Converter(_robot.Name);
        }
    }

    public class PickExtendHandler : Mag7RobotMotionHandler
    {
        private ModuleName _chamber;
        private int _slot;
        private Hand _hand;
        public PickExtendHandler()
        {
            background = true;
        }
        /// <summary>
        /// PICK station [SLOT slot] <<(ARM)>[(A|B|AB)]> <PAN L|R> <CW|CCW>
        //[[RO r_offset] [TO t_offset] [ZO z_offset]]
        // [ALTWAFSPD(Y | N)]
        // [EX NO_VIA|RE NO_VIA]
        // [STRT(NR | R1 | R2 | VIA)]
        // [(GRIP(OFF | ON)]
        // [ENRT [(NR | R1 | R2 | VIA)]
        // [(GRIP(OFF | ON)]
        // In MAG6 Compatibility, entering the word ARM is optional and SLOT starts with 1; in VT5 Compatibility, ARM is required and SLOT starts with 0.


        public override string package(params object[] args)
        {
            // PICK<CR>
            _chamber = (ModuleName)args[0];
            _slot = (int)args[1];
            _hand = (Hand)args[2];

            updateBefore();

            return string.Format("PICK {0} ARM {1} ENRT NR",
                Mag7RobotConvertor.MapModuleSlot(_chamber, _slot),
                Mag7RobotConvertor.hand2string(_hand));
        }

        private void updateBefore()
        {

            string arm = _hand == Hand.Blade1 ? "A" : "B";
            _robot.CmdBladeTarget = $"{_chamber}.{arm}";
            _robot.CmdBlade1Extend = _hand == Hand.Blade1 ? "1" : "0";
            _robot.CmdBlade2Extend = _hand == Hand.Blade1 ? "0" : "1";

            _robot.Blade1Target = _chamber;
            _robot.Blade2Target = _chamber;
        }
    }

    public class PickRetractHandler : Mag7RobotMotionHandler
    {
        private ModuleName _chamber;
        private int _slot;
        private Hand _hand;
        public PickRetractHandler()
        {
            background = true;
        }
        /// <summary>
        /// PICK station [SLOT slot] <<(ARM)>[(A|B|AB)]> <PAN L|R> <CW|CCW>
        //[[RO r_offset] [TO t_offset] [ZO z_offset]]
        // [ALTWAFSPD(Y | N)]
        // [EX NO_VIA|RE NO_VIA]
        // [STRT(NR | R1 | R2 | VIA)]
        // [(GRIP(OFF | ON)]
        // [ENRT [(NR | R1 | R2 | VIA)]
        // [(GRIP(OFF | ON)]
        // In MAG6 Compatibility, entering the word ARM is optional and SLOT starts with 1; in VT5 Compatibility, ARM is required and SLOT starts with 0.


        public override string package(params object[] args)
        {
            // PICK<CR>
            _chamber = (ModuleName)args[0];
            _slot = (int)args[1];
            _hand = (Hand)args[2];

            updateBefore();

            return string.Format("PICK {0} ARM {1} STRT NR",
                Mag7RobotConvertor.MapModuleSlot(_chamber, _slot),
                Mag7RobotConvertor.hand2string(_hand));
        }

        private void updateBefore()
        {
            string arm = _hand == Hand.Blade1 ? "A" : "B";
            _robot.CmdBladeTarget = $"{_chamber}.{arm}";
            _robot.CmdBlade1Extend ="0";
            _robot.CmdBlade2Extend = "0";

            _robot.Blade1Target = _chamber;
            _robot.Blade2Target = _chamber;
        }

        protected override void update(string[] data)
        {
            _robot.Blade1Target = ModuleHelper.Converter(_robot.Name);
            _robot.Blade2Target = ModuleHelper.Converter(_robot.Name);
        }
    }

    public class PlaceHandler : Mag7RobotMotionHandler
    {
        private ModuleName _chamber;
        private int _slot;
        private Hand _hand;

        public PlaceHandler()
        {
            background = true;
        }

        public override string package(params object[] args)
        {
            // $,<UNo>(,<SeqNo>),MTRS,<Mtn>,<TrsSt>,<Slot>,<Posture>,<Hand>,<TrsPnt>(,<OfstX>,<OfstY>,<OfstZ>)(,<Angle>)(,<Sum>)<CR>
            _chamber = (ModuleName)args[0];
            _slot = (int)args[1];
            _hand = (Hand)args[2];
            updateBefore();
            return string.Format("PLACE {0} ARM {1}",
                Mag7RobotConvertor.MapModuleSlot(_chamber, _slot),
                Mag7RobotConvertor.hand2string(_hand));
        }

        private void updateBefore()
        {
            _robot.Blade1Target = _chamber;
            _robot.Blade2Target = _chamber;

            string arm = _hand == Hand.Blade1 ? "A" : "B";
            _robot.CmdBladeTarget = $"{_chamber}.{arm}";
            _robot.CmdBlade1Extend = _hand == Hand.Blade1 ? "1" : "0";
            _robot.CmdBlade2Extend = _hand == Hand.Blade1 ? "0" : "1";
        }


        protected override void update(string[] data)
        {
            if (_hand == Hand.Both)
            {
                WaferManager.Instance.WaferMoved(ModuleHelper.Converter(_robot.Name), (int)Hand.Blade1, _chamber, _slot);
                WaferManager.Instance.WaferMoved(ModuleHelper.Converter(_robot.Name), (int)Hand.Blade2, _chamber, _slot + 1);
            }
            else
            {
                WaferManager.Instance.WaferMoved(ModuleHelper.Converter(_robot.Name), (int)_hand, _chamber, _slot);
            }
            string arm = _hand == Hand.Blade1 ? "A" : "B";
            _robot.CmdBladeTarget = $"{_chamber}.{arm}";
            _robot.CmdBlade1Extend ="0";
            _robot.CmdBlade2Extend ="0";

            _robot.Blade1Target = ModuleHelper.Converter(_robot.Name);
            _robot.Blade2Target = ModuleHelper.Converter(_robot.Name);
        }
    }
    public class PlaceExtendHandler : Mag7RobotMotionHandler
    {
        private ModuleName _chamber;
        private int _slot;
        private Hand _hand;

        public PlaceExtendHandler()
        {
            background = true;
        }

        public override string package(params object[] args)
        {
            // $,<UNo>(,<SeqNo>),MTRS,<Mtn>,<TrsSt>,<Slot>,<Posture>,<Hand>,<TrsPnt>(,<OfstX>,<OfstY>,<OfstZ>)(,<Angle>)(,<Sum>)<CR>
            _chamber = (ModuleName)args[0];
            _slot = (int)args[1];
            _hand = (Hand)args[2];
            updateBefore();
            return string.Format("PLACE {0} ARM {1} ENRT NR",
                Mag7RobotConvertor.MapModuleSlot(_chamber, _slot),
                Mag7RobotConvertor.hand2string(_hand));
        }

        private void updateBefore()
        {
            _robot.Blade1Target = _chamber;
            _robot.Blade2Target = _chamber;

            string arm = _hand == Hand.Blade1 ? "A" : "B";
            _robot.CmdBladeTarget = $"{_chamber}.{arm}";
            _robot.CmdBlade1Extend = _hand == Hand.Blade1 ? "1" : "0";
            _robot.CmdBlade2Extend = _hand == Hand.Blade1 ? "0" : "1";
        }


        protected override void update(string[] data)
        {
            _robot.Blade1Target = ModuleHelper.Converter(_robot.Name);
            _robot.Blade2Target = ModuleHelper.Converter(_robot.Name);
        }
    }
    public class PlaceRetractHandler : Mag7RobotMotionHandler
    {
        private ModuleName _chamber;
        private int _slot;
        private Hand _hand;

        public PlaceRetractHandler()
        {
            background = true;
        }

        public override string package(params object[] args)
        {
            // $,<UNo>(,<SeqNo>),MTRS,<Mtn>,<TrsSt>,<Slot>,<Posture>,<Hand>,<TrsPnt>(,<OfstX>,<OfstY>,<OfstZ>)(,<Angle>)(,<Sum>)<CR>
            _chamber = (ModuleName)args[0];
            _slot = (int)args[1];
            _hand = (Hand)args[2];
            updateBefore();
            return string.Format("PLACE {0} ARM {1} STRT NR",
                Mag7RobotConvertor.MapModuleSlot(_chamber, _slot),
                Mag7RobotConvertor.hand2string(_hand));
        }

        private void updateBefore()
        {
            _robot.Blade1Target = _chamber;
            _robot.Blade2Target = _chamber;

            string arm = _hand == Hand.Blade1 ? "A" : "B";
            _robot.CmdBladeTarget = $"{_chamber}.{arm}";
            _robot.CmdBlade1Extend =  "0";
            _robot.CmdBlade2Extend =  "0";
        }


        protected override void update(string[] data)
        {
            _robot.Blade1Target = ModuleHelper.Converter(_robot.Name);
            _robot.Blade2Target = ModuleHelper.Converter(_robot.Name);
        }
    }

    public class ExchangHandler : Mag7RobotMotionHandler
    {
        private ModuleName _chamber;
        private int _slot;
        private Hand _hand;


        public ExchangHandler()
        {
            background = true;
        }

        public override string package(params object[] args)
        {
            // Picks from designated arm and places using other arm.<CR>
            _chamber = (ModuleName)args[0];
            _slot = (int)args[1];
            _hand = (Hand)args[2];
            if (_hand == Hand.Blade1)
                _hand = Hand.Blade2;
            else
                _hand = Hand.Blade1;

            updateBefore();


            return string.Format("SWAP {0} {1}",
                Mag7RobotConvertor.MapModuleSlot(_chamber, _slot),
                Mag7RobotConvertor.hand2string(_hand));
        }

        private void updateBefore()
        {
            _robot.Blade1Target = _chamber;
            _robot.Blade2Target = _chamber;
            _robot.Swap = true;
            _robot.PlaceBalde = _hand;
        }

        protected override void update(string[] data)
        {
            if (_hand == Hand.Blade2)
            {
                WaferManager.Instance.WaferMoved(_chamber, _slot, ModuleHelper.Converter(_robot.Name), (int)Hand.Blade2);
                WaferManager.Instance.WaferMoved(ModuleHelper.Converter(_robot.Name), (int)Hand.Blade1, _chamber, _slot);
            }
            else
            {
                WaferManager.Instance.WaferMoved(_chamber, _slot, ModuleHelper.Converter(_robot.Name), (int)Hand.Blade1);
                WaferManager.Instance.WaferMoved(ModuleHelper.Converter(_robot.Name), (int)Hand.Blade2, _chamber, _slot);
            }

            _robot.Swap = false;
            _robot.Blade1Target = ModuleHelper.Converter(_robot.Name);
            _robot.Blade2Target = ModuleHelper.Converter(_robot.Name);
        }
    }

    public class GotoHandler : Mag7RobotMotionHandler
    {
        private ModuleName _chamber;
        private int _slot;
        private Hand _hand;
        public GotoHandler()
        {
            background = true;
        }

        public override string package(params object[] args)
        {
            // Moves to a specified station-referenced location.< CR >
            _chamber = (ModuleName)args[0];
            _slot = (int)args[1];
            _hand = (Hand)args[2];

            updateBefore();
            return string.Format("GOTO N {0} ARM {1} R RE Z DN",
                Mag7RobotConvertor.MapModuleSlot(_chamber, _slot),
                Mag7RobotConvertor.hand2string(_hand));
        }

        private void updateBefore()
        {
            _robot.Blade1Target = _chamber;
            _robot.Blade2Target = _chamber;

            string arm = _hand == Hand.Blade1 ? "A" : "B";
            _robot.CmdBladeTarget = $"{_chamber}.{arm}";
            _robot.CmdBlade1Extend = "0";
            _robot.CmdBlade2Extend =  "0" ;
        }
    }


    public class ExtendHandler : Mag7RobotMotionHandler
    {
        private ModuleName _chamber;
        private int _slot;
        private Hand _hand;
        public ExtendHandler()
        {
            background = true;
        }

        public override string package(params object[] args)
        {
            // Moves to a specified station-referenced location.< CR >
            _chamber = (ModuleName)args[0];
            _slot = (int)args[1];
            _hand = (Hand)args[2];

            updateBefore();
            return string.Format("GOTO N {0} ARM {1} R EX Z DN",
                Mag7RobotConvertor.MapModuleSlot(_chamber, _slot),
                Mag7RobotConvertor.hand2string(_hand));
        }

        private void updateBefore()
        {
            _robot.Blade1Target = _chamber;
            _robot.Blade2Target = _chamber;

            string arm = _hand == Hand.Blade1 ? "A" : "B";
            _robot.CmdBladeTarget = $"{_chamber}.{arm}";
            _robot.CmdBlade1Extend = _hand == Hand.Blade1 ? "1" : "0";
            _robot.CmdBlade2Extend = _hand == Hand.Blade1 ? "0" : "1";
        }
    }

    public class RetractHandler : Mag7RobotMotionHandler
    {
        private ModuleName _chamber;
        private int _slot;
        private Hand _hand;
        public RetractHandler()
        {
            background = true;
        }

        public override string package(params object[] args)
        {
            // Moves to a specified station-referenced location.< CR >
            _chamber = (ModuleName)args[0];
            _slot = (int)args[1];
            _hand = (Hand)args[2];

            updateBefore();
            return string.Format("GOTO N {0} ARM {1} R RE Z DN",
                Mag7RobotConvertor.MapModuleSlot(_chamber, _slot),
                Mag7RobotConvertor.hand2string(_hand));
        }

        private void updateBefore()
        {
            _robot.Blade1Target = _chamber;
            _robot.Blade2Target = _chamber;

            string arm = _hand == Hand.Blade1 ? "A" : "B";
            _robot.CmdBladeTarget = $"{_chamber}.{arm}";
            _robot.CmdBlade1Extend =  "0";
            _robot.CmdBlade2Extend =  "0"  ;
        }
    }

    public class RbSetSpeedHandler : Mag7RobotMotionHandler
    {
        private int _speed = 0;
        public RbSetSpeedHandler()
        {
            background = false;
        }

        public override string package(params object[] args)
        {
            _speed = (int)args[0];

            string speed = "LOSPD";
            switch (_speed)
            {
                case 1:    //low
                    speed = "LOSPD";
                    break;
                case 2:    //Medium
                    speed = "MESPD";
                    break;
                case 3:    //high
                    speed = "HISPD";
                    break;
            }
            return string.Format(" SET LOSPD Y", speed);
        }
    }


    public class RbSetCommunicationHandler : Mag7RobotMotionHandler
    {
        public RbSetCommunicationHandler()
        {
            background = true;
        }
        //SET COMM [M/B (MON|PKT)] [FLOW (SEQ|BKG|BKG+|MULTI|MULTI_DEV)]
        //[LF(ON | OFF)]
        //[ECHO(ON | OFF)]
        //[CHECKSUM(ON | OFF)]
        //[ERRLVL err_level]
        //[DREP(AUT | REQ)]
        //[ERR_REP(AUT | REQ)]
        //[RR(ON | OFF)]
        public override string package(params object[] args)
        {
            return string.Format("SET COMM {0} {1} {2} {3}",
                "M/B PKT",  // packet mode
                "FLOW SEQ", // sequential mode
                "ECHO OFF", // echo off
                "CHECKSUM OFF" // echo off

            );
        }
    }

    public class RbSetLoadHandler : Mag7RobotMotionHandler
    {
        public RbSetLoadHandler()
        {
            background = true;
        }
        //SET LOAD <<(ARM)>[(A | B)]> <PAN L|R> (?|ON|OFF)
        //RQ LOAD <<(ARM)>[(A | B)]> <PAN L|R>
        public override string package(params object[] args)
        {
            Hand hand = (Hand)args[0];

            return string.Format("SET LOAD {0} OFF", hand==Hand.Blade1?"A":"B");
        }
    }

    public class RbCheckLoadHandler : Mag7RobotMotionHandler
    {
        public RbCheckLoadHandler()
        {
            background = true;
        }
        //CHECK LOAD[station] [(A | B)] <PAN L|R> [[INTLCK ALL| (DIS|ENB)]| [EX_ENABLE
        //    (DIS | ENB)] |[SBIT_SLVL_SEN(DIS | ENB)] |[VLV_SEN(DIS | ENB)]
        public override string package(params object[] args)
        {
            ModuleName module = (ModuleName)args[0];
            int slot = (int) args[1];

            return string.Format("CHECK LOAD {0} INTLCK ALL DIS", Mag7RobotConvertor.MapModule(module));
        }
    }


    public class RbRequestWaferPresentHandler : ITransferMsg
    {
        public RbRequestWaferPresentHandler()
        {
            background = true;
        }
        //RQ WAFER PRESENT <<(ARM)>[(A|B|AB)]>
        public IDevice Robot { get; set; }
        public bool background { get; }
        public bool evt { get; }

        public string package(params object[] args)
        {
            return string.Format("RQ WAFER PRESENT AB");
        }

        public bool unpackage(string type, string[] items)
        {
            //WAFER PRESENT Y N
            if (type.Equals(ProtocolTag.resp_tag_excute))
            {
                return true;
            }


            if (items.Length == 4)
            {
                if (items[2] == "Y")
                   ((Robot)Robot).NotifyWaferPresent(Hand.Blade1, WaferStatus.Normal);
                if (items[2] == "?")
                    ((Robot)Robot).NotifyWaferPresent(Hand.Blade1, WaferStatus.Unknown);
                if (items[2] == "N")
                    ((Robot)Robot).NotifyWaferPresent(Hand.Blade1, WaferStatus.Empty);

                if (items[3] == "Y")
                    ((Robot)Robot).NotifyWaferPresent(Hand.Blade2, WaferStatus.Normal);
                if (items[3] == "?")
                    ((Robot)Robot).NotifyWaferPresent(Hand.Blade2, WaferStatus.Unknown);
                if (items[3] == "N")
                    ((Robot)Robot).NotifyWaferPresent(Hand.Blade2, WaferStatus.Empty);
            }
            else
            {
                EV.PostWarningLog(Robot.Module, $"Request Wafer Present return unexpected feedback");
                return false;
            }

            return false;
        }
    }

    public class RBQueryStateHandler : ITransferMsg
    {
        public bool background { get; protected set; }
        public bool evt { get { return false; } }
        public string deviceID { private get; set; }

        public string _cmd = string.Empty;

        public IDevice Robot { set { _device = (Robot)value; } }
        protected Robot _device;

        public RBQueryStateHandler()
        {
            background = false;
        }

        //$,<UNo>(,<SeqNo>),RSTS(,<Sum>)<CR> 
     
        public string package(params object[] args)
        {
            return ",RSTS,";
        }

        public bool unpackage(string type, string[] items)
        {

            return !background;
        }
    }

    public class RbEventHandler : ITransferMsg
    {
        public bool background { get { return false; } }
        public bool evt { get { return true; } }
        public string deviceID { private get; set; }

        public string _cmd = string.Empty;

        public IDevice Robot { set { _device = (Robot)value; } }
        protected Robot _device;

        public RbEventHandler()
        {
        }

        //$,<UNo>(,<SeqNo>),RSTS(,<Sum>)<CR> 

        public string package(params object[] args)
        {
            return "";
        }

        public bool unpackage(string type, string[] items)
        {
            return true;
        }
    }

    public class RBQueryPositionHandler : ITransferMsg
    {
        public bool background { get; protected set; }
        public bool evt { get { return false; } }
        public string deviceID { private get; set; }

        public string _cmd = string.Empty;
        public IDevice Robot { set { _device = (Robot)value; } }
        protected Robot _device;

        public RBQueryPositionHandler()
        {
            background = false;

        }

        //RQ POS ABS ALL
        //POS ABS(A|B) rVal tVal zVal sVal wVal waVal wbVal

        public string package(params object[] args)
        {
            return "RQ POS ABS ALL";
        }

        public bool unpackage(string type, string[] items)
        {
            //POS ABS (A|B) rVal tVal zVal sVal wVal waVal wbVal
             //Radial: rVal
             //Theta:tVal
             //Z:zVal
             //S:sVal
             //W:wVal
             //WA:waVal
             //WB:wbVal
            if (items.Length == 9)
            {  
                _device.Rotation = int.Parse(items[1]);
                
                return true;
            }

            return !background;
        }
    }
}