using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DMatrixEncode;

namespace EncodeDemo
{
   public partial class Form1 : Form
   {
      const int MAX_MATRIX_SIZE = 144 * 144;
      int MATRIX_MODULE_SIZE = 3;
      int QZ_SIZE = 6;

      private byte[] dMatrix = new byte[MAX_MATRIX_SIZE];
      private DMatrixEncoder encoder = new DMatrixEncoder();

      public Form1()
      {
         InitializeComponent();

         compact_comboBox1.SelectedIndex = 0;
         dim_comboBox1.SelectedIndex = 0;
         signature_comboBox.SelectedIndex = 0;
         saveFileDialog1.Filter = "BMP files(*.bmp)| *.bmp";
      }

      private void encode_button1_Click(object sender, EventArgs e)
      {
         if (saveImage_checkBox1.Checked)
            EncodeToBMP(".\\matrix.bmp");
         else
            EncodeToBMP(null);
      }

      void EncodeToBMP(string bmpName)
      {
         bool res;
         // Set size of module
         MATRIX_MODULE_SIZE = (int)module_numericUpDown1.Value;
         // Set size of QZ
         QZ_SIZE = MATRIX_MODULE_SIZE * 2;

         // Clear encoder
         encoder.Crear();

         // Set DMatrix size
         res = encoder.SetDimensions((T_DIMENSION)dim_comboBox1.SelectedIndex - 1);
         if (!res) { EncoderError(); return; }

         // Set scheme
         res = encoder.SetScheme((T_SCHEME)compact_comboBox1.SelectedIndex);
         if (!res) { EncoderError(); return; }

         // Set user autentification
         bool aut = (signature_comboBox.SelectedIndex == 1) || (signature_comboBox.SelectedIndex == 3);
         res = encoder.SetSignUser(aut);
         if (!res) { EncoderError(); return; }

         // Set encriptions
         bool encript = (signature_comboBox.SelectedIndex == 2) || (signature_comboBox.SelectedIndex == 3);
         if (encript)
            res = encoder.SetSignProduct(productID_textBox1.Text);
         else
            res = encoder.SetSignProduct(null);
         if (!res) { EncoderError(); return; }

         // Create DMatrix
         res = encoder.EncodeToBuf(data_textBox1.Text, dMatrix);
         if (!res) { EncoderError(); return; }

         // Create Dmatrix as BMP file
         if (bmpName != null)
         {
            res = encoder.EncodeToBMP(data_textBox1.Text, bmpName, MATRIX_MODULE_SIZE, QZ_SIZE);
            if (!res)
            {
               if (encoder.lastError == (int)T_RESULT.DME_RES_UNKNOWN)
               { MessageBox.Show(this, "Can't save image file!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; }
               else
               { EncoderError(); return; }
            }
         }

         DrawMatrix();
      }

      void DrawMatrix()
      {
         int matrixV = 0;
         int matrixH = 0;
         DMatrixSize sz = encoder.GetMatrixSize();
         matrixV = sz.height;
         matrixH = sz.width;

         Bitmap image = new Bitmap(matrixH * MATRIX_MODULE_SIZE + QZ_SIZE*2, matrixV * MATRIX_MODULE_SIZE + QZ_SIZE * 2);

         using (Graphics graph = Graphics.FromImage(image))
         {
            graph.Clear(Color.White);
         }
         for (int row = 0; row < matrixV; row++)
            for (int col = 0; col < matrixH; col++)
            {
               if (dMatrix[row * matrixH + col] != 0)
               {
                  int r0 = row * MATRIX_MODULE_SIZE + QZ_SIZE;
                  int c0 = col * MATRIX_MODULE_SIZE + QZ_SIZE;
                  for (int r = 0; r < MATRIX_MODULE_SIZE; r++)
                     for (int c = 0; c < MATRIX_MODULE_SIZE; c++)
                        image.SetPixel(c0 + c, r0 + r, Color.Black);
               }
            }
         pictureBox1.Image = image;
      }

      void EncoderError()
      {
         int error = encoder.lastError;
         string msg = "Encode error: " + error + "\n";
         switch((T_RESULT)error)
         {
            case T_RESULT.DME_RES_LONG1:
               msg = msg + "Too long text for this matrix size!";
               break;
            case T_RESULT.DME_RES_LONG2: 
               msg = msg + "Too long text for all sizes";
               break;
            case T_RESULT.DME_RES_ANSIX12: 
               msg = msg + "Unresolved character in ANSIX12 encodation";
               break;
            case T_RESULT.DME_RES_EDIFACT:  
               msg = msg + "Unresolved character  for Edifact encodation";
               break;
            case T_RESULT.DME_RES_AU_FAIL:  
               msg = msg + "Authentication failure";
               break;
            case T_RESULT.DME_RES_TYPE:    
               msg = msg + "Type error";
               break;
            case T_RESULT.DME_RES_DIMENSION:  
               msg = msg + "Dimension error";
               break;
            case T_RESULT.DME_RES_PARAMS:   
               msg = msg + "Invalid parameter";
               break;
            case T_RESULT.DME_RES_UserID:    
               msg = msg + "User ID not found or error";
               break;
            case T_RESULT.DME_RES_STRUCTURE:  
               msg = msg + "Structure error";
               break;
            case T_RESULT.DME_RES_CRYPTO:  
               msg = msg + "Data damaged (crypto error)";
               break;
            case T_RESULT.DME_RES_MATRIX:  
               msg = msg + "Incorrect MATRIX";
               break;
            case T_RESULT.DME_RES_EMPTY:  
               msg = msg + "No data";
               break;
            case T_RESULT.DME_RES_ProdID: 
               msg = msg + "Product ID error";
               break;
	      }
         MessageBox.Show(this, msg, "Warning!", MessageBoxButtons.OK ,MessageBoxIcon.Warning);
      }

      private void encodeTo_button_Click(object sender, EventArgs e)
      {
         if(saveFileDialog1.ShowDialog() == DialogResult.OK)
         {
            EncodeToBMP(saveFileDialog1.FileName);
         }
      }

      private void label3_Click(object sender, EventArgs e)
      {

      }
   }
}
