using System;
using System.Text;
using System.Runtime.InteropServices;

namespace EyeTrackingController
{
    public class EyeTrackingController
    {
        // API Enum definition. See the manual for further description. 
        public enum CalibrationstatusEnum
        {
            unknownCalibrationStatus = 0,
            noCalibration = 1,
            validCalibration = 2,
            performingCalibration = 3
        }

        // API Struct definition. See the manual for further description. 
        public struct SystemInfoStruct
        {
            public int samplerate;
            public int iV_MajorVersion;
            public int iV_MinorVersion;
            public int iV_Buildnumber;
            public int API_MajorVersion;
            public int API_MinorVersion;
            public int API_Buildnumber;
            public int iV_ETSystem;
        };

        public struct CalibrationPointStruct
        {
            public int number;
            public int positionX;
            public int positionY;
        };


        public struct EyeDataStruct
        {
            public double gazeX;
            public double gazeY;
            public double diam;
            public double eyePositionX;
            public double eyePositionY;
            public double eyePositionZ;
        };


        public struct SampleStruct
        {
            public Int64 timestamp;
            public EyeDataStruct leftEye;
            public EyeDataStruct rightEye;
        };

        public struct EventStruct
        {
            public char eventType;
            public char eye;
            public Int64 startTime;
            public Int64 endTime;
            public Int64 duration;
            public double positionX;
            public double positionY;
        };

        public struct AccuracyStruct
        {
            public double deviationLX;
            public double deviationLY;
            public double deviationRX;
            public double deviationRY;
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct CalibrationStruct
        {
            public int method;
            public int visualization;
            public int displayDevice;
            public int speed;
            public int autoAccept;
            public int foregroundColor;
            public int backgroundColor;
            public int targetShape;
            public int targetSize;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public string targetFilename;
        };

        public struct MonitorAttachedGeometryStruct
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public string setupName;
            public int stimX;
            public int stimY;
            public int redStimDistHeight;
            public int redStimDistDepth;
            public int redInclAngle;
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct ImageStruct
        {
            public int imageHeight;
            public int imageWidth;
            public int imageSize;
            public IntPtr imageBuffer;
        };

        public struct DateStruct
        {
            public int day;
            public int month;
            public int year;
        };

        // API Function definition. See the manual for further description. 
        [DllImport("myGazeAPI.dll", EntryPoint = "iV_AbortCalibration")]
        private static extern int Unmanaged_AbortCalibration();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_AcceptCalibrationPoint")]
        private static extern int Unmanaged_AcceptCalibrationPoint();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_Calibrate")]
        private static extern int Unmanaged_Calibrate();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_ChangeCalibrationPoint")]
        private static extern int Unmanaged_ChangeCalibrationPoint(int number, int positionX, int positionY);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_Connect")]
        private static extern int Unmanaged_Connect();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_ContinueEyetracking")]
        private static extern int Unmanaged_ContinueEyetracking();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_DeleteMonitorAttachedGeometry")]
        private static extern int Unmanaged_DeleteMonitorAttachedGeometry(StringBuilder name);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_DisableProcessorHighPerformanceMode")]
        private static extern int Unmanaged_DisableProcessorHighPerformanceMode();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_Disconnect")]
        private static extern int Unmanaged_Disconnect();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_EnableProcessorHighPerformanceMode")]
        private static extern int Unmanaged_EnableProcessorHighPerformanceMode();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_GetAccuracy")]
        private static extern int Unmanaged_GetAccuracy(ref AccuracyStruct accuracyData);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_GetAccuracyImage")]
        private static extern int Unmanaged_GetAccuracyImage(ref ImageStruct imageData);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_GetCalibrationParameter")]
        private static extern int Unmanaged_GetCalibrationParameter(ref CalibrationStruct calibrationData);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_GetCalibrationStatus")]
        private static extern int Unmanaged_GetCalibrationStatus(ref CalibrationstatusEnum calibrationStatus);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_GetCurrentMonitorAttachedGeometry")]
        private static extern int Unmanaged_GetCurrentMonitorAttachedGeometry(ref MonitorAttachedGeometryStruct monitorAttachedGeometry);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_GetCurrentTimestamp")]
        private static extern int Unmanaged_GetCurrentTimestamp(ref Int64 currentTimestamp);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_GetEvent")]
        private static extern int Unmanaged_GetEvent(ref EventStruct eventDataSample);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_GetGeometryProfiles")]
        private static extern int Unmanaged_GetGeometryProfiles(int maxSize, ref StringBuilder profileNames);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_GetLicenseDueDate")]
        private static extern int Unmanaged_GetLicenseDueDate(ref DateStruct licenseDueDate);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_GetMonitorAttachedGeometry")]
        private static extern int Unmanaged_GetMonitorAttachedGeometry(StringBuilder profileName, ref MonitorAttachedGeometryStruct monitorAttachedGeometry);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_GetSample")]
        private static extern int Unmanaged_GetSample(ref SampleStruct rawDataSample);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_GetSerialNumber")]
        private static extern int Unmanaged_GetSerialNumber(ref StringBuilder serialNumber);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_GetSystemInfo")]
        private static extern int Unmanaged_GetSystemInfo(ref SystemInfoStruct systemInfoData);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_GetTrackingMonitor")]
        private static extern int Unmanaged_GetTrackingMonitor(ref ImageStruct imageData);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_IsConnected")]
        private static extern int Unmanaged_IsConnected();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_LoadCalibration")]
        private static extern int Unmanaged_LoadCalibration(StringBuilder name);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_PauseEyetracking")]
        private static extern int Unmanaged_PauseEyetracking();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_Quit")]
        private static extern int Unmanaged_Quit();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_ResetCalibrationPoints")]
        private static extern int Unmanaged_ResetCalibrationPoints();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_SaveCalibration")]
        private static extern int Unmanaged_SaveCalibration(StringBuilder aoiName);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_SetConnectionTimeout")]
        private static extern int Unmanaged_SetConnectionTimeout(int time);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_SetGeometryProfile")]
        private static extern int Unmanaged_SetGeometryProfile(StringBuilder profileName);

        [DllImport("myGazeAPI.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "iV_SetEventCallback")]
        private static extern void Unmanaged_SetEventCallback(MulticastDelegate eventCallbackFunction);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_SetEventDetectionParameter")]
        private static extern int Unmanaged_SetEventDetectionParameter(int minDuration, int maxDispersion);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_SetLicense")]
        private static extern int Unmanaged_SetLicense(StringBuilder licenseKey);

        [DllImport("myGazeAPI.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "iV_SetSampleCallback")]
        private static extern void Unmanaged_SetSampleCallback(MulticastDelegate sampleCallbackFunction);

        [DllImport("myGazeAPI.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "iV_SetTrackingMonitorCallback")]
        private static extern void Unmanaged_SetTrackingMonitorCallback(MulticastDelegate trackingMonitorCallbackFunction);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_SetupCalibration")]
        private static extern int Unmanaged_SetupCalibration(ref CalibrationStruct calibrationData);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_SetupMonitorAttachedGeometry")]
        private static extern int Unmanaged_SetupMonitorAttachedGeometry(ref MonitorAttachedGeometryStruct monitorAttachedGeometry);

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_ShowAccuracyMonitor")]
        private static extern int Unmanaged_ShowAccuracyMonitor();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_ShowTrackingMonitor")]
        private static extern int Unmanaged_ShowTrackingMonitor();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_Start")]
        private static extern int Unmanaged_Start();

        [DllImport("myGazeAPI.dll", EntryPoint = "iV_Validate")]
        private static extern int Unmanaged_Validate();

        public int iV_AbortCalibration()
        {
            return Unmanaged_AbortCalibration();
        }

        public int iV_AcceptCalibrationPoint()
        {
            return Unmanaged_AcceptCalibrationPoint();
        }

        public int iV_Calibrate()
        {
            return Unmanaged_Calibrate();
        }

        public int iV_ChangeCalibrationPoint(int number, int positionX, int positionY)
        {
            return Unmanaged_ChangeCalibrationPoint(number, positionX, positionY);
        }

        public int iV_Connect()
        {
            return Unmanaged_Connect();
        }

        public int iV_ContinueEyetracking()
        {
            return Unmanaged_ContinueEyetracking();
        }

        public int iV_DeleteMonitorAttachedGeometry(StringBuilder name)
        {
            return Unmanaged_DeleteMonitorAttachedGeometry(name);
        }

        public int iV_DisableProcessorHighPerformanceMode()
        {
            return Unmanaged_DisableProcessorHighPerformanceMode();
        }

        public int iV_Disconnect()
        {
            return Unmanaged_Disconnect();
        }

        public int iV_EnableProcessorHighPerformanceMode()
        {
            return Unmanaged_EnableProcessorHighPerformanceMode();
        }

        public int iV_GetAccuracy(ref AccuracyStruct accuracyData)
        {
            return Unmanaged_GetAccuracy(ref accuracyData);
        }

        public int iV_GetAccuracyImage(ref ImageStruct image)
        {
            return Unmanaged_GetAccuracyImage(ref image);
        }

        public int iV_GetCalibrationParameter(ref CalibrationStruct calibrationData)
        {
            return Unmanaged_GetCalibrationParameter(ref calibrationData);
        }

        public int iV_GetCalibrationStatus(ref CalibrationstatusEnum calibrationStatus)
        {
            return Unmanaged_GetCalibrationStatus(ref calibrationStatus);
        }

        public int iV_GetCurrentMonitorAttachedGeometry(ref MonitorAttachedGeometryStruct monitorAttachedGeometry)
        {
            return Unmanaged_GetCurrentMonitorAttachedGeometry(ref monitorAttachedGeometry);
        }

        public int iV_GetCurrentTimestamp(ref Int64 currentTimestamp)
        {
            return Unmanaged_GetCurrentTimestamp(ref currentTimestamp);
        }

        public int iV_GetEvent(ref EventStruct eventDataSample)
        {
            return Unmanaged_GetEvent(ref eventDataSample);
        }

        public int iV_GetGeometryProfiles(int maxSize, ref StringBuilder profileNames)
        {
            return Unmanaged_GetGeometryProfiles(maxSize, ref profileNames);
        }

        public int iV_GetLicenseDueDate(ref DateStruct licenseDueDate)
        {
            return Unmanaged_GetLicenseDueDate(ref licenseDueDate);
        }

        public int iV_GetMonitorAttachedGeometry(StringBuilder profileName, ref MonitorAttachedGeometryStruct monitorAttachedGeometry)
        {
            return Unmanaged_GetMonitorAttachedGeometry(profileName, ref monitorAttachedGeometry);
        }

        public int iV_GetSample(ref SampleStruct rawDataSample)
        {
            return Unmanaged_GetSample(ref rawDataSample);
        }

        public int iV_GetSerialNumber(ref StringBuilder serialNumber)
        {
            return Unmanaged_GetSerialNumber(ref serialNumber);
        }

        public int iV_GetSystemInfo(ref SystemInfoStruct systemInfo)
        {
            return Unmanaged_GetSystemInfo(ref systemInfo);
        }

        public int iV_GetTrackingMonitor(ref ImageStruct image)
        {
            return Unmanaged_GetTrackingMonitor(ref image);
        }

        public int iV_IsConnected()
        {
            return Unmanaged_IsConnected();
        }

        public int iV_LoadCalibration(StringBuilder name)
        {
            return Unmanaged_LoadCalibration(name);
        }

        public int iV_PauseEyetracking()
        {
            return Unmanaged_PauseEyetracking();
        }

        public int iV_Quit()
        {
            return Unmanaged_Quit();
        }

        public int iV_ResetCalibrationPoints()
        {
            return Unmanaged_ResetCalibrationPoints();
        }

        public int iV_SaveCalibration(StringBuilder name)
        {
            return Unmanaged_SaveCalibration(name);
        }

        public void iV_SetConnectionTimeout(int time)
        {
            Unmanaged_SetConnectionTimeout(time);
        }

        public void iV_SetGeometryProfile(StringBuilder profileName)
        {
            Unmanaged_SetGeometryProfile(profileName);
        }

        public void iV_SetEventCallback(MulticastDelegate eventCallback)
        {
            Unmanaged_SetEventCallback(eventCallback);
        }

        public int iV_SetEventDetectionParameter(int minDuration, int maxDispersion)
        {
            return Unmanaged_SetEventDetectionParameter(minDuration, maxDispersion);
        }

        public int iV_SetLicense(StringBuilder key)
        {
            return Unmanaged_SetLicense(key);
        }

        public void iV_SetSampleCallback(MulticastDelegate sampleCallback)
        {
            Unmanaged_SetSampleCallback(sampleCallback);
        }

        public void iV_SetTrackingMonitorCallback(MulticastDelegate trackingMonitorCallback)
        {
            Unmanaged_SetTrackingMonitorCallback(trackingMonitorCallback);
        }

        public int iV_SetupCalibration(ref CalibrationStruct calibrationData)
        {
            return Unmanaged_SetupCalibration(ref calibrationData);
        }

        public int iV_SetupMonitorAttachedGeometry(ref MonitorAttachedGeometryStruct monitorAttachedGeometry)
        {
            return Unmanaged_SetupMonitorAttachedGeometry(ref monitorAttachedGeometry);
        }

        public int iV_ShowAccuracyMonitor()
        {
            return Unmanaged_ShowAccuracyMonitor();
        }

        public int iV_ShowTrackingMonitor()
        {
            return Unmanaged_ShowTrackingMonitor();
        }

        public int iV_Start()
        {
            return Unmanaged_Start();
        }

        public int iV_Validate()
        {
            return Unmanaged_Validate();
        }
    }
}