// <copyright file="ExampleForm.cs" company="Scriptel Corporation">
//      Copyright 2014 - Scriptel Corporation
// </copyright>
namespace ExampleForm
{
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    using EasyScriptAPI;
    using System.Drawing.Drawing2D;

    /// <summary>
    /// This class is a simple example form demonstrating the use of the C# keyboard
    /// API.
    /// </summary>
    public partial class ExampleForm : Form, IEasyScriptEventListener
    {
        /// <summary>
        /// This object is responsible for parsing keyboard strings.
        /// </summary>
        private EasyScript eScript;
        /// <summary>
        /// Graphics object we'll draw on to in order to produce a signature
        /// image.
        /// </summary>
        private Graphics graphics;
        /// <summary>
        /// Raster backing the graphics object.
        /// </summary>
        private Bitmap raster;
        /// <summary>
        /// Pen we'll use to create strokes on our graphics object.
        /// </summary>
        private Pen pen;
        /// <summary>
        /// The last point we captured.
        /// </summary>
        private Coordinate lastPoint = null;
        /// <summary>
        /// Whether or not the next event we receive should clear the signature.
        /// </summary>
        private bool clearOnNext = false;
        /// <summary>
        /// The current stroke count.
        /// </summary>
        private int strokeCount = 0;
        /// <summary>
        /// The amount to scale the coordinates by.
        /// </summary>
        private double scaleFactor = 1;

        /// <summary>
        /// Initializes a new instance of the <see cref="ExampleForm"/> class.
        /// </summary>
        public ExampleForm()
        {
            //Create a new EasyScript object.
            this.eScript = new EasyScript();

            //Register ourselves as a signature listener.
            eScript.AddListener(this);

            //Initialize our form.
            this.InitializeComponent();

            //Initialize our drawing components.
            raster = new Bitmap(signaturePictureBox.Width, signaturePictureBox.Height);
            graphics = Graphics.FromImage(raster);

            //Enable high quality drawing.
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.CompositingQuality = CompositingQuality.HighQuality;
            graphics.SmoothingMode = SmoothingMode.AntiAlias;
            pen = new Pen(Brushes.Black);

            //Calculate our scale factor based on the size of the picture box.
            scaleFactor = signaturePictureBox.Width / eScript.GetSignatureProtocol().GetWidth();

            //Clear the picture box.
            ClearSignatureBox();

            // this allows the form to preview all keyboard events before other parts of the form are allowed
            // to get them. If a particular keyboard event is from a ScripTouch device, 
            // we can prevent the event from propogating to other form elements, such as a TextBox.
            this.KeyPreview = true;
            this.cardSwipeInfoTextBox.ReadOnly = true;
            this.signatureInfoTextBox.ReadOnly = true;
        }

        /// <summary>
        /// This method handles exceptions generated by parsing signatures and
        /// cards.
        /// </summary>
        /// <param name="e">Exception to handle.</param>
        private void HandleException(Exception e)
        {
            cardSwipeInfoTextBox.Text = e.Message;
            signatureInfoTextBox.Text = e.Message;
        }

        /// <summary>
        /// This method clears the picture box showing the signature.
        /// </summary>
        private void ClearSignatureBox()
        {
            graphics.FillRectangle(Brushes.White, 0, 0, signaturePictureBox.Width, signaturePictureBox.Height);
            signaturePictureBox.Image = raster;
            signatureInfoTextBox.Text = "";
            strokeCount = 0;
        }

        /// <summary>
        /// This keyboard handler intercepts keyboard presses and passes them
        /// to EasyScript for parsing.
        /// </summary>
        /// <param name="sender">The sender of this event.</param>
        /// <param name="e">Keyboard event to parse.</param>
        private void ExampleFormKeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                char? chr = EasyScript.KeyboardEventToChar(e);
                if (chr != null)
                {
                    eScript.Parse((char)chr);
                }
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
        }

        /// <summary>
        /// This method gets called by EasyScript when a new coordinate is parsed.
        /// </summary>
        /// <param name="coordinate">Coordinate that was parsed.</param>
        void IEasyScriptEventListener.ReceiveCoordinate(Coordinate coordinate)
        {
            if (lastPoint != null)
            {
                graphics.DrawLine(pen, (float)(lastPoint.X * scaleFactor), (float)(lastPoint.Y * scaleFactor), (float)(coordinate.X * scaleFactor), (float)(coordinate.Y * scaleFactor));
                signaturePictureBox.Image = raster;
            }
            lastPoint = coordinate;

            signatureInfoTextBox.Text += "      " + coordinate + System.Environment.NewLine;
        }

        /// <summary>
        /// This method gets called by EasyScript when a new stroke is parsed.
        /// </summary>
        void IEasyScriptEventListener.NewStroke()
        {
            lastPoint = null;
            signatureInfoTextBox.Text += "   Stroke " + (strokeCount++) + ":" + System.Environment.NewLine;
        }

        /// <summary>
        /// This method gets called by EasyScript when the signature is cancelled
        /// by pressing the "Cancel" button in streaming mode.
        /// </summary>
        void IEasyScriptEventListener.Cancel()
        {
            ClearSignatureBox();
        }

        /// <summary>
        /// This method gets called by EasyScript when the signature is accepted
        /// by pressing "Ok" or "Accept".
        /// </summary>
        void IEasyScriptEventListener.EndOfSignature()
        {
            clearOnNext = true;
        }

        /// <summary>
        /// This method gets called by EasyScript when the preamble metadata is
        /// available.
        /// </summary>
        /// <param name="metadata">Signature metadata.</param>
        void IEasyScriptEventListener.SignatureMetaData(SignatureMetaData metadata)
        {
            if (clearOnNext)
            {
                ClearSignatureBox();
                clearOnNext = false;
            }

            signatureInfoTextBox.Text = metadata.ToString();
        }

        /// <summary>
        /// This method gets called by EasyScript when a card swipe is detected.
        /// </summary>
        /// <param name="swipe">Card swipe that was detected.</param>
        void IEasyScriptEventListener.CardSwipe(CardSwipe swipe)
        {
            cardSwipeInfoTextBox.Text = swipe.ToString();
        }
    }
}
