using NLog;
using SmartSEMControl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MeasureThread
{
    class Focus : IFocus
    {
        private Focusparam prm;
        private ISEMControl iSEM;
      private  NLog.Logger log;

        public Focus( ISEMControl iSEM)
        {
            log = NLog.LogManager.GetCurrentClassLogger();
           
            this.iSEM = iSEM ?? throw new ArgumentNullException(nameof(iSEM));
            this.log = log ?? throw new ArgumentNullException(nameof(log));
        }
        public Focusparam GetParam()
        {
            if (prm == null)
            {

                prm = new Focusparam();
            }
            return prm;
        }
        public bool SetMagnification(float newMag)
        {
            bool mRetMag = iSEM.SetMagnification(newMag);


            // 
            float set = newMag;
            Thread.Sleep(2000);
            float current = iSEM.GetMagnification();
            Thread.Sleep(200);
            while (Math.Abs(current - set) > 1)
            {
                iSEM.SetMagnification(set);
                Thread.Sleep(200);
                current = iSEM.GetMagnification();
            }
            Thread.Sleep(200);
            float cycle_time = iSEM.GetCycleTime();
            Thread.Sleep(Convert.ToInt32(cycle_time) + 100);
            return true;
        }
        public bool SetWorkingDistance(float newWdInMilimeter)
        {
            
            if (!iSEM.SetWorkingDistance(newWdInMilimeter/1000))//5.1mm  单位是米
            {
                log.Error("测量线程报错：重新设置到标准工作距离失败。", false);
                return false;
            }
            return true;
        }
     
        public bool DoFocusByNewMagnification(float newMag)
        {
            log.Warn("开始自动对焦！");
            // set magnification
            bool mRetMag = iSEM.SetMagnification(newMag);

         
            // 
            float set = newMag;
            Thread.Sleep(2000);
            float current = iSEM.GetMagnification();
            Thread.Sleep(200);
            while (Math.Abs(current - set) > 1)
            {
                iSEM.SetMagnification(set);
                Thread.Sleep(200);
                current = iSEM.GetMagnification();
            }
            Thread.Sleep(200);
            float cycle_time = iSEM.GetCycleTime();
            Thread.Sleep(Convert.ToInt32(cycle_time) + 100);
            // set the window of focusing.
            iSEM.SetReduced(prm.reduceWindowPos.X, prm.reduceWindowPos.Y, (int)prm.reduceWinWidth, (int)prm.reduceWinHeight);
            iSEM.CmdFocusScanSpeed("CMD_SCANRATE4");//
            if (prm.IfAutoBrightnessAndContrast)
            {
                iSEM.SetAutoBright(100);
                Thread.Sleep(200);
                iSEM.SetAutoContrast(100);
                Thread.Sleep(200);
                iSEM.SetAutoVideoBrightnessAndContrast();
                Thread.Sleep(10000);//adjust the brightness and contrast automaticaly 10 second
                iSEM.SetAutoVideoOff();
            }
            else
            {
                iSEM.SetAutoVideoOff();
                Thread.Sleep(200);
                iSEM.SetBrightness(prm.brightness);//50.0f
                Thread.Sleep(200);
                iSEM.SetContrast(prm.contrast);//30.0f
                Thread.Sleep(200);
            }

         

            bool ifStig =false;
            if (newMag > 5000)
            {
                ifStig = true;
            }
            if (!ImageFocus1(ifStig))
            {
                log.Error("自动对焦失败", false);
                iSEM.CloseReduced();
                return false;
            }

            iSEM.CloseReduced();
            Thread.Sleep(200);


            log.Warn("自动对焦结束！"+"ifStig="+ifStig.ToString());
            return true;


        }
        public bool DoFocusBySetMainParameter()
        {
            log.Warn("开始自动对焦！");
    
            // set magnification
            bool mRetMag=iSEM.SetMagnification(prm.mag);
            
            Thread.Sleep(2000);
            float current = iSEM.GetMagnification();
            while (Math.Abs(current - prm.mag) > 1)
            {
                iSEM.SetMagnification(prm.mag);
                Thread.Sleep(200);
                current = iSEM.GetMagnification();
            }
            Thread.Sleep(200);
            float cycle_time = iSEM.GetCycleTime();
            Thread.Sleep(Convert.ToInt32(cycle_time) + 100);
            // 
            if (!TiltCorrection(prm.tiltCorrAngle))
            {               
                return false;
            }
             float wd = iSEM.GetWorkingDistance();

           float offsetWd = Math.Abs(prm.workingDis - wd*1000);
            if (offsetWd > 3)//如果相差3mm以上，则重新设置，否则不动
            {
                log.Info("工作距离相差" + offsetWd + "mm");
                if (!iSEM.SetWorkingDistance(prm.workingDis / 1000))
                {

                    return false;
                }
                Thread.Sleep(1000);
            }
           
            // set the window of focusing.
            iSEM.SetReduced(prm.reduceWindowPos.X, prm.reduceWindowPos.Y, (int)prm.reduceWinWidth, (int)prm.reduceWinHeight);

            iSEM.CmdFocusScanSpeed("CMD_SCANRATE4");//
            if (prm.IfAutoBrightnessAndContrast)
            {
                iSEM.SetAutoBright(100);
                Thread.Sleep(200);
                iSEM.SetAutoContrast(100);
                Thread.Sleep(200);
                iSEM.SetAutoVideoBrightnessAndContrast();
                Thread.Sleep(10000);
                iSEM.SetAutoVideoOff();
            }
            else
            {
                iSEM.SetAutoVideoOff();
                Thread.Sleep(200);
                iSEM.SetBrightness(prm.brightness);//50.0f
                Thread.Sleep(200);
                iSEM.SetContrast(prm.contrast);//30.0f
                Thread.Sleep(200);
            }
          
            bool ifStig = false;
            if (prm.mag > 5000)
            {
                ifStig = true;
            }
            else
            {
                ifStig = prm.ifStig;
            }
            if (!ImageFocus1(ifStig))
            {
                log.Warn("自动对焦失败", false);
                iSEM.CloseReduced();
                return false;
            }

            iSEM.CloseReduced();
            Thread.Sleep(200);

            log.Warn("自动对焦结束！" + "ifStig=" + ifStig.ToString());
            return true;
        }

        public void setFocusParam(Focusparam param)
        {
            this.prm = param ;
           
        }
        //角度补偿
        public bool TiltCorrection(float a_fAngle)
        {
            float a = iSEM.GetTiltAngle();
            if (a != a_fAngle)
            {
                if (!iSEM.SetTiltAngleOn())
                {
                    return false;
                }
                Thread.Sleep(200);
                //恢复原始状态
                if (!iSEM.SetTiltAngle(a_fAngle))
                {
                    return false;
                }
                Thread.Sleep(2000);
            }
           
            return true;
        }
        //执行自动对焦
        public bool ImageFocus1(Boolean Is_Stig)
        {
            
                #region 执行蔡司自动对焦程序
                //服务地址
                string snumstr = @"http://192.168.1.101:8123";
                bool normalized;
               
                // 调用方法；只对焦不消像散
                if (Is_Stig)
                {
                    string focusstig = XmlRpcClient.autofocusstig(10, 3, 3, 3, 0.7, snumstr);//,normalized
                    if (focusstig != "success")
                    {
                        return false;
                    }
                }
                else
                {
                    string onlyfocus = XmlRpcClient.autofocus(10, 3, 3, true, snumstr);//,normalized
                    if (onlyfocus != "success")
                    {
                        return false;
                    }
                }
                #endregion
          
            return true;
        }
    }

}
