using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Sorter.Common;
using Aitex.Core.Common;
using MECF.Framework.Common.Equipment;
using CyberX8_RT.Devices;
using CyberX8_RT.Devices.YASKAWA;
using CyberX8_Core;
using MECF.Framework.Common.CommonData;

namespace CyberX8_RT.Devices.EFEM
{

    public abstract class EfemBase : BaseDevice, IDevice
    {
        public virtual ILoadport this[ModuleName mod] => throw new ApplicationException();

        // Properties
        //
        public new ModuleName Module { get; set; } = ModuleName.EFEM;
        public OnlineFlag OnlineFlag { get; set; }
        public bool CommunicationConnected { get; protected set; }

        protected object _lockerAction = new object();


        public string GripStateBlade1
        {
            get;
            set;
        }

        public string GripStateBlade2
        {
            get;
            set;
        }

        protected EfemBase()
        {
        }

        protected bool CheckEfemStatus()
        {
            if (Status == RState.Init)
            {
                LOG.Write(eEvent.ERR_EFEM_ROBOT, ModuleName.EFEM, "EFEM is not homed, please home first.");
                return false;
            }
            else if (Status == RState.Running)
            {
                LOG.Write(eEvent.ERR_EFEM_ROBOT, ModuleName.EFEM, $"EFEM is busy, please wait a minute");
                return false;
            }
            else if (Status == RState.Failed || Status == RState.Timeout)
            {
                LOG.Write(eEvent.ERR_EFEM_ROBOT, ModuleName.EFEM, "EFEM has a error, please check and fix the hardware issue and home it");
                return false;
            }

            return true;
        }

        public virtual bool Initialize()
        {
            return true;
        }

        public abstract void Monitor();
        public abstract void Terminate();
        public abstract void Reset();
        public abstract void SetOnline(bool online);
        public abstract void SetOnline(ModuleName mod, bool online);

        public abstract void SetBusy(ModuleName mod, bool online);

        public virtual RState Status { get; }
        public virtual RobotMoveInfo TMRobotMoveInfo { get; }
        public virtual bool IsHomed { get; }

        public virtual bool LiftIsUp { get; }
        public virtual bool LiftIsDown { get; }

        public abstract bool HomeAll();
        public abstract bool Home(ModuleName mod);
        public abstract bool OriginalSearch(ModuleName mod);
        public abstract bool CheckWaferPresence();
        public abstract string GetWaferPresence();
        public abstract bool Halt();
        public abstract bool ClearError();
        public abstract bool CloseBuzzer();
        public abstract bool PickExtend(ModuleName chamber, int slot, Hand hand);
        public abstract bool PickRetract(ModuleName chamber, int slot, Hand hand);
        public abstract bool PlaceExtend(ModuleName chamber, int slot, Hand hand);
        public abstract bool PlaceRetract(ModuleName chamber, int slot, Hand hand);
        public abstract bool Pick(ModuleName station, int slot, Hand hand);
        public abstract bool Place(ModuleName station, int slot, Hand hand);
        public abstract bool Goto(ModuleName station, Hand hand,string updown="UP");
        public abstract bool Grip(Hand blade, bool isGrip);
        public abstract bool GotoMap(ModuleName mod, Hand hand,string extend="EX");
        public abstract bool Map(ModuleName mod);

        public abstract bool RequestMapResult(ModuleName mod);
        public abstract bool Vacuum(ModuleName mod,bool VacuumState);
        public abstract bool SetPinUp(ModuleName mod);
        public abstract bool SetPinDown(ModuleName mod);

        public abstract bool SetAlignAngle(ModuleName mod,double angle);
        public abstract bool SetRobotSpeed(ModuleName mod,int speed);
        public abstract bool RobotPowerOn(ModuleName mod,bool status);
        public abstract bool Align(ModuleName mod, double angle,float delayTime, WaferSize size);
        public abstract bool SetLamp(LightType light, LightStatus status);
        public abstract bool Load(ModuleName mod);
        public abstract bool Unload(ModuleName mod);
        public abstract bool ReadCarrierId(ModuleName mod);
        public abstract bool WriteCarrierId(ModuleName mod, string id);
        public abstract bool ReadTagData(ModuleName mod);
        public abstract bool WriteTagData(ModuleName mod, string tagData);
        public abstract bool Dock(ModuleName mod);
        public abstract bool Undock(ModuleName mod);
        public abstract bool Clamp(ModuleName mod, bool isUnloadClamp);
        public abstract bool Unclamp(ModuleName mod);
        public abstract bool SetThickness(ModuleName mod, string thickness);
        public abstract void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target);

        public abstract bool GetWaferSize(ModuleName mod);
        public abstract bool SetWaferSize(ModuleName mod,int WaferSize);
    }
}