// <copyright file="IdentificationCardTrackTwo.cs" company="Scriptel Corporation">
//      Copyright 2014 - Scriptel Corporation
// </copyright>
namespace EasyScriptAPI
{
    using System;
    using System.Text;
    using System.Text.RegularExpressions;

    /// <summary>
    /// This class represents track two of a magnetic strip identification card
    /// such as a United States driver's license.
    /// </summary>
    public class IdentificationCardTrackTwo
    {
        /// <summary>
        /// Issuer identification number
        /// </summary>
        private string issuerNumber;

        /// <summary>
        /// Document number
        /// </summary>
        private string idNumber;

        /// <summary>
        /// Document expiration date.
        /// </summary>
        private DateTime expiration;

        /// <summary>
        /// Card holder birth date.
        /// </summary>
        private DateTime birthDate;
    
        /// <summary>
        /// This method attempts to parse track two data from a raw magnetic strip
        /// string.
        /// </summary>
        /// <param name="trackData">Track data to parse</param>
        /// <returns>IdentificationCardTrackTwo data if possible, null otherwise.</returns>
        public static IdentificationCardTrackTwo Parse(string trackData)
        {
            Regex regex = new Regex(".*;(6[0-9]{5})([0-9]{1,13})=([0-9]{4})([0-9]{8})([0-9]{0,5})=?\\?.*");
            Match m = regex.Match(trackData);
            if (m.Success)
            {
                IdentificationCardTrackTwo track = new IdentificationCardTrackTwo();
                track.SetIssuerNumber(m.Groups[1].Value);
                track.SetIdNumber(m.Groups[2].Value);
            
                int expYear = 2000 + int.Parse(m.Groups[3].Value.Substring(0, 2));
                int expMonth = int.Parse(m.Groups[3].Value.Substring(2));

                DateTime thisMonth = new DateTime(expYear, expMonth, 1, 0, 0, 0, 0);
                DateTime nextMonth = thisMonth.AddMonths(1);
                track.SetExpiration(nextMonth.AddMilliseconds(-1));

                int birthYear = int.Parse(m.Groups[4].Value.Substring(0, 4));
                int birthMonth = int.Parse(m.Groups[4].Value.Substring(4, 2));
                int birthDay = int.Parse(m.Groups[4].Value.Substring(6));

                track.SetBirthDate(new DateTime(birthYear, birthMonth, birthDay));
            
                return track;
            }
        
            return null;
        }
    
        /// <summary>
        /// Returns this object as a human readable string
        /// </summary>
        /// <returns>this object as a human readable string</returns>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            string ln = Environment.NewLine;
            sb.Append("Identification Card - Track Two:").Append(ln);
            sb.Append("     Issuer Number: ").Append(this.issuerNumber).Append(ln);
            sb.Append("         ID Number: ").Append(this.idNumber).Append(ln);
            sb.Append("        Expiration: ").Append(this.expiration).Append(ln);
            sb.Append("        Birth Date: ").Append(this.birthDate).Append(ln);
            return sb.ToString();
        }

        /// <summary>
        /// Gets the issuer identification number. This can be used to determine
        /// which state issued the document.
        /// </summary>
        /// <returns>issuer identification number</returns>
        public string GetIssuerNumber()
        {
            return this.issuerNumber;
        }

        /// <summary>
        /// Gets the document id number
        /// </summary>
        /// <returns>document id number</returns>
        public string GetIdNumber()
        {
            return this.idNumber;
        }

        /// <summary>
        /// Gets the expiration date of the document
        /// </summary>
        /// <returns>expiration date of the document</returns>
        public DateTime GetExpiration()
        {
            return this.expiration;
        }

        /// <summary>
        /// Gets the birth date of the card holder.
        /// </summary>
        /// <returns>birth date of the card holder.</returns>
        public DateTime GetBirthDate()
        {
            return this.birthDate;
        }

        /// <summary>
        /// Sets the issuer identification number
        /// </summary>
        /// <param name="issuerNumber">issuer identification number</param>
        private void SetIssuerNumber(string issuerNumber)
        {
            this.issuerNumber = issuerNumber;
        }

        /// <summary>
        /// Sets the document id number
        /// </summary>
        /// <param name="idNumber">document id number</param>
        private void SetIdNumber(string idNumber)
        {
            this.idNumber = idNumber;
        }

        /// <summary>
        /// Sets the expiration date of the document.
        /// </summary>
        /// <param name="expiration">expiration date of the document.</param>
        private void SetExpiration(DateTime expiration)
        {
            this.expiration = expiration;
        }

        /// <summary>
        /// Sets the birth date of the card holder.
        /// </summary>
        /// <param name="birthDate">birth date of the card holder.</param>
        private void SetBirthDate(DateTime birthDate)
        {
            this.birthDate = birthDate;
        }
    }
}
