// <copyright file="BlockingEasyScriptListener.cs" company="Scriptel Corporation">
//      Copyright 2015 - Scriptel Corporation
// </copyright>
namespace EasyScriptAPI
{
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// This class implements a legacy style signature listener where an entire
    /// signature is buffered before it's returned to a caller.
    /// </summary>
    class BlockingEasyScriptListener: IEasyScriptEventListener
    {
        /// <summary>
        /// Captured metadata.
        /// </summary>
        private SignatureMetaData metadata = null;
        /// <summary>
        /// Captured card swipe.
        /// </summary>
        private CardSwipe swipe = null;
        /// <summary>
        /// List of captured strokes and coordinates.
        /// </summary>
        private List<List<Coordinate>> coordinates = new List<List<Coordinate>>();
        /// <summary>
        /// Whether or not the next coordinate should trigger a new stroke.
        /// </summary>
        private bool newStroke = true;
        /// <summary>
        /// Whether or not this signature is complete (canceled or otherwise).
        /// </summary>
        private bool done = false;
        /// <summary>
        /// Whether or not this signature was canceled.
        /// </summary>
        private bool canceled = false;

        /// <summary>
        /// Receives a coordinate from the library and adds it to the current
        /// stroke.
        /// </summary>
        /// <param name="coordinate">Coordinate to add.</param>
        void IEasyScriptEventListener.ReceiveCoordinate(Coordinate coordinate)
        {
            if (newStroke || coordinates.Count == 0)
            {
                coordinates.Add(new List<Coordinate>());
                newStroke = false;
            }

            coordinates[coordinates.Count - 1].Add(coordinate);
        }

        /// <summary>
        /// Starts a new stroke.
        /// </summary>
        void IEasyScriptEventListener.NewStroke()
        {
            newStroke = true;
        }

        /// <summary>
        /// Cancels the current signature.
        /// </summary>
        void IEasyScriptEventListener.Cancel()
        {
            canceled = true;
            done = true;
        }

        /// <summary>
        /// Captures the end of the signature.
        /// </summary>
        void IEasyScriptEventListener.EndOfSignature()
        {
            canceled = false;
            done = true;
        }

        /// <summary>
        /// Gets whether or not this signature is complete (canceled or otherwise).
        /// </summary>
        /// <returns>Whether this signature is complete.</returns>
        public bool IsDone()
        {
            return done;
        }

        /// <summary>
        /// Gets whether or not this signature was canceled.
        /// </summary>
        /// <returns>Whether or not this signature was canceled.</returns>
        public bool IsCanceled()
        {
            return canceled;
        }

        /// <summary>
        /// Captures the signature meta data that will be added to the signature
        /// at the end.
        /// </summary>
        /// <param name="md">Metadata to capture.</param>
        void IEasyScriptEventListener.SignatureMetaData(SignatureMetaData md)
        {
            metadata = md;
        }

        /// <summary>
        /// Captures a card swipe.
        /// </summary>
        /// <param name="s">Cardswipe to capture.</param>
        void IEasyScriptEventListener.CardSwipe(CardSwipe s)
        {
            swipe = s;
        }

        /// <summary>
        /// Gets the captured signature.
        /// </summary>
        /// <returns>Captured signature.</returns>
        public Signature GetSignature()
        {
            return new Signature(metadata.ProtocolVersion, metadata.Model, metadata.Version, coordinates);
        }

        /// <summary>
        /// Gets the captured card swipe.
        /// </summary>
        /// <returns>Captured card swipe.</returns>
        public CardSwipe GetCardSwipe()
        {
            return swipe;
        }
    }
}
