using GxIAPINET;
using irisHelper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using irisRefactor.IrisThread;

namespace irisRefactor.IrisCamera
{
    public class DH_CameraOperator
    {
        bool m_bIsOpen = false;                           ///<设备打开状态
        bool m_bIsSnap = false;                           ///<发送开采命令标识
        bool m_bTriggerMode = false;                           ///<是否支持触发模式
        bool m_bTriggerActive = false;                           ///<是否支持触发极性
        bool m_bTriggerSource = false;                           ///<是否支持触发源 
        bool m_bWhiteAuto = false;                           ///<标识是否支持白平衡
        bool m_bBalanceRatioSelector = false;                           ///<标识是否支持白平衡通道
        bool m_bWhiteAutoSelectedIndex = true;                            ///<白平衡列表框转换标志
        IGXFactory m_objIGXFactory = null;                            ///<Factory对像
        IGXDevice m_objIGXDevice = null;                            ///<设备对像
        IGXStream m_objIGXStream = null;                            ///<流对像
        IGXFeatureControl m_objIGXFeatureControl = null;                            ///<远端设备属性控制器对像
        IGXFeatureControl m_objIGXStreamFeatureControl = null;                            ///<流层属性控制器对象
        string m_strBalanceWhiteAutoValue = "Off";                           ///<自动白平衡当前的值
        GxBitmap m_objGxBitmap = null;                            ///<图像显示类对象
        string m_strFilePath = "";                              ///<应用程序当前路径

        public DH_CameraOperator()
        {
            m_objIGXFactory = IGXFactory.GetInstance();
            m_objIGXFactory.Init();
        }

        /// <summary>
        /// 相机初始化
        /// </summary>
        void __InitDevice()
        {
            if (null != m_objIGXFeatureControl)
            {
                //设置采集模式连续采集
                m_objIGXFeatureControl.GetEnumFeature("AcquisitionMode").SetValue("Continuous");

                m_objIGXFeatureControl.GetEnumFeature("TriggerMode").SetValue("Off");
            }
        }

        /// <summary>
        /// 关闭流
        /// </summary>
        private void __CloseStream()
        {
            try
            {
                //关闭流
                if (null != m_objIGXStream)
                {
                    m_objIGXStream.Close();
                    m_objIGXStream = null;
                    m_objIGXStreamFeatureControl = null;
                }
            }
            catch (Exception)
            {
            }
        }

        /// <summary>
        /// 关闭设备
        /// </summary>
        private void __CloseDevice()
        {
            try
            {
                //关闭设备
                if (null != m_objIGXDevice)
                {
                    m_objIGXDevice.Close();
                    m_objIGXDevice = null;
                }
            }
            catch (Exception)
            {
            }
        }

        public bool OpenDevice(PictureBox pictureBox)
        {
            try
            {
                List<IGXDeviceInfo> listGXDeviceInfo = new List<IGXDeviceInfo>();

                //关闭流
                __CloseStream();
                // 如果设备已经打开则关闭，保证相机在初始化出错情况下能再次打开
                __CloseDevice();

                m_objIGXFactory.UpdateDeviceList(200, listGXDeviceInfo);

                // 判断当前连接设备个数
                if (listGXDeviceInfo.Count <= 0)
                {
                    LogHelper.WriteErrorLog(MethodBase.GetCurrentMethod().DeclaringType, "未发现设备!");
                    MessageBox.Show("未发现设备!");
                    return false;
                }

                LogHelper.WriteDebugLog(MethodBase.GetCurrentMethod().DeclaringType, "枚举的设备数量：" + listGXDeviceInfo.Count + "[" + listGXDeviceInfo[0].GetDisplayName() + "]");

                // 如果设备已经打开则关闭，保证相机在初始化出错情况下能再次打开
                if (null != m_objIGXDevice)
                {
                    m_objIGXDevice.Close();
                    m_objIGXDevice = null;
                }

                //打开列表第一个设备

                m_objIGXDevice = m_objIGXFactory.OpenDeviceBySN(listGXDeviceInfo[0].GetSN(), GX_ACCESS_MODE.GX_ACCESS_EXCLUSIVE);
                m_objIGXFeatureControl = m_objIGXDevice.GetRemoteFeatureControl();


                //打开流
                if (null != m_objIGXDevice)
                {
                    m_objIGXStream = m_objIGXDevice.OpenStream(0);
                    m_objIGXStreamFeatureControl = m_objIGXStream.GetFeatureControl();
                }

                // 建议用户在打开网络相机之后，根据当前网络环境设置相机的流通道包长值，
                // 以提高网络相机的采集性能,设置方法参考以下代码。
                GX_DEVICE_CLASS_LIST objDeviceClass = m_objIGXDevice.GetDeviceInfo().GetDeviceClass();
                if (GX_DEVICE_CLASS_LIST.GX_DEVICE_CLASS_GEV == objDeviceClass)
                {
                    // 判断设备是否支持流通道数据包功能
                    if (true == m_objIGXFeatureControl.IsImplemented("GevSCPSPacketSize"))
                    {
                        // 获取当前网络环境的最优包长值
                        uint nPacketSize = m_objIGXStream.GetOptimalPacketSize();
                        // 将最优包长值设置为当前设备的流通道包长值
                        m_objIGXFeatureControl.GetIntFeature("GevSCPSPacketSize").SetValue(nPacketSize);
                    }
                }

                //初始化相机参数
                __InitDevice();

                m_objGxBitmap = new GxBitmap(m_objIGXDevice, pictureBox);

                // 更新设备打开标识
                m_bIsOpen = true;

                return true;
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrorLog(MethodBase.GetCurrentMethod().DeclaringType, ex.Message);
                return false;
            }
        }

        public void CloseDevice()
        {
            try
            {
                try
                {
                    // 如果未停采则先停止采集
                    if (m_bIsSnap)
                    {
                        if (null != m_objIGXFeatureControl)
                        {
                            m_objIGXFeatureControl.GetCommandFeature("AcquisitionStop").Execute();
                            m_objIGXFeatureControl = null;
                        }
                    }
                }
                catch (Exception)
                {

                }

                m_bIsSnap = false;

                try
                {
                    //停止流通道、注销采集回调和关闭流
                    if (null != m_objIGXStream)
                    {
                        m_objIGXStream.StopGrab();
                        //注销采集回调函数
                        m_objIGXStream.UnregisterCaptureCallback();
                        m_objIGXStream.Close();
                        m_objIGXStream = null;
                        m_objIGXStreamFeatureControl = null;
                    }
                }
                catch (Exception)
                {

                }

                try
                {
                    //关闭设备
                    if (null != m_objIGXDevice)
                    {
                        m_objIGXDevice.Close();
                        m_objIGXDevice = null;
                    }
                }
                catch (Exception)
                {

                }

                m_bIsOpen = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        public void StartDevice()
        {
            try
            {
                if (null != m_objIGXStreamFeatureControl)
                {
                    //设置流层Buffer处理模式为OldestFirst
                    m_objIGXStreamFeatureControl.GetEnumFeature("StreamBufferHandlingMode").SetValue("OldestFirst");
                }

                //开启采集流通道
                if (null != m_objIGXStream)
                {
                    //RegisterCaptureCallback第一个参数属于用户自定参数(类型必须为引用
                    //类型)，若用户想用这个参数可以在委托函数中进行使用
                    m_objIGXStream.RegisterCaptureCallback(this, __CaptureCallbackPro);
                    m_objIGXStream.StartGrab();
                }

                //发送开采命令
                if (null != m_objIGXFeatureControl)
                {
                    m_objIGXFeatureControl.GetCommandFeature("AcquisitionStart").Execute();
                }
                m_bIsSnap = true;

                LogHelper.WriteInfoLog(MethodBase.GetCurrentMethod().DeclaringType, "device started, ready to capture");
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrorLog(MethodBase.GetCurrentMethod().DeclaringType, ex.Message);
            }
        }

        public void StopDevice()
        {
            try
            {
                //发送停采命令
                if (null != m_objIGXFeatureControl)
                {
                    m_objIGXFeatureControl.GetCommandFeature("AcquisitionStop").Execute();
                }


                //关闭采集流通道
                if (null != m_objIGXStream)
                {
                    m_objIGXStream.StopGrab();
                    //注销采集回调函数
                    m_objIGXStream.UnregisterCaptureCallback();
                }

                m_bIsSnap = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        void ImageShowAndSave(IFrameData objIFrameData)
        {
            try
            {
                m_objGxBitmap.Show(objIFrameData);
            }
            catch (Exception)
            {
            }

            SaveImageTh.GetInstance.SaveImage(objIFrameData.GetBuffer());
        }

        /// <summary>
        /// 回调函数,用于获取图像信息和显示图像
        /// </summary>
        /// <param name="obj">用户自定义传入参数</param>
        /// <param name="objIFrameData">图像信息对象</param>
        private void __CaptureCallbackPro(object objUserParam, IFrameData objIFrameData)
        {
            try
            {
                DH_CameraOperator objGxSingleCam = objUserParam as DH_CameraOperator;
                objGxSingleCam.ImageShowAndSave(objIFrameData);
            }
            catch (Exception)
            {
            }
        }

        public IImageData TriggerGetOneFrame()
        {
            IImageData objIImageData = null;
            double dElapsedtime = 0;

            try
            {
                //每次发送触发命令之前清空采集输出队列
                //防止库内部缓存帧，造成本次GXGetImage得到的图像是上次发送触发得到的图
                if (null != m_objIGXStream)
                {
                    m_objIGXStream.FlushQueue();
                }

                //发送软触发命令
                if (null != m_objIGXFeatureControl)
                {
                    m_objIGXFeatureControl.GetCommandFeature("TriggerSoftware").Execute();
                }

                //获取图像
                if (null != m_objIGXStream)
                {

                    objIImageData = m_objIGXStream.GetImage(500);

                    LogHelper.WriteInfoLog(MethodBase.GetCurrentMethod().DeclaringType, "获取图像耗时：" + dElapsedtime);
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrorLog(MethodBase.GetCurrentMethod().DeclaringType, ex.Message);
                MessageBox.Show(ex.Message);
            }

            return objIImageData;
        }

        public void stop()
        {
            try
            {
                //发送停采命令
                if (null != m_objIGXFeatureControl)
                {
                    m_objIGXFeatureControl.GetCommandFeature("AcquisitionStop").Execute();
                }


                //关闭采集流通道
                if (null != m_objIGXStream)
                {
                    m_objIGXStream.StopGrab();
                    //注销采集回调函数
                    m_objIGXStream.UnregisterCaptureCallback();
                }


                m_bIsSnap = false;

            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(MethodBase.GetCurrentMethod().DeclaringType, ex.Message);
            }
        }

        public void close()
        {
            try
            {
                try
                {
                    // 如果未停采则先停止采集
                    if (m_bIsSnap)
                    {
                        if (null != m_objIGXFeatureControl)
                        {
                            m_objIGXFeatureControl.GetCommandFeature("AcquisitionStop").Execute();
                            m_objIGXFeatureControl = null;
                        }
                    }
                }
                catch (Exception)
                {

                }

                m_bIsSnap = false;

                try
                {
                    //停止流通道、注销采集回调和关闭流
                    if (null != m_objIGXStream)
                    {
                        m_objIGXStream.StopGrab();
                        //注销采集回调函数
                        m_objIGXStream.UnregisterCaptureCallback();
                        m_objIGXStream.Close();
                        m_objIGXStream = null;
                        m_objIGXStreamFeatureControl = null;
                    }
                }
                catch (Exception)
                {
                }

                try
                {
                    //关闭设备
                    if (null != m_objIGXDevice)
                    {
                        m_objIGXDevice.Close();
                        m_objIGXDevice = null;
                    }
                }
                catch (Exception)
                {

                }

                m_bIsOpen = false;
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrorLog(MethodBase.GetCurrentMethod().DeclaringType, ex.Message);
            }
        }


        public byte[] getByteImg(IFrameData objIFrameData)
        {
            int ylength = 1280 * 960;

            byte[] imgBytes = new byte[ylength];

            IntPtr pData = objIFrameData.GetBuffer();

            Marshal.Copy(pData, imgBytes, 0, ylength);

            return imgBytes;
        }

        private byte[] imageToByte(Image _image)
        {
            MemoryStream ms = new MemoryStream();
            _image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            return ms.ToArray();
        }


    }
}