using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

using icDecLibAztec_Net;


namespace DemoAztecSharp
{
  public partial class Form1 : Form
  {

    
    icAztecPro Decoder =null;
    Bitmap BMP = null;
    Bitmap BMP_C = new Bitmap( 150, 150 );

    Bitmap BMP_S = new Bitmap( 205, 5 );

    Point[ , ] Conturs = new Point[ 7, 512 ];
    double [ , ] Dists = new Double[ 7, 512 ];
    double [ , ] Derivative = new Double[ 7, 512 ];
    const int DerivativeWindow = 10;
    int GIndex = 3;
    Point[ ] Centers = new Point[ 10 ];

    public Form1 ( )
    {
      InitializeComponent( );

      //Decoder = new icAztecPro( 2000, 2000 );
      Decoder = new icAztecPro( 2000, 2000 );

      //OpenFolderDialog1.SelectedPath = "F:\\Images\\AzTec\\Q1";

      CornersPicture.Image = BMP_C;
      Image_S.Image = BMP_S;
    }
    string [] Dir = new string [0];

    private void OpenFolderButton_Click (object sender, EventArgs e)
    {
      OpenFolderDialog1.Description = "Выберите папку с картинками";
      if ( OpenFolderDialog1.ShowDialog( ) != DialogResult.OK ) return;

      
      OpenFolder( OpenFolderDialog1.SelectedPath );

    }
    private void OpenFolder( string SelectedPath )
    {
      Dir = Directory.GetFiles( SelectedPath, "*.bmp" );
      DirTrackBar.Maximum = Dir.Length - 1;
      DirTrackBar.Minimum = 0;

      DirTrackBar.Visible = Dir.Length > 1;
      DirTrackBar.Value = 0;
      if ( DirTrackBar.Visible )
        DirTrackBar.Focus( );

      DecodeFile( );
    }
    private void DecodeFile ( )
    {
      if ( Dir.Length <= DirTrackBar.Value ) return;
      string FN = Dir[ DirTrackBar.Value ];
      Text = FN;

      BMP = new Bitmap( FN );

      Image1.Image = new Bitmap( BMP.Width, BMP.Height );

      if ( Decoder.DecodeImage( BMP ) > 0 )
        ResultText.Text = Decoder.GetText( );
      else
      {
        int RR = Decoder.RejectionReason;
        if ( RR == -1 ) ResultText.Text = "Error: Aztec Code not found";
        else if ( RR == -7 ) ResultText.Text = "Error:  too many errors in Reed Solomon code in Mode Message";
        else if ( RR == -8 ) ResultText.Text = "Error: too many errors in Reed Solomon code in Data Message";
        else if ( RR == -9 ) ResultText.Text = "Error: unexpected encodation scheme";
        else if ( RR == -13 ) ResultText.Text = "Error: unallowed module size";
        else ResultText.Text = Decoder.RejectionReason.ToString( );
      }
      ShowFile( );
    }


    private void DrawCorn (Graphics G, int iR, int iC)
    {
      const int Siz = 5;
      int FR = ( iR + 14 )*Siz ;
      int FC = ( iC + 14 )*Siz;
      /*int C;
      C = Decoder.GetDebugProperty( 50, iR, iC ); //DebugProperty_50
      if ( C > 128 )
        G.FillRectangle( Brushes.Blue, FC * Siz, FR * Siz, Siz, Siz );
      else
        G.FillRectangle( Brushes.Yellow, FC * Siz, FR * Siz, Siz, Siz );*/
      ShowPixel( iR, iC, G, FR, FC, Siz );
    }
    private void ShowCorners ( )
    {
      int MaxLevel = 11;
      Graphics G = Graphics.FromImage( CornersPicture.Image );
      G.FillRectangle( Brushes.White, 0, 0, 10 * 15, 10 * 15 );


      for ( int iR = -MaxLevel; iR <= MaxLevel; iR++ )
        for ( int iC = -MaxLevel; iC <= MaxLevel; iC++ )
          DrawCorn( G, iC, iR );
      /*
      DrawCorn( G, -7, -6 );
      DrawCorn( G, -6, -7 );
      DrawCorn( G, -7, -7 );

      DrawCorn( G, +7, +6 );
      DrawCorn( G, +6, +7 );
      DrawCorn( G, +7, +7 );

      DrawCorn( G, +6, -7 );
      DrawCorn( G, +7, -7 );
      DrawCorn( G, +7, -6 );

      DrawCorn( G, -6, +7 );
      DrawCorn( G, -7, +7 );
      DrawCorn( G, -7, +6 );
      */
    }
    private void ShowPoints (Graphics G, Brush Br, int Q)
    {
      int AZCountL = Decoder.GetDebugProperty( 20, Q, 0 );
      int CL, RL, ZL;
      int AZCountR = Decoder.GetDebugProperty( 25, Q, 0 );
      int CR, RR, ZR;
      for ( int P = 0; P < AZCountL; P++ )
      {
        CL = Decoder.GetDebugProperty( 21, Q, P );
        RL = Decoder.GetDebugProperty( 22, Q, P );
        ZL = Decoder.GetDebugProperty( 23, Q, P );
        G.FillRectangle( Br, CL, RL, 1, 1 );

        textBox1.AppendText( "ZL[" + Q.ToString( ) + "," + P.ToString( ) + "]=" +
          "("+CL.ToString()+","+RL.ToString()+") "+ZL.ToString( ) + "\r\n" );
      }
      for ( int P = 0; P < AZCountR; P++ )
      {
        CR = Decoder.GetDebugProperty( 26, Q, P );
        RR = Decoder.GetDebugProperty( 27, Q, P );
        ZR = Decoder.GetDebugProperty( 28, Q, P );
        G.FillRectangle( Br, CR, RR, 1, 1 );
        textBox1.AppendText( "ZR[" + Q.ToString( ) + "," + P.ToString( ) + "]=" +
          "(" + CR.ToString( ) + "," + RR.ToString( ) + ") " + ZR.ToString( ) + "\r\n" );
      }
    }

    private void ShowPixel (int iR, int iC, Graphics G, int FR, int FC, int Siz)
    {
      int C = Decoder.GetDebugProperty( 50, iR, iC ); //DebugProperty_50
      if ( C > 128 )
      {
        //G.FillRectangle( Brushes.White, FC, FR, Siz, Siz );
        G.FillRectangle( Brushes.Blue, FC+1, FR+1, Siz-1, Siz-1 );
      }
      else
      {
        //G.FillRectangle( Brushes.Black, FC, FR, Siz, Siz );
        G.FillRectangle( Brushes.Yellow, FC+1, FR+1, Siz-1, Siz-1 );
      }
    }
    private void DrawLine_44_45 (Graphics G, int i, int j, int i1, int j1)
    {
      Point P1 = new Point( 0, 0 ), P2 = new Point( 0, 0 );
      P1.Y = Decoder.GetDebugProperty( 44, i, j );
      P1.X = Decoder.GetDebugProperty( 43, i, j );
      P2.Y = Decoder.GetDebugProperty( 44, i1, j1 );
      P2.X = Decoder.GetDebugProperty( 43, i1, j1 );

      if ( P1.X <= 0 ) return;
      if ( P1.Y <= 0 ) return;
      if ( P2.X <= 0 ) return;
      if ( P2.Y <= 0 ) return;
      

      G.DrawLine( Pens.Red, P1, P2 );
    }
    private void Show_S ( )
    {
      Graphics G = Graphics.FromImage( Image_S.Image );

      G.FillRectangle( Brushes.White, 0, 0, Image_S.Image.Width, Image_S.Image.Height );

      ShowPixel( -7, -5, G, 0, 0, 5 );//0
      ShowPixel( -7, -4, G, 0, 5, 5 );//1
      ShowPixel( -7, -3, G, 0, 10, 5 );//2
      ShowPixel( -7, -2, G, 0, 15, 5 );//3
      ShowPixel( -7, -1, G, 0, 20, 5 );//4

      ShowPixel( -7, 1, G, 0, 25, 5 );//5
      ShowPixel( -7, 2, G, 0, 30, 5 );//6
      ShowPixel( -7, 3, G, 0, 35, 5 );//7
      ShowPixel( -7, 4, G, 0, 40, 5 );//8
      ShowPixel( -7, 5, G, 0, 45, 5 );//9
      


      ShowPixel( -5, +7, G, 0, 50, 5 );//10
      ShowPixel( -4, +7, G, 0, 55, 5 );//11
      ShowPixel( -3, +7, G, 0, 60, 5 );//12
      ShowPixel( -2, +7, G, 0, 65, 5 );//13
      ShowPixel( -1, +7, G, 0, 70, 5 );//14

      ShowPixel( +1, +7, G, 0, 75, 5 );//15
      ShowPixel( +2, +7, G, 0, 80, 5 );//16
      ShowPixel( +3, +7, G, 0, 85, 5 );//17
      ShowPixel( +4, +7, G, 0, 90, 5 );//18
      ShowPixel( +5, +7, G, 0, 95, 5 );//19


      ShowPixel( +7, +5, G, 0, 100, 5 );//20
      ShowPixel( +7, +4, G, 0, 105, 5 );//21
      ShowPixel( +7, +3, G, 0, 110, 5 );//22
      ShowPixel( +7, +2, G, 0, 115, 5 );//23
      ShowPixel( +7, +1, G, 0, 120, 5 );//24

      ShowPixel( +7, -1, G, 0, 125, 5 );//25
      ShowPixel( +7, -2, G, 0, 130, 5 );//26
      ShowPixel( +7, -3, G, 0, 135, 5 );//27
      ShowPixel( +7, -4, G, 0, 140, 5 );//28
      ShowPixel( +7, -5, G, 0, 145, 5 );//29
      
      ShowPixel( +5, -7, G, 0, 150, 5 );//30
      ShowPixel( +4, -7, G, 0, 155, 5 );//31
      ShowPixel( +3, -7, G, 0, 160, 5 );//32
      ShowPixel( +2, -7, G, 0, 165, 5 );//33
      ShowPixel( +1, -7, G, 0, 170, 5 );//34

      ShowPixel( -1, -7, G, 0, 175, 5 );//35
      ShowPixel( -2, -7, G, 0, 180, 5 );//36
      ShowPixel( -3, -7, G, 0, 185, 5 );//37
      ShowPixel( -4, -7, G, 0, 190, 5 );//38
      ShowPixel( -5, -7, G, 0, 195, 5 );//39
      

    }
    int NB_LayerQ (int L)
    {
      switch ( L - 1 )
      {
        //case 0: return 9;
        //case 1: return 11;
        //case 2: return 13;
        case 3: return 15;
        case 4: return 18;
        case 5: return 20;
        case 6: return 22;
        case 7: return 24;
        case 8: return 26;
        case 9: return 28;
        case 10: return 30;
        case 11: return 33;
        case 12: return 35;
        case 13: return 37;
        case 14: return 39;
        case 15: return 41;
        case 16: return 43;
        case 17: return 45;
        case 18: return 47;
        case 19: return 50;
        case 20: return 52;
        case 21: return 54;
        case 22: return 56;
        case 23: return 58;
        case 24: return 60;
        case 25: return 62;
        case 26: return 66;
        case 27: return 68;
        case 28: return 70;
        case 29: return 72;
        case 30: return 74;
        case 31: return 76;
      };
      return 15;
    }

    private void ReadResults ( )
    {
      int R, C;

      int CentersCount = Decoder.GetDebugProperty( 2, 0, 0 );
      if ( CentersCount == 0 )
        Centers = null;
      else
        Centers = new Point[ CentersCount ];
      for ( int i = 0; i < CentersCount; i++ )
      {
        C = Decoder.GetDebugProperty( 3, i, 0 );
        R = Decoder.GetDebugProperty( 4, i, 0 );
        Centers[ i ] = new Point( C, R );
      }

      for ( int G = 2; G <= 5; G++ )
      {
        double Sum = 0;
        for ( int i = 0; i < 512; i++ )
        {
          R = Decoder.GetDebugProperty( 32, G, i );
          C = Decoder.GetDebugProperty( 31, G, i );
          Conturs[ G, i ] = new Point( C, R );
          if ( CentersCount == 0 )
            Dists[ G, i ] = 0;
          else
            Dists[ G, i ] = Norma( Centers[ 0 ], Conturs[ G, i ] );

          Sum = Sum + Dists[ G, i ];
        }
        for ( int i = 0; i < 512; i++ )
        {
          Derivative[ G, i ] = 0;
          for ( int j = -DerivativeWindow; j <= DerivativeWindow; j++ )
          {
            if ( j < 0 )
              Derivative[ G, i ] = Derivative[ G, i ] - Dists[ G, ( i + j + 512 ) % 512 ];
            else if ( j > 0 )
              Derivative[ G, i ] = Derivative[ G, i ] + Dists[ G, ( i + j + 512 ) % 512 ];
          }
          if ( Sum > 0 )
            Derivative[ G, i ] = Derivative[ G, i ] * 512 / Sum * 33 / DerivativeWindow;
        }
      }
    }

    bool CornersPictureDown = false;
    int CornersPictureX, CornersPictureY;
    Brush CornersPictureC;
    private void ShowFile ( )
    {

      ReadResults( );

      ShowCorners( );

      Show_S( );

      Image1.Image = new Bitmap( BMP.Width, BMP.Height );

      Graphics Image1_G = Graphics.FromImage( Image1.Image );

      Image1_G.DrawImage( BMP, 0, 0,BMP.Width, BMP.Height );

      
      Pen PenYellow = new Pen( Color.Yellow );
      Pen PenRed = new Pen( Color.Red );
      Pen PenAqua = new Pen( Color.Aqua );

      PenAqua.Width = 1;
      PenYellow.Width = 1;
      LineUpDown.Maximum = 0;
      Label_Line.Text = "";
      
      textBox1.Text = "";
      if ( Centers == null )
      {
        LabelC.Text = "Centers = null";
      }
      else
      {
        LabelC.Text = "Centers["+Centers.Length.ToString()+"] =";
        foreach ( Point P in Centers )
        {
          LabelC.Text = LabelC.Text + P.X.ToString( ) + " , " + P.Y.ToString( );
          Image1_G.FillRectangle( Brushes.Aqua, P.X-1, P.Y-1, 3, 3 );
        }
      }
      //for ( int Q = 3; Q < 6; Q++ )
      ShowPoints( Image1_G, Brushes.Aqua, 5 );
      ShowPoints( Image1_G, Brushes.Red, 4 );
      /*
      int Q = 5;
      {
        */
        /*
        if ((AZCountL==4)&&(AZCountR==4))
          for ( int P = 0; P < 4; P++ )
          {
            CR = Decoder.GetDebugProperty( 26, Q, P );
            RR = Decoder.GetDebugProperty( 27, Q, P );
            CL = Decoder.GetDebugProperty( 21, Q, P );
            RL = Decoder.GetDebugProperty( 22, Q, P );
            G.DrawLine( Pens.Aqua, CR, RR, CL, RL );
          }
         
      }*/
      
      if ( Decoder.RejectionReason < 0 )
      {
        for ( int i = 0; i < 512; i++ )
        {
          Point P;
          P = Conturs[ 5, i ]; Image1_G.FillRectangle( Brushes.Green, P.X, P.Y, 1, 1 );
          P = Conturs[ 4, i ]; Image1_G.FillRectangle( Brushes.Red, P.X, P.Y, 1, 1 );
          P = Conturs[ 3, i ]; Image1_G.FillRectangle( Brushes.Green, P.X, P.Y, 1, 1 );
          P = Conturs[ 2, i ]; Image1_G.FillRectangle( Brushes.Red, P.X, P.Y, 1, 1 );
        }
      } 

      int Q = 19;
      int Layers = Decoder.GetDebugProperty( 60, 0, 0 );

      Q = NB_LayerQ( Layers );

      for ( int j16 = -Q; j16 <= Q; j16++ )
      {
        if ( j16 % 16 == 0 )
          for ( int i = 0; i <= Q; i++ )
          {
            DrawLine_44_45( Image1_G, j16, i, j16, i + 1 );

            DrawLine_44_45( Image1_G, j16, -i, j16, -i - 1 );

            DrawLine_44_45( Image1_G, i, j16, i + 1, j16 );

            DrawLine_44_45( Image1_G, -i, j16, -i - 1, j16 );
          }
      }


      for ( int iC = -Q; iC <= +Q; iC++ )
      {
        for ( int iR = -Q; iR <= +Q; iR++ )
        {
          int fR = Decoder.GetDebugProperty( 44, iR, iC );
          int fC = Decoder.GetDebugProperty( 43, iR, iC );

          int C = Decoder.GetDebugProperty( 50, iR, iC ); //DebugProperty_50

          if ( C < 128 )
          {
            Image1_G.FillRectangle( Brushes.Blue, fC, fR, 1, 1 );
          }
          else
          {
            Image1_G.FillRectangle( Brushes.Yellow, fC, fR, 1, 1 );
          }
        }
      }

      if ( CornersPictureDown )
      {
        Image1_G.FillRectangle( CornersPictureC, CornersPictureX - 1, CornersPictureY - 1, 3, 3 );

      }

#if false
      int LinesCount = Decoder.GetDebugProperty( 7, 0, 0 );
      LineUpDown.Maximum = LinesCount + 1;

      Label_QU.Text = ""; Label_QD.Text = ""; Label_Line.Text = "";

      for ( int L = 0; L < LinesCount; L++ )
      {
        
        if ((LineUpDown.Value >0)&&(L != (LineUpDown.Value+1))) continue;
        int Q = Decoder.GetDebugProperty( 8, L, 0 );

        int C = Decoder.GetDebugProperty( 9, L, 0 );
        int R = Decoder.GetDebugProperty( 10, L, 0 );

        int C1 = Decoder.GetDebugProperty( 11, L, 0 );
        int R1 = Decoder.GetDebugProperty( 12, L, 0 );

        int P = Decoder.GetDebugProperty( 15, L, 0 );

        if ( R < 0 ) continue;
        if ( C < 0 ) continue;
        if ( R1 < 0 ) continue;
        if ( C1 < 0 ) continue;

        if ( ( Q == 3 ) || ( Q == 4 ) || ( Q == 5 ) )
        {
          G.DrawLine( PenAqua, C, R, C1, R1 );
          G.FillRectangle( GreenBrush, C - 1, R - 1, 3, 3 );
          G.FillRectangle( RedBrush, C1 - 1, R1 - 1, 3, 3 );
          Label_QU.Text = Decoder.GetDebugProperty( 14, L, 0 ).ToString( );
          Label_QD.Text = Decoder.GetDebugProperty( 13, L, 0 ).ToString( );
          Label_Line.Text = Q.ToString( ) + "("+P.ToString( ) + ") | (" + C.ToString( ) + "," + R.ToString( ) + ") - (" + C1.ToString( ) + "," + R1.ToString( ) + ")";
        }
      }
#endif
#if false
      for ( int Q = 0; Q < 6; Q++ )
        for ( int Points = 0; Points < 16; Points++ )
        {
          int C = Decoder.GetDebugProperty( 5, Q, Points );
          int R = Decoder.GetDebugProperty( 6, Q, Points );

          if ( R < 0 ) continue;
          if ( C < 0 ) continue;

          if ( Q == 3 )
          {
            G.FillRectangle( GreenBrush, C-1, R-1, 3, 3 );
          }
          else if ( Q == 5 )          
          {
            G.FillRectangle( RedBrush, C-1, R-1, 3, 3 );
          }
        }
#endif
#if false
      int Maxx = Decoder.GetDebugProperty( 1, 0, 0 );
      if ( Maxx == 0 ) return;
      for ( int R = 0; R < BMP.Height; R++ )
        for ( int C = 0; C < BMP.Width; C++ )
        {
          int DebugColor = Decoder.GetDebugProperty( 0, R, C );
          /*if ( DebugColor == Maxx )
            G.FillRectangle( BMaxx, C, R, 1, 1 );
          else if ( DebugColor == Maxx - 1 )
            G.FillRectangle( BMaxx1, C, R, 1, 1 );
          else if ( DebugColor == Maxx - 2 )
            G.FillRectangle( BMaxx2, C, R, 1, 1 );
          else */if ( DebugColor == 254 )
            G.FillRectangle( BMaxx3, C, R, 1, 1 );
          else ;
        }
#endif
      CornersPicture.Refresh( );
      Image_S.Refresh( );

      int L = Decoder.GetDebugProperty( 60, 0, 0 );
      fR_UpDown.Minimum = -9-L*2;
      fR_UpDown.Maximum = 9+L*2;
      fC_UpDown.Minimum = -9-L*2;
      fC_UpDown.Maximum = 9+L*2;
      textBox1.AppendText( "Уровней=" + Decoder.GetDebugProperty( 60, 0, 0 ).ToString( ) + "\r\n" );
      textBox1.AppendText( "Блоков=" + Decoder.GetDebugProperty( 61, 0, 0 ).ToString( ) + "\r\n" );
      textBox1.AppendText( "Битов=" + Decoder.GetDebugProperty( 62, 0, 0 ).ToString( ) + "\r\n" );
      textBox1.AppendText( "Слов=" + Decoder.GetDebugProperty( 63, 0, 0 ).ToString( ) + "\r\n" );

      ShowResults( );
    }

    double Norma (Point P1, Point P2)
    {
      double dX = P1.X - P2.X;
      double dY = P1.Y - P2.Y;
      return Math.Sqrt( dX * dX + dY * dY );

    }
    private void ShowResults ( )
    {
      Image2.Image = new Bitmap( 600, 600 );
      Graphics Image2_G = Graphics.FromImage( Image2.Image );

      Pen PP = new Pen( Color.Aqua ); PP.Width = 3;

      //int i1 = -1, i2 = -1, i3 = -1, i4 = -1;
      //double D1=0,D2=0,D3=0,D4=0;
      
      for ( int i = 0; i < 512; i++ )
      {
        double D;


        Image2_G.FillRectangle( Brushes.Green, i + 50, 200 - (int)( Dists[ GIndex, i ] ), 1, 1 );

        D = Derivative[ GIndex, i ];

        D = D * 15;

        Image2_G.FillRectangle( Brushes.Blue, i + 50, 400, 1, 1 );
        Image2_G.FillRectangle( Brushes.Green, i + 50, 400 - (int)( D ), 1, 1 );

        Image2_G.DrawLine( Pens.Blue, i + 50, 400, i + 50, 400 - (int)( D ) );

      }
      Image2_G.FillRectangle( Brushes.Red, 50, 400, 512, 1 );

      bool Up = false;
      bool Dn = false;


      double UpperV = Derivative[ GIndex, 0 ];
      double LowerV = UpperV;
      double Val;
      int XUpperV=0, XLowerV=0;

      const double H1 = 1;// DerivativeWindow / 33.0;
      const double H2 = H1*2;
      
      for ( int X = 1; X < 512 + 128; X++ )
      {
        Val = Derivative[ GIndex, X % 512 ];
        if ( X == 338 )
          X = 338;
      
        if ( ( Val > H2 ) && ( Val > UpperV ) )
        {
          //                                 /                  |
          //                                /                   |
          //                               *                    |
          //                            --/-- 0.2               |
          //                             /                      |
          //----------------------------+--------------------   |
          //                           /                        |
          //            \   dark      /                         |
          //             \-(LowerV)--/                          |
          //                                                    |
          //                                                    |
          // сюда попадаем если яркость растёт
          UpperV = Val;
          XUpperV = X;
          Up = true;
          Dn = false;
        }
        if ( ( Val < -H2 ) && ( Val < LowerV ) )
        {
          //                                                    |
          //                                                    |
          //    /-(UpperV)-\                                    |
          //   /            \                                   |
          //                 \                                  |
          //------------------+------------------------------   |
          //                   \                                |
          //                    \                               |
          //                  ---\---   -0.2                    |
          //                      \                             |
          //                       *                            |
          //                                                    |
          // сюда попадаем если  яркость падает
          LowerV = Val;  // понизим нижний уровень
          XLowerV = X;
          Up = false;
          Dn = true;
        }

        if ( Up && ( Val < ( UpperV - H1 ) ) )
        {
          //                                                    |
          //                                                    |
          //                               /-(UpperV)-\         |
          //                              /            \        |
          //                             /              *       |
          //                            O                       |
          //                           /                        |
          //            \   dark      /                         |
          //             \-(LowerV)--/                          |
          //                                                    |
          //                                                    |
          Up = false;
          
        }
        if (Dn && (Val > (LowerV + H1)))
        {
          //                                                    |
          //                                                    |
          //    /-(UpperV)-\                                    |
          //   /            \                                   |
          //                 \                                  |
          //                  O                                 |
          //                   \               *                |
          //                    \   dark      /                 |
          //                     \-(LowerV)--/                  |
          //                                                    |
          //                                                    |
          Dn = false;
          if ( ( UpperV > H2 ) && ( LowerV < -H2 ) )
          {
            if ( XUpperV < 512 )
            {
              Image2_G.DrawLine( PP, 50 + XUpperV, 400 - (int)( UpperV * 15 ), 50 + XLowerV, 400 - (int)( LowerV * 15 ) );
              if ( ( XLowerV > 512 ) && ( XUpperV < 512 ) )
                Image2_G.DrawLine( PP, 50 + XUpperV - 512, 400 - (int)( UpperV * 15 ), 50 + XLowerV - 512, 400 - (int)( LowerV * 15 ) );
            }
          }
          LowerV = 0;
          UpperV = 0;
        }
      }//for X
    
    }


    private void DirTrackBar_Scroll (object sender, EventArgs e)
    {
      LineUpDown.Value = 0;
      DecodeFile( );
    }

    

    private void LineUpDown_ValueChanged (object sender, EventArgs e)
    {
      ShowFile( );
    }

   

    private void Image1_DoubleClick (object sender, EventArgs e)
    {
      Image2.Visible = !Image2.Visible;
    }


    private void Image2_MouseDown (object sender, MouseEventArgs e)
    {
      if ( ( e.Button & MouseButtons.Left ) != 0 )
      {
        int Y = e.Y * Image2.Image.Height / Image2.Height;
        int X = e.X * Image2.Image.Width / Image2.Width;
        int i = X - 50;
        if ( i < 0 ) return;
        if ( i >= 512 ) return;
        labelM.Text = " Derivative["+i.ToString()+"] =" + Derivative[ GIndex, i ].ToString( );
        Invalidate( );
      }
    }

    

    private void numericUpDown1_ValueChanged (object sender, EventArgs e)
    {
      GIndex = (int)numericUpDown1.Value;
    }

   
    private void CornersPicture_MouseUp (object sender, MouseEventArgs e)
    {

      CornersPictureDown = false;
      ShowFile( );
      Invalidate( );

    }

    private void CornersPicture_MouseMove (object sender, MouseEventArgs e)
    {

      int iC, X = e.X;
      int iR, Y = e.Y;

      const int Siz = 5;
      iR   =Y/Siz - 14;
      iC   = X/Siz- 14;

      //iC = X;        iR = Y;

      int fR = Decoder.GetDebugProperty( 44, iR, iC );
      int fC = Decoder.GetDebugProperty( 43, iR, iC );

      CornersPictureX = fC;
      CornersPictureY = fR;
      int C = Decoder.GetDebugProperty( 50, iR, iC ); //DebugProperty_50

      if ( C > 128 )
        CornersPictureC = Brushes.Aqua;
      else
        CornersPictureC = Brushes.Red;
      Invalidate( );
    }

    private void CornersPicture_MouseDown (object sender, MouseEventArgs e)
    {
      CornersPictureDown = true;
      ShowFile( );
      textBox1.AppendText( "\r\n(" + CornersPictureX.ToString( ) + "," + CornersPictureY.ToString( ) + ")" );
    }

    private void Button_50_Click (object sender, EventArgs e)
    {
      int iC=(int)fC_UpDown.Value;
      int iR=(int)fR_UpDown.Value;

      int fR = Decoder.GetDebugProperty( 44, iR, iC );
      int fC = Decoder.GetDebugProperty( 43, iR, iC );

      CornersPictureX = fC;
      CornersPictureY = fR;
      int C = Decoder.GetDebugProperty( 50, iR, iC ); //DebugProperty_50

      if ( C > 128 )
        CornersPictureC = Brushes.Aqua;
      else
        CornersPictureC = Brushes.Red;
      CornersPictureDown = true;
      ShowFile( );
      textBox1.AppendText( "\r\n(" + CornersPictureX.ToString( ) + "," + CornersPictureY.ToString( ) + ")" );


    }
  }
}
