using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZEISS.MTB.Api;
using YQLInterfaces;
using YQLUtils;
namespace ZeissMicroscopeAPI
{
    public class ZeissMicReader: YQLInterface, IMicroscope
    {
        private ZeissMicReader()
        {
            initialization("ZeissMicReader");
        }
        ~ZeissMicReader()
        {
            deinitialize();
        }
        public void Dispose()
        {
            deinitialize();
        }
        public override void initValue()
        {
            initManager();
        }
        public override void deleValue()
        {
            deleManager();
        }
        public IMicroscope Instance() { return GetInstance(); }
        private static IMicroscope uniqueInstance;

        // 定义一个标识确保线程同步
        private static readonly object locker = new object();


        /// <summary>
        /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
        /// </summary>
        /// <returns></returns>
        public static IMicroscope GetInstance()
        {
            // 当第一个线程运行到这里时，此时会对locker对象 "加锁"，
            // 当第二个线程运行该方法时，首先检测到locker对象为"加锁"状态，该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后（即线程运行完之后）会对该对象"解锁"
            // 双重锁定只需要一句判断就可以了
            if (uniqueInstance == null)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建，否则直接返回
                    if (uniqueInstance == null)
                    {
                        uniqueInstance = new ZeissMicReader();
                    }
                }
            }
            return uniqueInstance;
        }
        private IMTBDevice                  Microscope       = null;
        private MTBConnection               MicConnection    = null;
        private string                      MicID            = null;
        private IMTBRoot                    MicManager       = null;
        private Dictionary<string, object>  MicModules       = null;
        private string                      MicType          = null;
        private string                      MicVersion       = null;
        private bool                        isSucceed        = false;
        private bool                        isLogin          = false;
        private bool                        isInit           = false;
        private string                      MicAxisUnit      = null;
        private string                      MicUnit          = null;
        private string                      MicSpeedUnit     = null;
        private string                      MicLightUnit     = null;
        private int                         MicDeviceID      = 0   ;
        public IMTBDevice ZeissMicroscope { get { return Microscope; } }
        public bool IsLogin                        { get   { return isLogin ; } }
        public bool IsLogout                       { get   { return !isLogin; } }
        public bool IsInit                         { get   { return isLogin && isInit; } }
        public bool hasMicroscope           { get   { return Microscope     != null                             ; } }
        public bool hasMTBConnection        { get   { return MicConnection  != null                             ; } }            // 连接接口
        public bool hasMTBID                { get   { return MicID          != null && MicID.Length > 0         ; } }            // 模块序号
        public bool hasManager              { get   { return MicManager     != null                             ; } }             // 控制模块
        public bool hasMTBModules           { get   { return MicModules     != null                             ; } }            // 全部模块
        public int  Accessibility           { get   { return hasMicroscope ? (int)Microscope.Accessibility : (int)MTBAccessibility.None; } }
        public bool IsValid                 { get   { return hasManager && hasMTBConnection && hasMTBID && hasMTBModules ; } }
        public bool IsAvailable             { get   { return IsValid && hasMTBID && IsLogin && IsInit; } }
        public bool IsOpen                  { get   { return IsValid && hasMTBID && IsLogin && IsInit; } }
        public string MicroscopeType        { get   { return MicType        != null                      ? MicType    : Settings.DEFAULT_STRING; } }               // 蔡司显微镜型号
        public string MicroscopeVersion     { get   { return MicVersion     != null                      ? MicVersion : Settings.DEFAULT_STRING; } }               // 蔡司显微镜版本
        public string MicroscopeID          { get   { return MicID != null && MicID.Length > 0           ? MicID      : Settings.DEFAULT_STRING; } }               // 蔡司显微镜序号
        public bool   IsSucceed             { get   { return isSucceed; } }               // 当前加载状态
        public int DeviceID                 { get   { return MicDeviceID ; } set { MicDeviceID = value; } }
        public string MTBAxisUnit           { get   { return MicAxisUnit        != null ? MicAxisUnit : Settings.DEFAULT_STRING; } set {    MicAxisUnit  = value;   } }               // 显微镜轴移动单位
        public string MTBUnit               { get   { return MicUnit            != null ? MicUnit     : Settings.DEFAULT_STRING; } set {    MicUnit      = value;   } }               // 显微镜默认单位
        public string MTBSpeedUnit          { get   { return MicSpeedUnit       != null ? MicSpeedUnit: Settings.DEFAULT_STRING; } set {    MicSpeedUnit = value;   } }               // 显微镜速度单位
        public string MTBLightUnit          { get   { return MicLightUnit       != null ? MicLightUnit: Settings.DEFAULT_STRING; } set {    MicLightUnit = value;   } }               // 显微镜光源单位
        public int                      Open                            (                   ) {
            int isWarning = Settings.RECODE_FAILURE;
            try
            {
                initManager     ();
                initMicroscope  ();
                initMTBModules  ();
                var deviceCount = getDeviceCount();
                Console.WriteLine($"deviceCount:{deviceCount} IsLogin: {IsLogin} IsInit: {IsInit}");
                isWarning = isInit && deviceCount > 0 ? Settings.RECODE_SUCCEED : Settings.RECODE_FAILURE;

            }
            catch (Exception E) { YQLUtil.Print_Exception(E); }
            return isWarning;
        }
        public int                      Close                           (                   )  {
            int isWarning = Settings.RECODE_FAILURE;
            try
            {
                Logout();
                isWarning = IsLogout ? Settings.RECODE_SUCCEED : Settings.RECODE_FAILURE;

            }
            catch (Exception E) { YQLUtil.Print_Exception(E); }
            return isWarning;
        }
        public int                      ReOpen                          (                   )  {
            Close();
            return Open();
        }
        public void initMTBConnection           ()
        {
            try
            {
                if(!hasMTBConnection)
                {
                    MicConnection = new MTBConnection();
                }
            }
            catch (Exception E) { YQLUtil.Print_Exception(E);  MicConnection = null; }
        }
        public int getDeviceCount()
        {
            int DeviceCount = 0;
            try
            {
                if (hasManager)
                    DeviceCount = MicManager.GetDeviceCount();
            }
            catch (Exception E) { YQLUtil.Print_Exception(E); }
            return DeviceCount;
        }
        public void initMTBID                   ()
        {

            try
            {
                if (!hasMTBConnection)
                    initMTBConnection();
                Login();
            }
            catch (Exception E) { YQLUtil.Print_Exception(E);  MicID = null; }

        }
        public int Init    () {
            try
            {
                if(!IsInit)
                {
                    
                    if (!IsLogin)
                        Login();
                    
                    if (IsLogin && hasMTBConnection && hasMTBID)
                    {
                        MicConnection.Init(MicID);
                        isInit = MicConnection.ID.Length > 0;
                    }
                }
            }
            catch (Exception E) { YQLUtil.Print_Exception(E); isInit = false; }
            return hasMTBID ? Settings.RECODE_SUCCEED : Settings.RECODE_FAILURE;
        }
        public int Login   () {
            try
            {
                if(!IsLogin)
                {
                    if (!hasMTBConnection)
                        initMTBConnection();

                    if (hasMTBConnection)
                    {
                        MicID = "";
                        MicConnection.Login(Settings.MTBMicroscopeLanguage, out MicID);
                        isLogin = MicConnection.ID.Length > 0;
                        if (!isLogin)
                            MicID = null;
                        else
                            MicID = MicConnection.ID;

                    }
                }
                
            }
            catch (Exception E) { YQLUtil.Print_Exception(E); isLogin = false; }
            return hasMTBID ? Settings.RECODE_SUCCEED : Settings.RECODE_FAILURE;
        }
        public int Logout  () {
            try
            {
                if(isLogin)
                {
                    if(hasMTBConnection && hasMTBID)
                    {
                        MicConnection.Logout(MicID);
                    }
                    isLogin = false;
                    MicID   = null;
                }
            }
            catch (Exception E) { YQLUtil.Print_Exception(E);  }
            isLogin = false;
            return hasMTBID ? Settings.RECODE_FAILURE : Settings.RECODE_SUCCEED;
        }
        public void                     initManager                     (                   ) {
            try
            {
                if(!hasManager)
                {
                    if (!isLogin)
                        Login();
                    if (!IsInit)
                        Init();
                    if(isInit && hasMTBID && hasMTBConnection)
                    {
                        MicManager = MicConnection.GetRoot(MicID);
                        MicVersion = MicConnection.MTBVersion;
                        MicType    = MicConnection.MTBBuildVersion;
                    }
                }
                
            }
            catch (Exception E) { YQLUtil.Print_Exception(E); MicManager = null; }

        }
        public void                     deleManager                     (                   ) {
            try
            {
                if (hasManager)
                {
                    MicManager = null;
                }

            }
            catch (Exception E) { YQLUtil.Print_Exception(E); MicManager = null; }
            GC.Collect();
        }
        public void initMicroscope() {
            try
            {
                if(!hasMicroscope)
                {
                    if (!hasManager)
                        initManager();
                    if(hasManager)
                        Microscope = MicManager.GetDevice(MicDeviceID);

                }
            }
            catch (Exception E) { YQLUtil.Print_Exception(E); }
        }
        public void deleMicroscope() {
            try
            {
                Microscope = null;
                GC.Collect();
            }
            catch (Exception E) { YQLUtil.Print_Exception(E); }
        }
        public void                     initMTBModules                  (                   ) {
            try
            {
                if (!hasMTBModules)
                    MicModules = new Dictionary<string, object>();
                if(hasMicroscope)
                {
                    var componentCount = Microscope.GetComponentCount();
                    var buffer = "";
                    for (int index = 0; index < componentCount; index++)
                    {
                        IMTBComponent component = Microscope.GetComponent(index);
                        MicModules[component.ID] = component;
                        buffer += $"{component.ID}\t";
                    }
                    Console.WriteLine($"{buffer}\r\n");
                }
            }
            catch (Exception E) { YQLUtil.Print_Exception(E);  MicModules = null; }
        }
        public void                     deleMTBModules                  (                   ) {
            try
            {
                if(hasMTBModules)
                {
                    MicModules.Clear();
                }
            }
            catch (Exception E) { YQLUtil.Print_Exception(E); }
            MicModules = null;
            GC.Collect();
        }
        public string[]                 ComponentIDs                    (                   ) {
            var result = Settings.DEFAULT_STRING_ARRAY;
            try
            {
                if (hasMTBModules) 
                    result = MicModules.Keys.ToArray();
            }
            catch (Exception E) { YQLUtil.Print_Exception(E); }
            return result;
        }
        public IMTBComponent            Handler                         (string ComponentID )
        {
            IMTBComponent result = null;
            try
            {
                if (hasMTBModules && MicModules.ContainsKey(ComponentID))
                {
                    result = (IMTBComponent)MicModules[ComponentID];
                }
            }
            catch (Exception E) { YQLUtil.Print_Exception(E); }
            return result;
        }
        public IMTBFocus                FocusHandler                    { 
            get{
                IMTBFocus result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBFocus))
                    {
                        result = (IMTBFocus)MicModules[Settings.MTBFocus];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            } }
        public IMTBAxis                 AxisHandler
        {
            get
            {
                IMTBAxis result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBFocus))
                    {
                        result = (IMTBAxis)MicModules[Settings.MTBFocus];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBMove                 MoveHandler
        {
            get
            {
                IMTBMove result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBFocus))
                    {
                        result = (IMTBMove)MicModules[Settings.MTBFocus];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBContinualSpeed       SpeedHandler
        {
            get
            {
                IMTBContinualSpeed result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBFocus))
                    {
                        result = (IMTBContinualSpeed)MicModules[Settings.MTBFocus];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBChanger              RLTLHandler                     { 
            get{
                IMTBChanger result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBRLTLSwitch))
                    {
                        result = (IMTBChanger)MicModules[Settings.MTBRLTLSwitch];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            } }
        public IMTBObjectiveChanger ObjectiveHandler                { 
            get{
                IMTBObjectiveChanger result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBObjectiveChanger))
                    {
                        result = (IMTBObjectiveChanger)MicModules[Settings.MTBObjectiveChanger];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            } }
        public IMTBLamp                 HalogenLamp                     { 
            get{
                IMTBLamp result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBTLHalogenLamp))
                    {
                        result = (IMTBLamp)MicModules[Settings.MTBTLHalogenLamp];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            } }
        public IMTBLamp                 LampHandler                     { 
            get{
                IMTBLamp result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBTLHalogenLamp))
                    {
                        result = (IMTBLamp)MicModules[Settings.MTBTLHalogenLamp];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            } }
        public IMTBServo                ApblHandler                     { 
            get{
                IMTBServo result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBTLFieldStop))
                    {
                        result = (IMTBServo)MicModules[Settings.MTBTLFieldStop];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            } }
        public IMTBServo                LfblHandler
        {
            get
            {
                IMTBServo result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBTLFieldStop))
                    {
                        result = (IMTBServo)MicModules[Settings.MTBTLFieldStop];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBContrastChangerProperties               MTBCondenserProperties                  {
            get
            {
                IMTBContrastChangerProperties result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBCondenserProperties))
                    {
                        result = (IMTBContrastChangerProperties)MicModules[Settings.MTBCondenserProperties];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBEyepiece                                MTBEyePiece                             {
            get
            {
                IMTBEyepiece result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBEyePiece))
                    {
                        result = (IMTBEyepiece)MicModules[Settings.MTBEyePiece];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBFocus                                   MTBFocus                                {
            get
            {
                IMTBFocus result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBFocus))
                    {
                        result = (IMTBFocus)MicModules[Settings.MTBFocus];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBMicroscopeManager                       MTBMicroscopeManager                    {
            get
            {
                IMTBMicroscopeManager result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBMicroscopeManager))
                    {
                        result = (IMTBMicroscopeManager)MicModules[Settings.MTBMicroscopeManager];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBObject                                  MTBObject                               {
            get
            {
                IMTBObject result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBObject))
                    {
                        result = (IMTBObject)MicModules[Settings.MTBObject];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBObjectiveChanger                        MTBObjectiveChanger                     {
            get
            {
                IMTBObjectiveChanger result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBObjectiveChanger))
                    {
                        result = (IMTBObjectiveChanger)MicModules[Settings.MTBObjectiveChanger];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBChanger                                 MTBRLTLSwitch                           {
            get
            {
                IMTBChanger result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBRLTLSwitch))
                    {
                        result = (IMTBChanger)MicModules[Settings.MTBRLTLSwitch];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBServo                                   MTBTLFieldStop                          {
            get
            {
                IMTBServo result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBTLFieldStop))
                    {
                        result = (IMTBServo)MicModules[Settings.MTBTLFieldStop];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBFilterChanger                           MTBTLFilterChanger1                     {
            get
            {
                IMTBFilterChanger result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBTLFilterChanger1))
                    {
                        result = (IMTBFilterChanger)MicModules[Settings.MTBTLFilterChanger1];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBFilterChanger                           MTBTLFilterChanger2                     {
            get
            {
                IMTBFilterChanger result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBTLFilterChanger2))
                    {
                        result = (IMTBFilterChanger)MicModules[Settings.MTBTLFilterChanger2];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBLamp                                    MTBTLHalogenLamp                        {
            get
            {
                IMTBLamp result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBTLHalogenLamp))
                    {
                        result = (IMTBLamp)MicModules[Settings.MTBTLHalogenLamp];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
        public IMTBFilterChanger                           MTBTLVirtualFilterChanger
        {
            get
            {
                IMTBFilterChanger result = null;
                try
                {
                    if (hasMTBModules && MicModules.ContainsKey(Settings.MTBTLVirtualFilterChanger))
                    {
                        result = (IMTBFilterChanger)MicModules[Settings.MTBTLVirtualFilterChanger];
                    }
                }
                catch (Exception E) { YQLUtil.Print_Exception(E); }
                return result;
            }
        }
    }
}
