using System;
using System.Runtime.InteropServices;

namespace ScanDemo
{
    public enum ConfigSettings : int
    {
        CV_CAL_STOPSCAN = 0,
        CV_CAL_CALIBRATE = 1,       // Done once for each scanner. Survives re-boots but must be re-done if hardware changes 
                                    // Calibration file saved by default to %ProgramData%\Scanprint\Scanner\
        CV_CAL_SET_BW = 2,          // Black and White threshold ( 0 to 255 ) for B/W scanning modes
        CV_CAL_GET_BW = 3,          // superceeded by gamma setting for all modes
        CV_CAL_SET_RESO = 4,        // Despite the name this is actually used to set scan color depth 
        CV_CAL_STARTSCAN = 6,       // scans started as soon as clean paper edge detected 
        CV_CAL_GET_LIGHT = 7,       
        CV_CAL_SET_LIGHT = 8,       // Light level set by calibration but can be tweaked  (0 to 99 max) 
        CV_CAL_SET_DEV = 10,        // The scan resolution DPI is set via this 
        CV_CAL_FORCESCAN = 11,      // Force scan as soon as any paper is detected 
        CV_CAL_PAPER = 24,          // get the current scanner paper status 
        CV_CAL_SET_GAMMA = 29,      // superceeds SET_BW. Use this to set scan sensitivity  
        CV_CAL_GET_GAMMA = 30,
        CV_CAL_STATUS_ACTIVITY = 37,// activity status of scanner
        CV_CAL_RECALIBRATE = 47     // Safe Calibration - always overwrites existing calibration file 
    }

    // Scanner Status mask flags used by CV_CAL_STATUS_ACTIVITY
    public enum ScannerStatus : int
    {
        SS_LODAED = 0x01,		    // scanner driver found and loaded
        SS_THREAD = 0x02,		    // scanner thread started and hasn't terminated
        SS_BUSY	= 	0x04,		    // scanner is busy (scanner thread not idle sleeping)
        SS_STOPPED	= 	0x08,		// scanner polling is disabled (note: it is still possible to get BUSY 
                                    // but the hardware is not used)
        SS_SCANNING	= 	0x10,		// scanner is currently in the process of scanning 
        SS_CALLBACK	=	0x20,		// scanner thread is in user scan callback
        SS_OSCILLO	=	0x40,		// scanner is in oscilloscope display mode (in this mode the POLL counter 
                                    // incerments much faster)
        SS_PAPER	= 0x00ff00,		// paper detectors at last poll
        SS_POLL		= 0xff0000,		// mask of 8 bit scanner thread activity counter - incremented each poll 
                                    // (nominally every 150ms). During a scan this counter will not incremant at this rate)
    }


    public enum Resolutions : int
    {
        EACRmFULL256 = 0, 	// full cis resolution 256 levels (8bpp)
        EACRmHALF256 = 1, 	// half cis resolution 256 levels (8bpp)
        EACRmFULL2 = 2      // Full res in black and white.
    }

    public enum DeviceCode
    {
        EDEV200A4_1728 = 1,     // 200 DPI
        EDEV300A4_2592 = 3      // 300 DPI
    }


    public enum cvErrors : int
    {
        CV_SCANNER_NOT_CONNECTED = 0,
        CV_SCANNER_ERROR_CALIB = 1,
        CV_PRINTER_ERROR = 2,
        CV_PRINTER_OFFLINE = 3,
        CV_PRINTER_PAPER_ERROR = 4,
        CV_BARCODE = 5,	
        CV_DEBUG= 6,
        CV_PRINTER_COVER_ERROR = 7,
        CV_PRINTER_HEAD_UNLOAD = 8,
        CV_PIPE_BROKEN = 9,
        CV_PRINTER_NEARLY_OUT = 10,
        CV_BARCODE_CHECKSUM_BAD = 11,
        CV_OCR = 12,
        CV_SCAN_ABORTED = 13
    }

    public enum cvErrorType : int
    {
          CV_FATAL_ERROR = 0,
          CV_ERROR = 1,
          CV_WARNING = 2,
          CV_NO_ERROR = 3
    }


    public struct CyberImg
    {
        public IntPtr pIm;
        public IntPtr pCoef;
        public IntPtr pGamma;
        public IntPtr pTDens;
        public IntPtr pTSwap;
        //public IntPtr WinBITMAP;
        //public IntPtr WinHDC;
        public int lTime;
        public short wWidBy;
        public short wWid;
        public short wHei;
        public short wNoClr;
        public byte bPlanes;
        public byte bType;
        public byte bRet;
    }

    class CyberCs
    {

        
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate void ScanDataCallback(ref CyberImg data);

        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate bool ScanPartDataCallback(ref CyberImg data);

        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate void ErrorReportCallback(int error, UIntPtr type);
        

        [DllImport("CyberSc.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int ScInit(ScanDataCallback fpFinScanning, 
            ErrorReportCallback fpError);

        [DllImport("CyberSC.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int ScSetupPartScan([In, Out]int[] steps, 
            int numSteps, ScanPartDataCallback fpPartScan);

        [DllImport("CyberSc.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int ScSCalibrate(ConfigSettings step, int param);

        [DllImport("CyberSc.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void ScRejectPaper();

    }
}
