/***************************************************************************/
/**                                                                       **/
/**                               MAGICARD                                **/
/**                                                                       **/
/***************************************************************************/
/**                                                                       **/
/**  PROJECT      : SDK C# Demo - Ultima Printers                         **/
/**                                                                       **/
/**  MODULE NAME  : Encoding.cs                                           **/
/**                                                                       **/
/**  COPYRIGHT    : Magicard                                              **/
/**                                                                       **/
/***************************************************************************/
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using SDKShim;

namespace CSharpDemo
{
    public partial class SDK_CSDemo : Form
    {
        #region === Initialisation ===

        private void InitEncodingTab()
        {
            InitEncodingTypeCombo();
            InitCoercivityCombo();
            InitBPCCombos();
            InitBPICombos();
        }

        Dictionary<SDK.EncodingSpec, string> encodingkp = new Dictionary<SDK.EncodingSpec, string>()
        {
            {SDK.EncodingSpec.ISO,  "ISO"},
            {SDK.EncodingSpec.JIS2, "JIS2"},
            //{SDK.EncodingSpec.RAW,  "Raw"},
        };

        private void InitEncodingTypeCombo()
        {
            EncodingTypeCombo.DataSource    = new BindingSource(encodingkp, null);
            EncodingTypeCombo.DisplayMember = "Value";
        }

        Dictionary<SDK.Coercivity, string> coercivitykp = new Dictionary<SDK.Coercivity, string>()
        {
            {SDK.Coercivity.Default, "Default"},
            {SDK.Coercivity.HiCo,    "HiCo"},
            {SDK.Coercivity.LoCo,    "LoCo"},
        };

        private void InitCoercivityCombo()
        {
            CoercivityCombo.DataSource = new BindingSource(coercivitykp, null);
            CoercivityCombo.DisplayMember = "Value";
        }

        Dictionary<SDK.BitsPerChar, string> bpckp = new Dictionary<SDK.BitsPerChar, string>()
        {
            {SDK.BitsPerChar.Default, "Default"}, 
            {SDK.BitsPerChar.BPC1,    "1"},       
            {SDK.BitsPerChar.BPC5,    "5"},       
            {SDK.BitsPerChar.BPC7,    "7"},       
        };

        private void InitBPCCombos()
        {
            T1_BPCCombo.DataSource    = new BindingSource(bpckp, null);
            T1_BPCCombo.DisplayMember = "Value";
            T2_BPCCombo.DataSource    = new BindingSource(bpckp, null);
            T2_BPCCombo.DisplayMember = "Value";
            T3_BPCCombo.DataSource    = new BindingSource(bpckp, null);
            T3_BPCCombo.DisplayMember = "Value";
        }

        Dictionary<SDK.BitsPerInch, string> bpikp = new Dictionary<SDK.BitsPerInch, string>()
        {
            {SDK.BitsPerInch.Default, "Default"}, 
            {SDK.BitsPerInch.BPI210,  "210"},     
            {SDK.BitsPerInch.BPI75,   "75"},      
        };

        private void InitBPICombos()
        {
            T1_BPICombo.DataSource = new BindingSource(bpikp, null);
            T1_BPICombo.DisplayMember = "Value";
            T2_BPICombo.DataSource = new BindingSource(bpikp, null);
            T2_BPICombo.DisplayMember = "Value";
            T3_BPICombo.DataSource = new BindingSource(bpikp, null);
            T3_BPICombo.DisplayMember = "Value";
        }

        #endregion === Initialisation ===

        //----------------------------------------------------------------------

        #region === Local Methods ===

        private void CheckDataAvailable()
        {
            EncodeMagButton.Enabled = Track1Write.Checked || Track2Write.Checked || Track3Write.Checked;
        }

        private void ClearEncodingBoxButton_Click(object sender, EventArgs e)
        {
            EncodingBox.Clear();
        }

        private void Track1Write_CheckedChanged(object sender, EventArgs e)
        {
            //Enable/Disable the appropriate controls according to the selection
            Track1Label.Enabled         = Track1Write.Checked;
            Track1SettingsLabel.Enabled = Track1Write.Checked;
            Track1Data.Enabled          = Track1Write.Checked;
            T1_BPCCombo.Enabled         = Track1Write.Checked;
            T1_BPICombo.Enabled         = Track1Write.Checked;

            CheckDataAvailable();
        }

        private void Track2Write_CheckedChanged(object sender, EventArgs e)
        {
            //Enable/Disable the appropriate controls according to the selection
            Track2Label.Enabled         = Track2Write.Checked;
            Track2SettingsLabel.Enabled = Track2Write.Checked;
            Track2Data.Enabled          = Track2Write.Checked;
            T2_BPCCombo.Enabled         = Track2Write.Checked;
            T2_BPICombo.Enabled         = Track2Write.Checked;

            CheckDataAvailable();
        }

        private void Track3Write_CheckedChanged(object sender, EventArgs e)
        {
            //Enable/Disable the appropriate controls according to the selection
            Track3Label.Enabled         = Track3Write.Checked;
            Track3SettingsLabel.Enabled = Track3Write.Checked;
            Track3Data.Enabled          = Track3Write.Checked;
            T3_BPCCombo.Enabled         = Track3Write.Checked;
            T3_BPICombo.Enabled         = Track3Write.Checked;

            CheckDataAvailable();
        }

        private void EncodingTypeBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            //Enable/Disable appropriate controls according to ISO or JIS2 being selected
            bool visible = (EncodingTypeCombo.SelectedIndex == 0);		//TRUE if ISO, FALSE if JIS2

            Track1Label.Visible         = visible;
            Track1Write.Visible         = visible;
            Track2Label.Visible         = visible;
            Track2Data.Visible          = visible;
            Track2Write.Visible         = visible;
            Track3Label.Visible         = visible;
            Track3Data.Visible          = visible;
            Track3Write.Visible         = visible;
            Track1SettingsLabel.Visible = visible;
            Track2SettingsLabel.Visible = visible;
            Track3SettingsLabel.Visible = visible;

            T1_BPCCombo.Visible         = visible;
            T1_BPICombo.Visible         = visible;
            T2_BPCCombo.Visible         = visible;
            T2_BPICombo.Visible         = visible;
            T3_BPCCombo.Visible         = visible;
            T3_BPICombo.Visible         = visible;
            BitsPerCharLabel.Visible    = visible;
            BitsPerInchLabel.Visible    = visible;

            //JIS2 labels are the opposite of ISO labels
            JIS2Label.Visible = !visible;

            Track1Read.Visible = visible;
            Track2Read.Visible = visible;
            Track3Read.Visible = visible;
            ReadMagTracks.Visible = visible;
        }

        private void EncodingGetRadio_CheckedChanged(object sender, EventArgs e)
        {
            StartPosn.Enabled = false;
        }

        private void EncodingSetRadio_CheckedChanged(object sender, EventArgs e)
        {
            StartPosn.Enabled = true;
        }

        #endregion === Local Methods ===

        //----------------------------------------------------------------------

        #region === Encode Mag ===

        static private char ISO_7_BIT_START_SENTINEL = '%';
        static private char ISO_5_BIT_START_SENTINEL = ';';
        static private char ISO_END_SENTINEL         = '?';
        static private char JIS2_SENTINEL            = '\x7f';

        private void EncodeMagButton_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;

            SDK.MagDef Encode = new SDK.MagDef();

            Encode.EncodingSpec = ((KeyValuePair<SDK.EncodingSpec, string>)EncodingTypeCombo.SelectedItem).Key;
            Encode.Coercivity   = ((KeyValuePair<SDK.Coercivity, string>)CoercivityCombo.SelectedItem).Key;
            Encode.Verify       = Verify.Checked ? SDK.Verify.On : SDK.Verify.Off;

            if (Encode.EncodingSpec == SDK.EncodingSpec.JIS2)
            {
                Encode.Track[0].CharCount = decimal.ToByte(Track1Data.TextLength);
                Encode.Track[0].Data = JIS2_SENTINEL + Track1Data.Text + JIS2_SENTINEL;
            }

            else
            {
                if (Track1Write.Checked)
                {
                    if (Encode.EncodingSpec == SDK.EncodingSpec.ISO)
                        Encode.Track[0].Data = ISO_7_BIT_START_SENTINEL + Track1Data.Text + ISO_END_SENTINEL;
                    else
                        Encode.Track[0].Data = Track1Data.Text;
                    Encode.Track[0].CharCount   = decimal.ToByte(Track1Data.TextLength);
                    Encode.Track[0].BitsPerChar = ((KeyValuePair<SDK.BitsPerChar, string>)T1_BPCCombo.SelectedItem).Key;
                    Encode.Track[0].BitsPerInch = ((KeyValuePair<SDK.BitsPerInch, string>)T1_BPICombo.SelectedItem).Key;
                }

                if (Track2Write.Checked)
                {
                    if (Encode.EncodingSpec == SDK.EncodingSpec.ISO)
                        Encode.Track[1].Data = ISO_5_BIT_START_SENTINEL + Track2Data.Text + ISO_END_SENTINEL;
                    else
                        Encode.Track[1].Data = Track2Data.Text;
                    Encode.Track[1].CharCount   = decimal.ToByte(Track2Data.TextLength);
                    Encode.Track[1].BitsPerChar = ((KeyValuePair<SDK.BitsPerChar, string>)T2_BPCCombo.SelectedItem).Key;
                    Encode.Track[1].BitsPerInch = ((KeyValuePair<SDK.BitsPerInch, string>)T2_BPICombo.SelectedItem).Key;
                }

                if (Track3Write.Checked)
                {
                    if (Encode.EncodingSpec == SDK.EncodingSpec.ISO)
                        Encode.Track[2].Data = ISO_5_BIT_START_SENTINEL + Track3Data.Text + ISO_END_SENTINEL;
                    else
                        Encode.Track[2].Data = Track2Data.Text;
                    Encode.Track[2].CharCount   = decimal.ToByte(Track3Data.TextLength);
                    Encode.Track[2].BitsPerChar = ((KeyValuePair<SDK.BitsPerChar, string>)T3_BPCCombo.SelectedItem).Key;
                    Encode.Track[2].BitsPerInch = ((KeyValuePair<SDK.BitsPerInch, string>)T3_BPICombo.SelectedItem).Key;
                }
            }

            SDK.Return SDKReturn = SDK.ID_EncodeMag(hSession, Encode);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("EncodeMag", SDKReturn);
            }
            else
            {
                WaitForPrinterToFinish();
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Encode Mag ===

        //----------------------------------------------------------------------

        #region === Display Mag Data ===

        private void DisplayUltimaMag(SDK.MagData2 MagData, SDK.TrackID Tracks = SDK.TrackID.AllTracks)
        {
            SDK.EncodingSpec EncodingSpec = ((KeyValuePair<SDK.EncodingSpec, string>)EncodingTypeCombo.SelectedItem).Key;

            if (Tracks.HasFlag(SDK.TrackID.Track1)) EncodingBox.AppendText("(1): " + MagData.tk1 + Environment.NewLine);
            if (EncodingSpec == SDK.EncodingSpec.ISO)
            {
                if (Tracks.HasFlag(SDK.TrackID.Track2)) EncodingBox.AppendText("(2): " + MagData.tk2 + Environment.NewLine);
                if (Tracks.HasFlag(SDK.TrackID.Track3)) EncodingBox.AppendText("(3): " + MagData.tk3 + Environment.NewLine);
            }
            EncodingBox.AppendText(Environment.NewLine);
        }

        #endregion === Display Mag Data ===

        //----------------------------------------------------------------------

        #region === Read Mag Data (3 tracks) ===

        private void ReadMagButton_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;

            SDK.EncodingSpec EncodingSpec = ((KeyValuePair<SDK.EncodingSpec, string>)EncodingTypeCombo.SelectedItem).Key;

            SDK.MagData2 MagData = new SDK.MagData2();
            SDK.Return SDKReturn = SDK.ID_ReadMag(hSession, MagData, EncodingSpec);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("ReadMag", SDKReturn);
            }

            else
            {
				DisplayUltimaMag(MagData);
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Read Mag Data (3 tracks) ===

        //----------------------------------------------------------------------

        #region === Read Mag Tracks ===

        private void ReadMagTracks_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;

            SDK.EncodingSpec EncodingSpec = ((KeyValuePair<SDK.EncodingSpec, string>)EncodingTypeCombo.SelectedItem).Key;

            //Call SDK to read the Mag Stripe Data
            SDK.TrackID Tracks = 0;
            if (Track1Read.Checked) Tracks |= SDK.TrackID.Track1;
            if (Track2Read.Checked) Tracks |= SDK.TrackID.Track2;
            if (Track3Read.Checked) Tracks |= SDK.TrackID.Track3;

            if (Tracks == 0)
            {
                return;
            }

            SDK.MagData2 MagData = new SDK.MagData2();
            SDK.Return SDKReturn = SDK.ID_ReadMagTracks(hSession, MagData, EncodingSpec, Tracks);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("ReadMagTracks", SDKReturn);
            }

            else
            {
				DisplayUltimaMag(MagData, Tracks);
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Read Mag Tracks ===

        //----------------------------------------------------------------------

        #region === Mag Start ===

        private SDK.Return GetMagStart(ref int MagStart)
        {
            SDK.Return SDKReturn = SDK.ID_MagStart(hSession, SDK.Action.Read, ref MagStart);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("MagStart", SDKReturn);
            }
            else
            {
                MagStartToControl(MagStart);
            }

            return SDKReturn;
        }

        private void MagStartToControl(int MagStart)
        {
            StartPosn.Value = MagStart;
        }

        private void MagStartToMsgBox(int MagStart, SDK.Action Action)
        {
            EncodingBox.AppendText("MagStart" + Separator(Action) + MagStart.ToString());
            EncodingBox.AppendText(Environment.NewLine);
        }

        private void MagStartButton_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;

            int MagStart = new int();

            if (EncodingGetRadio.Checked)
            {
                if (GetMagStart(ref MagStart) == SDK.Return.Success)
                {
                    MagStartToMsgBox(MagStart, SDK.Action.Read);
                }
            }
            else
            {
                //Call the SDK to write to the driver
                MagStart = decimal.ToInt32(StartPosn.Value);

                SDK.Return SDKReturn = SDK.ID_MagStart(hSession, SDK.Action.Write, ref MagStart);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetMagStart", SDKReturn);
                }

                else
                {
                    MagStartToMsgBox(MagStart, SDK.Action.Write);
                }
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Mag Start ===
    }
}
