using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace N_Series_SDK
{
    public partial class KSPLIB_NSeries
    {
        public enum emCCDType
        {
            SP_CCD_SONY = 0,
            SP_CCD_TOSHIBA = 1,
            SP_CCD_PDA = 2,      // Back thinned CCD
            SP_CCD_G9212 = 3,      // InGaAs
            SP_CCD_S10420 = 4,      //Non Cooled BT Back thinned CCD
            SP_CCD_G92XX_256 = 5,
            SP_CCD_S10141 = 6,
            SP_CCD_TCD1304AP = 7
        }

        public enum emTriggerMode
        {
            SP_TRIGGER_FREERUN_PREV = 1,
            SP_TRIGGER_FREERUN_NEXT = 2,
            SP_TRIGGER_SOFTWARE = 3,
            SP_TRIGGER_EXTERNAL = 4,
            SP_TRIGGER_SYNCHRONOUS= 5,
        };

        public enum emErrorCode
        {
            SP_NO_ERROR = 1,
            SP_ERROR_DEVICE_IO_CTRL = -101,
            SP_ERROR_OPEN_DRIVER = -102,
            SP_ERROR_OPEN_FILE = -103,
            SP_ERROR_EEPROM_READ = -104,
            SP_ERROR_MEMORY_ALLOC = -105,
            SP_ERROR_AUTODARK = -106,
            SP_ERROR_NOTSUPORT_DEV = -107,
            SP_ERROR_INVALIDHANDLE = -108,
            SP_ERROR_INPUT_PARAM = -109,
            SP_ERROE_SHUTTER_VALUE = -110,
            SP_ERROE_FW_POSITION = -111,
            SP_EEPROM_READ_ERROR = -112,
            SP_ERROR_EEPROM_EMPTY = -113,
            SP_ERROR_DATA_LACK = -114,
            SP_ERROR_NOTFINDDEVICE = -115,
            SP_ERROR_ALREAYDOPENOTHERINF = -116,
            SP_ERROR_WAIT_TIMEOUT = -117,
            SP_ERROR_SCANNUM_RANGE = -118,
            SP_ERROR_SMOOTH_RANGE = -119,
            SP_ERROR_INVALIDVALUE = -120,
            SP_ERROR_INVALID_INPUTCHANNEL = -121,
            SP_ERROR_CHECKINTRERFACE = -122,
            SP_ERROR_MEMORY_EMPTY = -123,
            SP_ERROR_NOTSUPORT_MODE = -124,

            SP_ERROR_COM_SETTING = -201,
            SP_ERROR_COM_READ = -202,
            SP_ERROR_COM_WRITE = -203,
            SP_ERROR_COM_OPERATING = -204,
            SP_ERROR_COM_NOTMATCHDEV = -205,
            SP_ERROR_COM_NOTCONNECTION = -206,

            SP_ERROR_ETH_IPSCAN = -301,
            SP_ERROR_ETH_NOTMATCHDEV = -302,
            SP_ERROR_ETH_SOCKETCREATE = -303,
            SP_ERROR_ETH_SOCKETCONNECT = -304,
            SP_ERROR_ETH_TIMEOUT = -305,
            SP_ERROR_ETH_RECEIVE = -306,
            SP_ERROR_ETH_RECVBUFFER = -307,
            SP_EEROR_ETH_DISCONNECT = -308,
            SP_ERROR_ETH_SENDPACKET = -309,
            SP_ERROR_ETH_PACKET_SIZE_SMALL = -310,            
        };

        public enum emCCDPixelNumber
        {
            SP_CCD_PIXEL_G92XX_256 = 256,   // InGaAs
            SP_CCD_PIXEL_G92XX_256_REAL = 256,
            SP_CCD_PIXEL_G9212 = 512,   // InGaAs
            SP_CCD_PIXEL_G9212_REAL = 512,
            SP_CCD_PIXEL_PDA = 1056,    // Back thinned CCD, it has to be a multiple of "32"
            SP_CCD_PIXEL_PDA_REAL = 1024,
            SP_CCD_PIXEL_SONY = 2080,
            SP_CCD_PIXEL_SONY_REAL = 2048,
            SP_CCD_PIXEL_TOSHIBA = 3680,
            SP_CCD_PIXEL_TOSHIBA_REAL = 3648,
            SP_CCD_PIXEL_S10420 = 2080, // Non Cooled Back thined
            SP_CCD_PIXEL_S10420_REAL = 2048,
            SP_CCD_PIXEL_S10141 = 2080,
            SP_CCD_PIXEL_S10141_REAL = 2048,
            SP_CCD_PIXEL_TCD1304AP = 3680,
            SP_CCD_PIXEL_TCD1304AP_REAL = 3648
        };

        public enum emScanMode
        {
            SP_SCAN_ALLDEVICE = 0,
            SP_SCAN_CANNECTABLE = 1,
        }

        public enum emInterfaceType
        {
            SP_INTERFACE_USB = 0,
            SP_INTERFACE_ETHERNET = 1
        };

        public enum emNETMode
        {
            SP_NETMODE_DHCP = 0,
            SP_NETMODE_STATIC = 1
        }

        public enum emCalWavelength
        {
            SP_CALWL_COEFFICIENT = 0,
            SP_CALWL_CALPOINT = 1
        }


        [Serializable]
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct _DeviceList
        {
            public Int16 sInterfaceType;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
            public string strCOM;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
            public string strModel;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
            public string strSerial;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
            public string strIPAddr;
        }

        [Serializable]
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct _DevInformation
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
            public string strCOM;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
            public string strModel;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
            public string strSerial;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
            public string strIPAddr;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
            public string strStaticIPAddr;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
            public string strMACAddr;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3648)]
            public double[] dWLTable;
            public int iDummyPixel;
            public int iInttime;
            public int iTimeavg;
            public int iTotPixel;
            public int iRealPixel;
            public short sTrgMode;
            public short sInterfaceType;
            public short sNetMode;
            public short sChannel;
            public short sCCDType;
        }

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNScanDevice(short sScanMode = (short)emScanMode.SP_SCAN_CANNECTABLE);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNScanDevice_IP(char[] pcNetworkID, short sStartHostID, short sEndHostID);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNConnect(short sInterFace, string strConnectAddr);


        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNGetDeviceList([Out] _DeviceList[] stDevList);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNGetDevParam(ref _DevInformation stDevInfo, short sChannel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNDevInfo(StringBuilder Model, StringBuilder Serial, ref short sInterfaceType, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNGetCCDType(ref short sCCDType, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNGetEEPROM(StringBuilder pcEEPData, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNSetIntTime(Int32 lIntTime, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNSetDBLIntTime(double dIntTime, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNSetTimeAvg(short sAvgTime, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNSetTrgMode(short sTrgMode, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNSetDevice(Int32 lIntTime, short sAverage, short sTrgMode, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNGetWLTable(double[] WLTable, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNReadDataEx(int[] lpArray, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNGetNETInfo(StringBuilder pcIPAddr, StringBuilder pcMACAddr, ref short sNetMode, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern bool spNCheckConnection(short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNDevClose(short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNSetShutterPos(short sOpenClose, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNAutoDark(short sAutoDark, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNReadDataExOutTrg(int[] lpArray, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNSetOutTrgPin(short sOutPin, short sDelay, short Channel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern StringBuilder spNGetErrorString(short sErrorCode);

        //BurstMode Func
        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNStartBurstData(int iCount, short sChannel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNStartSyncTrgData(int iCount, short sChannel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNStopSyncTrgData(short sChannel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNGetBurstSingleData(int[] plData, short sChannel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNGetBurstData_DotNet(int iCount, byte[] pbDataList, short sChannel);
        //

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNPolyFit(double[] x, double[] y, short sNumPts, double[] pdCoeffs, short sOrder);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNPolyCalc(double[] pdCoefs, short sOrder, double x, ref double y);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNReadWLCalCoeff_User(double[] pdCoefs, ref short sOrder, short sChannel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNWriteWLCalCoeff_User(double[] pdCoefs, short sOrder, short sChannel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNReadWLCalPoint_User(double[] pdPixel, double[] pdWavelength, ref short sPointNum, short sChannel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNWriteWLCalPoint_User(double[] pdPixel, double[] pdWavelength, short sPointNum, short sChannel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNGetWLTable_User(double[] pdWLTable, short sSelMemory, short sChannel);

        [DllImport("Libraries\\SPdbEthm.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        private static extern short spNCalBinningAvg(short sCCDType, int[] lpInputData, short sBinning, double[] dpOutputData);

        public short NScanDevice(short sScanMode = (short)emScanMode.SP_SCAN_CANNECTABLE)
        {
             return spNScanDevice(sScanMode);
        }

        public short NScanDevice_IP(char[] pcNetworkID, short sStartHostID, short sEndHostID)
        {
            return spNScanDevice_IP(pcNetworkID, sStartHostID, sEndHostID);
        }

        public short NGetDeviceList([Out] _DeviceList[] stDevList)
        {
            return spNGetDeviceList(stDevList);
        }

        public short NGetDevParam(ref _DevInformation stDevInfo, short sChannel)
        {
            return spNGetDevParam(ref stDevInfo, sChannel);
        }

        public short NConnect(short sInterFaceType, string strConnectAddr)
        {
            return spNConnect(sInterFaceType, strConnectAddr);
        }

        public short NDevInfo(StringBuilder Model, StringBuilder Serial, ref short sInterfaceType, short Channel)
        {
            return spNDevInfo(Model, Serial, ref sInterfaceType, Channel);
        }

        public short NGetCCDType(ref short sCCDType, short Channel)
        {
            return spNGetCCDType(ref sCCDType, Channel);
        }

        public short NGetEEPROM(StringBuilder pcEEPData, short Channel)
        {
            return spNGetEEPROM(pcEEPData, Channel);
        }

        public short NSetIntTime(int lIntTime, short Channel)
        {
            return spNSetIntTime(lIntTime, Channel);
        }

        public short NSetDBLIntTime(double dIntTime, short Channel)
        {
            return spNSetDBLIntTime(dIntTime, Channel);
        }

        public short NSetTimeAvg(short sAvgTime, short Channel)
        {
            return spNSetTimeAvg(sAvgTime, Channel);
        }

        public short NSetTrgMode(short sTrgMode, short Channel)
        {
            return spNSetTrgMode(sTrgMode, Channel);
        }

        public short NSetShutterPos(short sCodeShutter, short Channel)
        {
            return spNSetShutterPos(sCodeShutter, Channel);
        }

        public short NSetDevice(int lIntTime, short sAverage, short sTrgMode, short Channel)
        {
            return spNSetDevice(lIntTime, sAverage, sTrgMode, Channel);
        }

        public short NGetWLTable(double[] WLTable, short Channel)
        {
            return spNGetWLTable(WLTable, Channel);
        }

        public short NReadDataEx(int[] lpArray, short Channel)
        {
            return spNReadDataEx(lpArray, Channel);
        }

        public short NGetNETInfo(StringBuilder pcIPAddr, StringBuilder pcMACAddr, ref short sNetMode, short Channel)
        {
            return spNGetNETInfo(pcIPAddr, pcMACAddr, ref sNetMode, Channel);
        }

        public bool NCheckConnection(short Channel)
        {
            return spNCheckConnection(Channel);
        }

        public short NDevClose(short Channel)
        {
            return spNDevClose(Channel);
        }

        public short NAutoDark(short sAutoDark, short Channel)
        {
            return spNAutoDark(sAutoDark,Channel);
        }

        public short NReadDataExOutTrg(int[] lpArray, short Channel)
        {
            return spNReadDataExOutTrg(lpArray, Channel);
        }

        public short NSetOutTrgPin(short sOutPin, short sDelay, short Channel)
        {
            return spNSetOutTrgPin(sOutPin, sDelay, Channel);
        }

        public StringBuilder NGetErrorString(short sErrorCode)
        {
             return spNGetErrorString(sErrorCode);
        }

        public short NStartBurstData(int iCount, short sChannel)
        {
            return spNStartBurstData(iCount, sChannel);
        }

        public short NStartSyncTrgData(int iCount, short sChannel)
        {
            return spNStartSyncTrgData( iCount, sChannel);
        }

        public short NStopSyncTrgData(short sChannel)
        {
            return spNStopSyncTrgData(sChannel);
        }

        public short NGetBurstSingleData(int[] plData, short sChannel)
        {
            return spNGetBurstSingleData(plData, sChannel);
        }

        public short NGetBurstData(int iCount, int[][] plDataList, short sChannel)
        {
            short sRtn;

            byte[] pbDataList = new byte[plDataList.Length * plDataList[0].Length * sizeof(int)];

            sRtn = spNGetBurstData_DotNet(iCount, pbDataList, sChannel);
            if (sRtn < 0)
                return sRtn;

            for (int i = 0; i < plDataList.Length; i++)
                Buffer.BlockCopy(pbDataList, i * plDataList[i].Length * sizeof(int), plDataList[i], 0, plDataList[i].Length * sizeof(int));

            return sRtn;
        }

        public short NPolyFit(double[] x, double[] y, short sNumPts, double[] pdCoeffs, short sOrder)
        {
            return spNPolyFit(x, y, sNumPts, pdCoeffs, sOrder);
        }

        public short NPolyCalc(double[] pdCoefs, short sOrder, double x, ref double y)
        {
            return spNPolyCalc(pdCoefs, sOrder, x, ref y);
        }

        public short NReadWLCalCoeff_User(double[] pdCoefs, ref short sOrder, short sChannel)
        {
            return spNReadWLCalCoeff_User(pdCoefs, ref sOrder, sChannel);
        }

        public short NWriteWLCalCoeff_User(double[] pdCoefs, short sOrder, short sChannel)
        {
            return spNWriteWLCalCoeff_User(pdCoefs, sOrder, sChannel);
        }

        public short NReadWLCalPoint_User(double[] pdPixel, double[] pdWavelength, ref short sPointNum, short sChannel)
        {
            return spNReadWLCalPoint_User(pdPixel, pdWavelength, ref sPointNum, sChannel);
        }

        public short NWriteWLCalPoint_User(double[] pdPixel, double[] pdWavelength, short sPointNum, short sChannel)
        {
            return spNWriteWLCalPoint_User(pdPixel, pdWavelength, sPointNum, sChannel);
        }

        public short NGetWLTable_User(double[] pdWLTable, short sSelMemory, short sChannel)
        {
            return spNGetWLTable_User(pdWLTable, sSelMemory, sChannel);
        }

        public short NCalBinningAvg(short sCCDType, int[] lpInputData, short sBinning, double[] dpOutputData)
        {
            return spNCalBinningAvg(sCCDType, lpInputData, sBinning, dpOutputData);
        }
    }
}
