using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Runtime.InteropServices;
using GrayScaleClass;

namespace icLDecNetPro
{

    public enum TYPE_CODE{
    TC_ANY               = -1,
    TC_TCODE128          = 1,
    TC_TCODE39           = 2,
    TC_TCODABAR          = 3,
    TC_TINTERLEAVED      = 4,
    TC_TEAN13            = 5,
    TC_TEAN8             = 6,
    TC_TUPCE             = 7,
    TC_TPOSTNET          = 8,
    TC_TIMB              = 9,
    TC_TPHARMACODE       = 10,

    TC_TRSS              = 11,
    TC_TRSS_L            = 12,
    TC_TRSS_E            = 13,

    TC_TEAN13EX          = 14,
    TC_TUPCEEX           = 15,
    
    TC_TCODE93           = 16,

    TC_TADF              = 17,
    TC_TNZP              = 18,
    TC_TUPCA             = 19,    // ONLY for returning the type of decoded symbologes. Decoded as EAN13.

      TCM_TCODE128 = 0x00200,
    TCM_TCODE39          = 0x00400,
    TCM_TCODABAR         = 0x00800,
    TCM_TINTERLEAVED     = 0x01000,
    TCM_TEAN13           = 0x02000,
    TCM_TEAN8            = 0x04000,
    TCM_TUPCE            = 0x08000,
    TCM_TEAN13EX         = 0x400000, // 0x100<<14
    TCM_TUPCEEX          = 0x800000,

    TCM_TRSS             = 0x80000,
    TCM_TRSS_L           = 0x100000,
    TCM_TRSS_E           = 0x200000,

    TCM_TRSS_ALL         = 0x380000
};

public enum L_REJECTION_REASON{
    L_SUCCESSFUL         = 0,
    L_NO_LINEAR_FOUND    = 1,
    L_POOR_IMAGE_QUALITY = 2,
    L_RR_UNKNOWN         = 3,
//
    L_RS_ERROR           = 5,
    L_CHECKSUM_FAILED    = 6,
    L_NOT_CONFIRMED      = 7,
    L_NOT_QUIET_ZONE     = 8
//UseRSS
    ,L_2D_FAILED         = 9 //!< obligatory 2D-symbol is not found
    ,L_NOT_SUPPORTED     = 10 // symbology is not supported by this release

};

enum L_BREAK_REASON{
    L_ALL_INSPECTED      = 0, //!< Normal termination (whole image was inspected)
    L_TIMEOUT            = 1, //!< Termination by time-out
    L_TERMINATED         = 2  //!< Termination by user break (not implemented)
};

enum L_SCAN_DIR{
    L_SCAN_VERTICAL      = 0,
    L_SCAN_HORIZONTAL    = 1,
    L_SCAN_ALL           = 2
};

/*! Directions of Pharmacode*/
enum L_PHARMACODEDIR{
    L_LR   = 0, //!< Barcode goes approximately from image left to image right
    L_TB   = 1, //!< From image top to bottom
    L_RL   = 2, //!< From image right to left
    L_BT   = 3, //!< From image bottom to top
    L_LRL  = 4, //!< left -> right -> left (result as "XXXX YYYY")
    L_TBT  = 5  //!< top -> bottom -> top
};

public enum L_Color{
	L_BLACK = 1,
	L_WHITE   = 2, //!< Is valide for NZP 
	L_DEFAULT = 3  //!< Any, if type code = -1..7,14,15. Black for all other code types
};

public enum L_Mode
{
   L_M_STANDARD = 0,
   L_M_SMALL_QZ = 1,
   L_M_STANDARD_AND_SMALL_QZ = 2
}

//--------------------------------------------------------------------------
/// The structure accumulates decoder options.
   public struct TL_OptMode
{
  public Int32 maxLcount;    //!<\brief From 1 to 100. Equals to 1 by Default.
                    //!<
                    //!< Maximum number of barcodes.
                    //!< Should be equal to 1 if code type is PostNet or USPS IMB
  public Int32 typecode;     /*!<\brief Equals to -1 by Default.
                         Value TC_ANY (=-1) means search within all linear barcode types
                         except of Pharma, PostNet and USPS IMB
                    */
  public Int32 timeout;     //!< TimeOut in mls. Timeout = 0 - the infinite timeout.
  public Int32 paramq;      //!< 1 - on, 0 - off
  public Int32 checksum_I25; //!< 1 - on, 0 - off
  public Int32 checksum_C39; //!< 1 - on, 0 - off
  public Int32 quietzone;    //!< 1<=quietzone<=15
  public Int32 smartmode;    //!< \brief Not assigned  (=0) by Default
/*!<
 Is equal to number of couples bar+space at both sides of a barcode
 that we can treat as noise.
 Negative value means the unlimited quantity of "excessive" bars and spaces.
 Option is valid for all code types except Pharma, PostNet and USPS IMB
*/
  public Int32 EC_Factor;  //!< [0..4] - Maximum errors in USPS IMB (1..2 are preferable)
  public Int32 pharmacodedir;
  public Int32 scandir;    //!< Option is valid for all code types except of Postal codes
  public Int32 scanstep;   //!< \brief By Default is equal to 8
                  //!<
                  //!< The value should conform to 1<= scanstep<=20.
                  //!< Option is valid for all code types except of Postal codes

  public Int32 checksum_CB; //!< 1 - on, 0 - off
  public Int32 FullASCII_C39;

  public Int32 colbeg;  //!<Left column of ROI. -1 for leftmost
  public Int32 colend;  //!<Right column of ROI. -1 for rightmost
  public Int32 rowbeg;  //!< Top row of  ROI. -1 for upper row
  public Int32 rowend;  //!< Bottom row of ROI. -1 for lower row

  public Int32 TADF_num;
  public Int32 color;
  public Int32 mode;
};

   //        ADDITIONAL OPTIONS. 
   // Can be set using the function Set_L_Addition_Option.
   //
   enum L_AdditionalOptions
   {
      // When decoding, replace the code UPCE with UPCA by adding zeros. Default ON
      L_OPT_EXT_UPCE_TO_UPCA = 1000
   };

   //--------------------------------------------------------------------------
   /// Linear Image properties.
   struct TL_ImageInfo
{
  int LCount;          //!< Number of well decoded Linear symbols within image
  int RejectionReason;	//!< not 0 if no one symbol was well decoded
  int BreakReason;	    //!< 0 - normal termination (whole image inspected),
                       //!< 1 - termination by time-out
};

//--------------------------------------------------------------------------
/// Linear codes ISO 15416 Standard Quality Parameters.
struct LINEAR_QUALITY
{
     public Single decode;
     public Single symbol_contrast;
     public Single min_reflectance;
     public Single max_reflectance;
     public Single global_threshold;
     public Single min_edge_contrast;
     public Single modulation;
     public Single defects;
     public Single decodability;
     public Single decode_grade;
     public Single symbol_contrast_grade;
     public Single min_reflectance_grade;
     public Single global_threshold_grade;
     public Single min_edge_contrast_grade;
     public Single modulation_grade;
     public Single defects_grade;
     public Single decodability_grade;
     public Single overall_grade;

     public Single decode_grade_av;
     public Single symbol_contrast_grade_av;
     public Single min_reflectance_grade_av;
     public Single global_threshold_grade_av;
     public Single min_edge_contrast_grade_av;
     public Single modulation_grade_av;
     public Single defects_grade_av;
     public Single decodability_grade_av;
     public Single overall_grade_av;

};

    public class TRowCols
    {
        protected float[ ] FRowCols = new float[ 8 ];
        protected bool FValid;
        public float this[ int ix ]
        {
            get
            {
                if ( ix < 0 ) return -1;
                if ( ix > 7 ) return -1;
                if ( !FValid ) return -1;
                return FRowCols[ ix ];
            }
        }
        public bool Valid { get { return FValid; } }
    }

    public class TL_Quality
    {
        public Single decode;
        public Single symbol_contrast;
        public Single min_reflectance;
        public Single max_reflectance;
        public Single global_threshold;
        public Single min_edge_contrast;
        public Single modulation;
        public Single defects;
        public Single decodability;
        public Single decode_grade;
        public Single symbol_contrast_grade;
        public Single min_reflectance_grade;
        public Single global_threshold_grade;
        public Single min_edge_contrast_grade;
        public Single modulation_grade;
        public Single defects_grade;
        public Single decodability_grade;
        public Single overall_grade;

        public Single decode_grade_av;
        public Single symbol_contrast_grade_av;
        public Single min_reflectance_grade_av;
        public Single global_threshold_grade_av;
        public Single min_edge_contrast_grade_av;
        public Single modulation_grade_av;
        public Single defects_grade_av;
        public Single decodability_grade_av;
        public Single overall_grade_av;
    }

    public class TL_Info
    {
        public TL_Info (IntPtr DLLInfo)
        {
            SetInfo( DLLInfo );
        }
        unsafe private void SetInfo (IntPtr DLLInfo)
        {
            FInfo = (T_US_L_Info*)DLLInfo;
            FRowCols.SetInfo( FInfo );
            FQuality.SetInfo( FInfo );
        }

        unsafe public struct  LINEAR_SCAN_LINE
        {
            public Int16 scan_line_start_x;  //!< column of scan line begin
            public Int16 scan_line_start_y;  //!< row of scan line begin
            public Int16 scan_line_end_x;    //!< column of scan line end
            public Int16 scan_line_end_y;    //!< row of scan line end
            public Byte first;                    //!< flag of main scan line
            Byte quietzone;                //!< QZ OK
            Byte checksum;                 //!< checksum OK
            Byte length;           //!< number of decoded characters
            Byte* dataRes;                  //!< result of decoding the scan line
        };

//--------------------------------------------------------------------------
/// Descriptor of 10 scan lines in each L_Info
//        unsafe public LINEAR_SCAN_LINE*  SCAN_LINE_ALL;

//        #region PrivateFields
        unsafe public T_US_L_Info* FInfo;
        public unsafe struct T_US_L_Info
        { //result of decoding per each 1D symbol
            public Int16   RejectionReason;
//            public Int16[] rowcols;    //!< Coordinates of barcode rectangle
            public Int16 rowcols0;    // symbol corners
            public Int16 rowcols1;    // symbol corners
            public Int16 rowcols2;    // symbol corners
            public Int16 rowcols3;    // symbol corners
            public Int16 rowcols4;    // symbol corners
            public Int16 rowcols5;    // symbol corners
            public Int16 rowcols6;    // symbol corners
            public Int16 rowcols7;    // symbol corners
            public Int16   type;          //!< Actual type of a barcode
            public Byte    idx_scan_line; //!< Index of "main" scan line (0<=idx_scan_line<10)
            public Byte    pchlen;        //!< Length of decoded byte array
            public Byte*   pch;           //!<Pointer to that array

//            SCAN_LINE_ALL  sl;   //!< Descriptors of 10 scan lines
            public LINEAR_SCAN_LINE sl1;
            public LINEAR_SCAN_LINE sl2;
            public LINEAR_SCAN_LINE sl3;
            public LINEAR_SCAN_LINE sl4;
            public LINEAR_SCAN_LINE sl5;
            public LINEAR_SCAN_LINE sl6;
            public LINEAR_SCAN_LINE sl7;
            public LINEAR_SCAN_LINE sl8;
            public LINEAR_SCAN_LINE sl9;
            public LINEAR_SCAN_LINE sl10;
//            public LINEAR_QUALITY lq;   //!< ISO 15416 Quality Parameters
            public Single decode;
            public Single symbol_contrast;
            public Single min_reflectance;
            public Single max_reflectance;
            public Single global_threshold;
            public Single min_edge_contrast;
            public Single modulation;
            public Single defects;
            public Single decodability;
            public Single decode_grade;
            public Single symbol_contrast_grade;
            public Single min_reflectance_grade;
            public Single global_threshold_grade;
            public Single min_edge_contrast_grade;
            public Single modulation_grade;
            public Single defects_grade;
            public Single decodability_grade;
            public Single overall_grade;

            public Single decode_grade_av;
            public Single symbol_contrast_grade_av;
            public Single min_reflectance_grade_av;
            public Single global_threshold_grade_av;
            public Single min_edge_contrast_grade_av;
            public Single modulation_grade_av;
            public Single defects_grade_av;
            public Single decodability_grade_av;
            public Single overall_grade_av;
            //  TIMB_L_QUALITY* add_lq; //!< In accordance with code type: PL_IMBQuality...

            public Int32 RSErr;		   // number of reed solomon errors
            public Single unused_error_correction;
            public Single unused_error_correction_grade;
        }

        class T_US_RowCols : TRowCols
        {
            unsafe public void SetInfo (T_US_L_Info* FInfo)
            {
                FValid = false;
                if ( FInfo == (T_US_L_Info*)null ) return;
                //if ( FInfo->rcFlag == 0 ) return;

                FRowCols[ 0 ] = FInfo->rowcols0;
                FRowCols[ 1 ] = FInfo->rowcols1;
                FRowCols[ 2 ] = FInfo->rowcols2;
                FRowCols[ 3 ] = FInfo->rowcols3;
                FRowCols[ 4 ] = FInfo->rowcols4;
                FRowCols[ 5 ] = FInfo->rowcols5;
                FRowCols[ 6 ] = FInfo->rowcols6;
                FRowCols[ 7 ] = FInfo->rowcols7;
                FValid = true;
            }
        }
        class T_US_Quality : TL_Quality
        {
            unsafe public void SetInfo (T_US_L_Info* FInfo)
            {
                if ( FInfo == (T_US_L_Info*)null ) 
                {
                    decode = -1;
                    symbol_contrast = -1;
                    global_threshold = -1;
                    min_reflectance = -1;
                    max_reflectance = -1;
                    min_edge_contrast = -1;
                    defects = -1;
                    decodability = -1;

                    symbol_contrast_grade = -1;
                    global_threshold_grade = -1;
                    min_reflectance_grade = -1;
                    min_edge_contrast_grade = -1;
                    defects_grade = -1;
                    decodability_grade = -1;
                    modulation_grade = -1;
                    decode_grade = -1;
                    overall_grade = -1;
                }
                else
                {
                    decode = FInfo->decode;
                    symbol_contrast = FInfo->symbol_contrast;
                    global_threshold_grade = FInfo->global_threshold_grade;
                    min_reflectance = FInfo->min_reflectance;
                    max_reflectance = FInfo->max_reflectance;
                    min_edge_contrast = FInfo->min_edge_contrast;
                    defects = FInfo->defects;
                    decodability = FInfo->decodability;

                    decode_grade = FInfo->decode_grade;
                    symbol_contrast_grade = FInfo->symbol_contrast_grade;
                    global_threshold_grade = FInfo->global_threshold_grade;
                    min_reflectance_grade = FInfo->min_reflectance_grade;
                    min_edge_contrast_grade = FInfo->min_edge_contrast_grade;
                    defects_grade = FInfo->defects_grade;
                    decodability_grade = FInfo->decodability_grade;
                    modulation_grade = FInfo->modulation_grade;
                    overall_grade = FInfo->overall_grade;
                }
            }
        }

        private T_US_Quality FQuality = new T_US_Quality( );
        private T_US_RowCols FRowCols = new T_US_RowCols( );
        unsafe private bool IsInfo ( )
        {
            return ( FInfo != null );
        }

//        #endregion

        public int RSErr
        {
            get
            {
                if ( !IsInfo( ) )
                    return -1;

                unsafe { return FInfo->RSErr; };
            }
        }

        private byte[ ] GetDecodedBytes (StringConvertor SC)
        {
            byte[ ] Result;
            unsafe
            {
                if ( IsInfo( ) )
                {
                    Result = SC.PCharToArray( FInfo->pch, FInfo->pchlen );
                }
                else
                {
                    return new byte[ 0 ];
                }
            }
            return Result;
        }

        public byte[ ] GetDecodedBytes ( )
        {
            StringConvertor SC = new StringConvertor( );
            return GetDecodedBytes( SC );
        }
        public String GetDecodedChars (int codepage)
        {
            StringConvertor SC = new StringConvertor( codepage );
            byte[ ] A = GetDecodedBytes( SC );
            return SC.ByteArrayToString( A );
        }
        public String GetDecodedChars ( )
        {
            StringConvertor SC = new StringConvertor( );
            byte[ ] A = GetDecodedBytes( );
            return SC.ByteArrayToString( A );
        }

        unsafe public String GetSymbologyID()
        {
            StringConvertor SC = new StringConvertor();
            byte[] SIDch = new byte[4];
            SIDch[0] = (byte)(FInfo->pch)[-3];
            SIDch[1] = (byte)(FInfo->pch)[-2];
            SIDch[2] = (byte)(FInfo->pch)[-1];
            SIDch[3] = (byte)0;
            return SC.ByteArrayToString(SIDch);
        }

        unsafe public String GetTypecode(int typecode)
        {
            String[] type = {
            "CODE128",      // 1,
            "CODE39",       // 2,
            "CODABAR",      // 3,
            "INTERLEAVED",  // 4,
            "EAN13",        // 5,
            "EAN8",         // 6,
            "UPCE",         // 7,
            "POSTNET",      // 8,
            "IMB",          // 9,
            "PHARMACODE",   // 10,

            "RSS",          // 11,
            "RSS_L",        // 12,
            "RSS_E",        // 13,

            "EAN13EX",      // 14,
            "UPCEEX",       // 15,

            "CODE93",       // 16

            "TADF",         // 17,
            "NZP",          // 18,
            "UPCA",         // 19,
            };
            if (typecode < 0 || typecode > 19)
                return "?";
            else
                return type[typecode-1];
        }

        public TRowCols RowCols
        {
            get
            {
                return FRowCols;
            }
        }

        public TL_Quality Quality
        {
            get { return FQuality; }
        }

    }
    // TL_Info

    public class icLC_Decoder_Pro
    {
//        #region Private_Fields

//        [DllImport("LC_PRO_32.dll", EntryPoint = "Connect_L_Decoder", CallingConvention = CallingConvention.StdCall)]
//        internal static extern IntPtr Connect_L_Decoder ([In] Int32 MaxRowCount, [In] Int32 MaxColCount);

        [DllImport( "LC_PRO.dll", EntryPoint = "Disconnect_L_Decoder", CallingConvention = CallingConvention.StdCall )]
        internal static extern void Disonnect_L_Decoder ([In] IntPtr Decoder);

        [DllImport("LC_PRO.dll", EntryPoint = "Create_L_Options", CallingConvention = CallingConvention.StdCall)]
        internal static extern IntPtr Create_L_Options(
              [In] IntPtr Decoder,
              [In] TL_OptMode opt);

        [DllImport( "LC_PRO.dll", EntryPoint = "Delete_L_Options", CallingConvention = CallingConvention.StdCall )]
        internal static extern void Delete_L_Options ([In] IntPtr Options);

        [DllImport( "LC_PRO.dll", EntryPoint = "GetL_ImageInfo", CallingConvention = CallingConvention.StdCall )]
        internal static extern IntPtr GetL_ImageInfo ([In] IntPtr DecoderO);

        [DllImport( "LC_PRO.dll", EntryPoint = "GetL_Info", CallingConvention = CallingConvention.StdCall )]
        internal static extern IntPtr GetL_Info ([In] IntPtr DecoderO, [In] Int32 SymbolNumber);

        [DllImport( "LC_PRO.dll", EntryPoint = "Decode_L_Bits", CallingConvention = CallingConvention.StdCall )]
        internal static extern int Decode_L_Bits ([In] IntPtr DecoderO, [In] Int32 RowCount, [In] Int32 ColCount, [In] IntPtr[ ] PPBits);

        [DllImport("LC_PRO.dll", EntryPoint = "Set_L_Addition_Option", CallingConvention = CallingConvention.StdCall)]
        internal static extern int Set_L_Addition_Option([In] IntPtr DecoderO, [In] Int32 optCode, [In] Int32 optValue);

        private IntPtr FDecoderW = IntPtr.Zero;
        private IntPtr DecoderO = IntPtr.Zero;
        private bool FOptionChanged = true;
        private Int32 FLCount = 0;        // number of well decoded symbols within image
        public L_REJECTION_REASON FRejectionReason = L_REJECTION_REASON.L_RR_UNKNOWN;// if no one matrix has been decoded
        private int FcornQ = 0;

      private int ExtendUPCE_to_UPCA = 1;
      
      /*
              public void Disconnect ( )
              {
                  unsafe
                  {
                      fixed ( void* PD = &_decoderPtr )
                      {
                          IntPtr P = new IntPtr( PD );
                          Disonnect_L_Decoder( P );
                      }
                  }
              }
      */
      public unsafe struct T_US_L_OptMode
        {
            public Int32 maxLCount;   // from 1 to 100
            public Int32 codeType;
            public Int32 paramq;
            public Int32 Color;
            public Int32 ScanStep;
            public Int32 mode;
        }

        private unsafe struct T_US_L_ImageInfo
        { // averall image properties
            public Int32 LCount;        // number of well decoded symbols within image
            public Int32 RejectionReason;// if no one matrix has been decoded
            public byte  cornQ;// number of detected corners in symbol ( = 4 if a rectangle was detected)
        }

        public T_US_L_OptMode FOptMode;

        private int DecodeBitsO (Int32 RowCount, Int32 ColCount, IntPtr[ ] PPBits)
        {
            int Result = 0;
            TL_OptMode newopt;

            if ( ( DecoderO == IntPtr.Zero ) || ( FOptionChanged ) )
            {
                if ( DecoderO != IntPtr.Zero )
                {
                    unsafe
                    {
                        fixed ( void* PO = &DecoderO )
                        {
                            IntPtr P = new IntPtr( PO );
                            Delete_L_Options( P );
                            DecoderO = IntPtr.Zero;
                        }
                    }
                }

                unsafe
                {
                    IntPtr PD = FDecoderW;

                    newopt = new TL_OptMode();
                    newopt.maxLcount = FOptMode.maxLCount;
                    newopt.typecode  = FOptMode.codeType;
                    newopt.paramq = FOptMode.paramq;
                    newopt.color = FOptMode.Color;
                    newopt.colbeg = newopt.colend = newopt.rowbeg = newopt.rowend = -1;
                    newopt.scanstep = FOptMode.ScanStep;
                    newopt.scandir = (Int32)(L_SCAN_DIR.L_SCAN_ALL);
                    newopt.mode = FOptMode.mode;
                    DecoderO = Create_L_Options(PD, newopt);
                    FOptionChanged = false;
                }
            }

         Set_L_Addition_Option(DecoderO, (int)L_AdditionalOptions.L_OPT_EXT_UPCE_TO_UPCA, ExtendUPCE_to_UPCA);

         Result = Decode_L_Bits( DecoderO, RowCount, ColCount, PPBits );
            return Result;
        }

        unsafe private int Get_maxLCount ( )
        {
            return FOptMode.maxLCount;
        }
        unsafe private void Set_maxLCount (int Value)
        {
            if ( FOptMode.maxLCount == Value ) return;
            if (Value < 1) Value = 1;
            else if (Value > 100) Value = 100;
            FOptMode.maxLCount = Value; 
            FOptionChanged = true;
        }

        public void SetMode(L_Mode mode)
        {
            if (FOptMode.mode == (int)mode) return;
            FOptMode.mode = (int)mode;
            FOptionChanged = true;
        }

        unsafe private int Get_codeType()
        {
            return FOptMode.codeType;
        }
        unsafe private void Set_codeType(int Value)
        {
            if (FOptMode.codeType == Value) return;
            if (Value < 0 || (Value > 19 && Value != (int)TYPE_CODE.TCM_TRSS_ALL))
                Value = -1; // all 
            FOptMode.codeType = Value;
            FOptionChanged = true;
        }

        unsafe private int Get_paramq()
        {
            return FOptMode.paramq;
        }
        unsafe private void Set_paramq(int Value)
        {
            if (FOptMode.paramq == Value) return;
            if (Value < 0 || Value > 1)
                Value = 1; // YES
            FOptMode.paramq = Value; 
            FOptionChanged = true;
        }

        unsafe private int Get_L_Color()
        {
            return FOptMode.Color;
        }
        unsafe private void Set_L_Color(int Value)
        {
            if (FOptMode.Color == Value) return;
            if (Value < 1 || Value > 3)
                Value = 3; // L_DEFAULT
            FOptMode.Color = Value; 
            FOptionChanged = true;
        }

      private bool SetAddOption(L_AdditionalOptions code, int value)
      {
         unsafe
         {
            int res = Set_L_Addition_Option(DecoderO, (int)code, value);
            return res == 0;
         }
      }

      //        #endregion
      public void SetExtendUPCE_to_UPCA(bool on)
      {
         ExtendUPCE_to_UPCA = 0;
         if (on)
            ExtendUPCE_to_UPCA = 1;
      }

      public int MaxLCount
        {
            get { return Get_maxLCount( ); }
            set { Set_maxLCount( value ); }
        }

        public int codeType
        {
            get { return Get_codeType(); }
            set { Set_codeType(value); }
        }

        public int paramq
        {
            get { return Get_paramq(); }
            set { Set_paramq(value); }
        }

        public int L_Color
        {
            get { return Get_L_Color( ); }
            set { Set_L_Color( value ); }
        }

        public int ScanStep
        {
           get { return FOptMode.ScanStep;  }
           set { FOptMode.ScanStep = value; FOptionChanged = true; }
        }

        public icLC_Decoder_Pro (IntPtr decptr)
        {
            //            FDecoderW = Connect_L_Decoder(5000, 8000 );
            FDecoderW = decptr;
            FOptMode.maxLCount = 10;
            FOptMode.codeType = -1;
            FOptMode.paramq = 1;
            FOptMode.Color = 3; // L_Default
            FOptMode.ScanStep = 8;
            FOptMode.mode = (int)L_Mode.L_M_STANDARD;
        }


        public int DecodeImage (Bitmap BMP)
        {
            int Result;
            GrayScale G = new GrayScale( BMP );
            G.OnDecBits += this.DecodeBitsO;

            Result = G.DecodeBits( );

            IntPtr II = GetL_ImageInfo( DecoderO );
            unsafe
            {
                T_US_L_ImageInfo* UII = (T_US_L_ImageInfo*)II.ToPointer( );
                {
                    FRejectionReason = (L_REJECTION_REASON)UII->RejectionReason;
                    FLCount = UII->LCount;
                    FcornQ = UII->cornQ;
                }
            }
            return Result;
        }

        public L_REJECTION_REASON Rejection_Reason
        {
            get { return FRejectionReason; }
        }
        public int LCount
        {
            get { return FLCount; }
        }

        public TL_Info Get_L_Info (int Index)
        {
            TL_Info Result = null;
            IntPtr II = IntPtr.Zero;
            if ( Index < 0 ) return null;
            if ( Index >= FLCount ) return null;

            II = GetL_Info( DecoderO, Index );
            Result = new TL_Info( II );

            return Result;
        }
    }
    //L DEcoder
}
