/***************************************************************************/
/**                                                                       **/
/**                               MAGICARD                                **/
/**                                                                       **/
/***************************************************************************/
/**                                                                       **/
/**  PROJECT      : SDK C# Demo - DTC Printers                            **/
/**                                                                       **/
/**  MODULE NAME  : Printer.cs                                            **/
/**                                                                       **/
/**  COPYRIGHT    : Magicard                                              **/
/**                                                                       **/
/***************************************************************************/
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Printing;
using System.Net;
using System.Diagnostics;
using SDKShim;

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

        static private IntPtr hSession = IntPtr.Zero;
        static private SDK.PrinterType printerType = SDK.PrinterType.None;
        static private IntPtr hDC = IntPtr.Zero;
        static private PrinterSettings ps = new PrinterSettings();
        static private PrintDialog pd = new PrintDialog();
        static private Graphics g;
        private object _locker = new object();

        private void InitPrinterTab()
        {
            InitSessionConfigCombo();
            InitErrorResponseCombo();
            InitMoveFilmCombo();
            InitHandFeedCombo();
            InitEjectModeCombo();
            InitHorzEjectCombo();
            InitEraseSpeedCombo();
            InitSmartModeCombo();
            InitIPModeCombo();

            FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo("SDKShim.dll");
            PrinterMsgBox.AppendText("Demo Version: " + Application.ProductVersion + Environment.NewLine);
            PrinterMsgBox.AppendText(myFileVersionInfo.FileDescription 
                                     + " Version: " 
                                     + myFileVersionInfo.FileVersion 
                                     + Environment.NewLine);
            PrinterMsgBox.AppendText(SDK.ID_SDKBits() + " Bit SDK" + Environment.NewLine + Environment.NewLine);
        }

        #endregion === Initialisation ===

        //*********************************************************************

        #region === Local Methods ===

        private void PrinterActionGetRadio_CheckedChanged(object sender, EventArgs e)
        {
            PrinterTabGetSetControls(false);
        }

        private void PrinterActionSet_CheckedChanged(object sender, EventArgs e)
        {
            PrinterTabGetSetControls(true);
        }

        private bool PrinterActionIsGet()
        {
            return PrinterGetRadio.Checked;
        }

        private void ClearPrinterMsgButton_Click(object sender, EventArgs e)
        {
            PrinterMsgBox.Clear();
        }

        private void ShowHideControls()
        {
            bool bControl = (printerType == SDK.PrinterType.Generation2);

            //Controls for Rio Pro 360
            MoveFilmButton.Visible     = bControl;
            MoveFilmCombo.Visible      = bControl;
            CardLocationButton.Visible = bControl;

            //Controls for Enduro
            GenCmdGroupBox.Visible     = !bControl;
            GenCommandBox.Visible      = !bControl;
            GenCommandButton.Visible   = !bControl;
            CleanPrinterButton.Visible = !bControl;
            SmartModeButton.Visible    = !bControl;
            SmartModeCombo.Visible     = !bControl;
            HorzEjectButton.Visible    = !bControl;
            HorzEjectCombo.Visible     = !bControl;
            EraseSpeedButton.Visible   = !bControl;
            EraseSpeedCombo.Visible    = !bControl;
        }

        private void PrinterTabGetSetControls(bool state)
        {
            SmartModeCombo.Enabled  = state;
            EraseSpeedCombo.Enabled = state;
            HorzEjectCombo.Enabled  = state;
            HandFeedCombo.Enabled   = state;
            EjectModeCombo.Enabled  = state;
            SmartOffsetBox.Enabled  = state;
            
            if (!ProntoPrinter())
            {
                IPModeCombo.Enabled  = state;
                IPAddressBox.Enabled = state;
                IPSubnetBox.Enabled  = state;
                IPGatewayBox.Enabled = state;
            }
        }

        private void EnableControls(bool state)
        {
            MoveFilmButton.Enabled      = state;
            MoveFilmCombo.Enabled       = state;
            CardLocationButton.Enabled  = state;
            GenCommandButton.Enabled    = state;
            GenCommandBox.Enabled       = state;
            CleanPrinterButton.Enabled  = state;
            EraseSpeedButton.Enabled    = state;
            HorzEjectButton.Enabled     = state;
            SmartModeButton.Enabled     = state;

            FeedMoveButton.Visible      = state;
            FeedMoveButton.Enabled      = state;
            FeedMoveCombo.Visible       = state;
            FeedMoveCombo.Enabled       = state;

            EjectCardButton.Enabled     = state;
            FlipCardButton.Enabled      = state;
            TestCardButton.Enabled      = state;
            RestartButton.Enabled       = state;
            EraseCardButton.Enabled     = state;
            EraseArea_BotLXBox.Enabled  = state;
            EraseArea_BotLYBox.Enabled  = state;
            EraseArea_TopRXBox.Enabled  = state;
            EraseArea_TopRYBox.Enabled  = state;
            EraseCount.Enabled          = state;
            ErrorResponseButton.Enabled = state;
            ErrorResponseCombo.Enabled    = state;
            PrinterGetRadio.Enabled     = state;
            PrinterSetRadio.Enabled     = state;
            HandFeedButton.Enabled      = state;
            EjectModeButton.Enabled     = state;
            SmartOffsetButton.Enabled   = state;
            IPSettingsButton.Enabled    = state;

            PrinterTabGetSetControls(!PrinterGetRadio.Checked);

            if (state)
            {
                TabControl.Controls.Add(Information);
                TabControl.Controls.Add(MagEncoding);
                TabControl.Controls.Add(DriverSettings1);
                TabControl.Controls.Add(DriverSettings2);
                TabControl.Controls.Add(PrintDemo);
                TabControl.Controls.Add(Utils);
            }
            else
            {
                TabControl.Controls.Remove(Information);
                TabControl.Controls.Remove(MagEncoding);
                TabControl.Controls.Remove(DriverSettings1);
                TabControl.Controls.Remove(DriverSettings2);
                TabControl.Controls.Remove(PrintDemo);
                TabControl.Controls.Remove(Utils);
            }
        }

        private Boolean ProntoPrinter()
        {
            if (printerType != SDK.PrinterType.Enduro)
            {
                return false;
            }

            return SDK.ID_PrinterModel(hSession).HasFlag(SDK.Model.Pronto);
        }

        private bool PrinterConnected()
        {
            string temp_string = "";
            switch (SDK.ID_PrinterStatus(hSession))
            {
            case SDK.PrinterStatus.Ready:   return true;
            case SDK.PrinterStatus.Offline: temp_string = "Printer is offline"; break;
            case SDK.PrinterStatus.Error:   temp_string = "Printer is in error"; break;
            case SDK.PrinterStatus.Busy:    temp_string = "Printer is busy"; break;
            }
            MessageBox.Show(temp_string, "Invalid Printer", MessageBoxButtons.OK);
            return false;
        }

        #endregion === Local Methods ===

        //*********************************************************************

        #region === Open Session ===

        Dictionary<SDK.Config, string> openconfigkp = new Dictionary<SDK.Config, string>()
        {
            {SDK.Config.Normal, "Config Normal"},
            {SDK.Config.Quiet,  "Config Quiet"},
        };

        private void InitSessionConfigCombo()
        {
            SessionConfigCombo.DataSource    = new BindingSource(openconfigkp, null);
            SessionConfigCombo.DisplayMember = "Value";
            SessionConfigCombo.SelectedItem  = SDK.Config.Normal;
        }

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

            pd.PrinterSettings = ps;
            pd.AllowPrintToFile = true;
            if (pd.ShowDialog() == DialogResult.OK)
            {
                ps = pd.PrinterSettings;

                // Get the printer HDC
                g = ps.CreateMeasurementGraphics();
                hDC = g.GetHdc();

                SDK.Config Config = ((KeyValuePair<SDK.Config, string>)SessionConfigCombo.SelectedItem).Key;
                SDK.Return SDKReturn = SDK.ID_OpenSession(hDC, out hSession, Config);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("OpenSession", SDKReturn);
                }
                else
                {
                    ResinAreaWidthUpDown.Maximum = SDK.ID_CardWidth(hSession);
                    AreaHoleWidthUpDown.Maximum  = SDK.ID_CardWidth(hSession);
                    EraseAreaWidthUpDown.Maximum = SDK.ID_CardWidth(hSession);
                    EraseArea_TopRXBox.Maximum   = SDK.ID_CardWidth(hSession) - 1;
                    EraseArea_TopRXBox.Value     = SDK.ID_CardWidth(hSession) - 1;

                    //Call the SDK to get the printer model
                    printerType = SDK.ID_PrinterType(hSession);
                    if ((printerType != SDK.PrinterType.Enduro)
                    &&  (printerType != SDK.PrinterType.Generation2))
                    {
                        MessageBox.Show("Use with DTC Printers Only", "Invalid Printer", MessageBoxButtons.OK);
                        SDK.ID_CloseSession(hSession);
                    }
                    else
                    {
                        PrinterID.Text = "Printer: " + pd.PrinterSettings.PrinterName;
                        PrinterID.Visible = true;
                        PrinterPrefs.Visible = true;

                        ShowHideControls();

                        if (printerType == SDK.PrinterType.Generation2)
                        {

                            EraseArea_TopRXBox.Value = SDK.ID_CardWidth(hSession) - 1;

                            FeedMoveButton.Text = "MoveCard";
                            InitMoveCardCombo();
                            FeedMoveCombo.Enabled = true;

                            if (!pd.PrintToFile)
                            {
                                //Get Hand Feed status
                                SDK.HandFeed mode = new SDK.HandFeed();
                                GetHandFeed(ref mode);
                                SetHandFeedCombo(mode);
                            }
                        }
                        else
                        {
                            FeedMoveButton.Text = "FeedCard";
                            InitFeedCardCombo();
                            FeedMoveCombo.Enabled = true;

                            if (!pd.PrintToFile)
                            {
                                SDK.PrinterInfo PrinterInfo = new SDK.PrinterInfo();
                                SDKReturn = SDK.ID_PrinterInfo(hSession, PrinterInfo);
                                if (SDKReturn != SDK.Return.Success)
                                {
                                    HandleError("Open - GetPrinterInfo", SDKReturn);
                                }
                                else
                                {
                                    if (PrinterInfo.iBitFields.HasFlag(SDK.InfoMask.EncodePlaten))
                                        SetSmartModeCombo(SDK.SmartMode.Platen);
                                    else if (PrinterInfo.iBitFields.HasFlag(SDK.InfoMask.EncodeXLI))
                                        SetSmartModeCombo(SDK.SmartMode.XLI);
                                    else
                                        SetSmartModeCombo(SDK.SmartMode.Default);
                                    SetHandFeedCombo(PrinterInfo.iHandFeed != 0
                                                    ? SDK.HandFeed.On : SDK.HandFeed.Off);
                                    SetEraseSpeedCombo(PrinterInfo.iBitFields.HasFlag(SDK.InfoMask.EraseSpeed)
                                                    ? SDK.EraseSpeed.Quick : SDK.EraseSpeed.Thorough);
                                    SetEjectModeCombo(PrinterInfo.iBitFields.HasFlag(SDK.InfoMask.EjectMode)
                                                    ? SDK.EjectMode.On : SDK.EjectMode.Off);
                                    SetHorzEjectCombo(PrinterInfo.iBitFields.HasFlag(SDK.InfoMask.HorzEject)
                                                    ? SDK.HorzEject.On : SDK.HorzEject.Off);
                                    SetSmartOffset(PrinterInfo.iSmartOffset);

                                    SDK.IPData settings = new SDK.IPData();
                                    GetIPSettings(ref settings);
                                    IPSettingsToCtrl(settings);

                                    IPModeCombo.Enabled  = true;
                                    IPAddressBox.Enabled = true;
                                    IPSubnetBox.Enabled  = true;
                                    IPGatewayBox.Enabled = true;
                                }
                            }
                        }

                        if (ProntoPrinter())
                        {
                            IPSettingsButton.Visible = false;
                            IPModeCombo.Visible      = false;
                            IPAddressBox.Visible     = false;
                            IPSubnetBox.Visible      = false;
                            IPGatewayBox.Visible     = false;
                            IPGroupBox.Visible       = false;
                            IPModeLabel.Visible      = false;
                            IPAddressLabel.Visible   = false;
                            IPSubnetLabel.Visible    = false;
                            IPGatewayLabel.Visible   = false;
                        }

                        if (PrinterIs600DPICapable())
                        {
                            byte resolution = 0;
                            GetResolution(ref resolution);
                            ResolutionButton.Enabled = true;
                        }

                        OpenSessionButton.Visible = false;
                        SessionConfigCombo.Visible = false;
                        CloseSessionButton.Visible = true;

                        EnableControls(true);
                    }
                }

                Application.DoEvents();
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Open Session ===

        //*********************************************************************

        #region === Close Session ===

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

            OpenSessionButton.Visible  = true;
            SessionConfigCombo.Visible = true;
            CloseSessionButton.Visible = false;

            PrinterID.Visible    = false;
            PrinterPrefs.Visible = false;

            EnableControls(false);
            PrinterTabGetSetControls(false);

            printerType = SDK.PrinterType.None;

            SDK.Return SDKReturn = SDK.ID_CloseSession(hSession);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("CloseSession", SDKReturn);
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Close Session ===

        //*********************************************************************

        #region === Error Response ===

        Dictionary<SDK.Response, string> errorresponsekp = new Dictionary<SDK.Response, string>()
        {
            {SDK.Response.OK,     "OK"},
            {SDK.Response.Cancel, "Cancel"},
        };

        private void InitErrorResponseCombo()
        {
            ErrorResponseCombo.DataSource    = new BindingSource(errorresponsekp, null);
            ErrorResponseCombo.DisplayMember = "Value";
            ErrorResponseCombo.SelectedItem  = SDK.Response.OK;
        }

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

            SDK.Response Response = ((KeyValuePair<SDK.Response, string>)ErrorResponseCombo.SelectedItem).Key;

            SDK.Return SDKReturn = SDK.ID_ErrorResponse(hSession, Response);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("ErrorResponse", SDKReturn);
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Error Response ===

        //*********************************************************************

        #region === General Command ===

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

            if (GenCommandBox.Text.Length == 0)
            {
                MessageBox.Show("General Command Box is empty");
            }
            else
            {
                SDK.Return SDKReturn = SDK.ID_GeneralCommand(hSession, GenCommandBox.Text);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("GeneralCommand", SDKReturn);
                }
                else
                {
                    WaitForPrinterToFinish();
                }
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === General Command ===

        //*********************************************************************

        #region === Feed/Move Card ===

        private void FeedMoveButton_Click(object sender, EventArgs e)
        {
            if (printerType == SDK.PrinterType.Generation2)
            {
                MoveCard();
            }
            else
            {
                FeedCard();
            }
        }

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

        Dictionary<SDK.FeedMode, string> feedcardkp = new Dictionary<SDK.FeedMode, string>()
        {
            {SDK.FeedMode.ChipCard,    "Contact"},     
            {SDK.FeedMode.Contactless, "ContactLess"}, 
        };

        private void InitFeedCardCombo()
        {
            FeedMoveCombo.DataSource    = new BindingSource(feedcardkp, null);
            FeedMoveCombo.DisplayMember = "Value";
            FeedMoveCombo.SelectedIndex = 0;
        }

        private void FeedCard()
        {
            Cursor.Current = Cursors.WaitCursor;

            SDK.FeedMode mode = ((KeyValuePair<SDK.FeedMode, string>)FeedMoveCombo.SelectedItem).Key;

            SDK.Return SDKReturn = SDK.ID_FeedCard(hSession, mode, 0);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("FeedCard", SDKReturn);
            }
            else
            {
                WaitForPrinterToFinish();
            }

            Cursor.Current = Cursors.Default;
        }

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

        Dictionary<SDK.CardPosition, string> movecardkp = new Dictionary<SDK.CardPosition, string>()
        {
            {SDK.CardPosition.Standby,            "Standby"},
            {SDK.CardPosition.ContactEncoder,     "Contact"},
            {SDK.CardPosition.ContactlessEncoder, "ContactLess"},
            {SDK.CardPosition.Rotate,             "Rotate"},
            {SDK.CardPosition.Eject,              "Eject"},
            {SDK.CardPosition.Initialise,         "Initialise"}, 
            {SDK.CardPosition.Reject,             "Reject"},
        };

        private void InitMoveCardCombo()
        {
            FeedMoveCombo.DataSource    = new BindingSource(movecardkp, null);
            FeedMoveCombo.DisplayMember = "Value";
            FeedMoveCombo.SelectedIndex = 0;
        }

        private void MoveCard()
        {
            Cursor.Current = Cursors.WaitCursor;

            SDK.CardPosition position = ((KeyValuePair<SDK.CardPosition, string>)FeedMoveCombo.SelectedItem).Key;
            SDK.Return SDKReturn = SDK.ID_MoveCard(hSession, position);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("MoveCard", SDKReturn);
		    }
            else
            {
                WaitForPrinterToFinish();
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Feed/Move Card ===

        //*********************************************************************

        #region === Move Film ===

        Dictionary<SDK.DyePanel, string> movefilmkp = new Dictionary<SDK.DyePanel, string>()
        {
            {SDK.DyePanel.Initialise, "Initialise"},
            {SDK.DyePanel.NextPanel,  "Next"},
            {SDK.DyePanel.Yellow,     "Yellow"},
            {SDK.DyePanel.Magenta,    "Magenta"},
            {SDK.DyePanel.Cyan,       "Cyan"},
            {SDK.DyePanel.KResin,     "KResin"}, 
            {SDK.DyePanel.Overcoat,   "Overcoat"},
        };

        private void InitMoveFilmCombo()
        {
            MoveFilmCombo.DataSource = new BindingSource(movefilmkp, null);
            MoveFilmCombo.DisplayMember = "Value";
        }

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

            SDK.DyePanel panel = ((KeyValuePair<SDK.DyePanel, string>)MoveFilmCombo.SelectedItem).Key;
            SDK.Return SDKReturn = SDK.ID_MoveFilm(hSession, panel);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("MoveFilm", SDKReturn);
            }
            else
            {
                WaitForPrinterToFinish();
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Move Film ===

        //*********************************************************************

        #region === Eject Card ===

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

            SDK.Return SDKReturn = SDK.ID_EjectCard(hSession);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("EjectCard", SDKReturn);
            }
            else
            {
                WaitForPrinterToFinish();
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Eject Card ===

        //*********************************************************************

        #region === Flip Card ===

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

            SDK.Return SDKReturn = SDK.ID_FlipCard(hSession);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("FlipCard", SDKReturn);
            }
            else
            {
                WaitForPrinterToFinish();
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Flip Card ===

        //*********************************************************************

        #region === Clean Printer ===

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

            SDK.Return SDKReturn = SDK.ID_CleanPrinter(hSession);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("CleanPrinter", SDKReturn);
            }
            else
            {
                WaitForPrinterToFinish();
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Clean Printer ===

        //*********************************************************************

        #region === Restart Printer ===

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

            SDK.Return SDKReturn = SDK.ID_RestartPrinter(hSession);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("RestartPrinter", SDKReturn);
            }
            else
            {
                WaitForPrinterToFinish();
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Restart Printer ===

        //*********************************************************************

        #region === Print Test Card ===

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

            SDK.Return SDKReturn;

            if (printerType == SDK.PrinterType.Generation2)
            {
                //Call SDK to Prepare to Print a Test Card
                SDKReturn = SDK.ID_PrepareForPrint(hSession);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("PrintTestCardPrepare", SDKReturn);
                }
            }

			else
			{
	            SDKReturn = SDK.ID_PrintTestCard(hSession);
	            if (SDKReturn != SDK.Return.Success)
	            {
	                HandleError("PrintTestCard", SDKReturn);
	            }
	            else
	            {
                    if (printerType == SDK.PrinterType.Generation2)
	                {
	                    SDKReturn = SDK.ID_WaitPrintComplete(hSession);
	                    if (SDKReturn != SDK.Return.Success)
	                    {
	                        HandleError("PrintTestCardComplete", SDKReturn);
	                    }
	                }
	                else
	                {
	                    WaitForPrinterToFinish();
	                }
	            }
	        }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Print Test Card ===

        //*********************************************************************

        #region === Erase Card ===

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

            SDK.Return SDKReturn = SDK.ID_EraseCard(hSession,
                                                    decimal.ToInt32(EraseCount.Value),
                                                    decimal.ToInt32(EraseArea_BotLXBox.Value),
                                                    decimal.ToInt32(EraseArea_BotLYBox.Value),
                                                    decimal.ToInt32(EraseArea_TopRXBox.Value),
                                                    decimal.ToInt32(EraseArea_TopRYBox.Value));
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("Erasecard", SDKReturn);
            }
            else
            {
                WaitForPrinterToFinish();
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Erase Card ===

        //*********************************************************************

        #region === Hand Feed ===

        Dictionary<SDK.HandFeed, string> handfeedkp = new Dictionary<SDK.HandFeed, string>()
        {
            {SDK.HandFeed.On,  "On" },  
            {SDK.HandFeed.Off, "Off"}, 
        };

        private void InitHandFeedCombo()
        {
            HandFeedCombo.DataSource = new BindingSource(handfeedkp, null);
            HandFeedCombo.DisplayMember = "Value";
        }

        private void HandFeedToMsgBox(SDK.Action Action, SDK.HandFeed mode)
        {
            string sep = Separator(Action);
            PrinterMsgBox.AppendText("Hand Feed" + sep + handfeedkp[mode] + Environment.NewLine);
            PrinterMsgBox.AppendText(Environment.NewLine);
        }

        private void SetHandFeedCombo(SDK.HandFeed mode)
        {
            HandFeedCombo.Text = handfeedkp[mode];
        }

        private SDK.Return GetHandFeed(ref SDK.HandFeed Mode)
        {
            SDK.Return SDKReturn = SDK.ID_HandFeed(hSession, SDK.Action.Read, ref Mode);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("GetHandFeed", SDKReturn);
            }
            return SDKReturn;
        }

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

            SDK.HandFeed mode = ((KeyValuePair<SDK.HandFeed, string>)HandFeedCombo.SelectedItem).Key;

            if (PrinterActionIsGet())
            {
                if (GetHandFeed(ref mode) == SDK.Return.Success)
                {
                    SetHandFeedCombo(mode);
                    HandFeedToMsgBox(SDK.Action.Read, mode);
                }
            }
            else
            {
                SDK.Return SDKReturn = SDK.ID_HandFeed(hSession, SDK.Action.Write, ref mode);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetHandFeed", SDKReturn);
                }
                else
                {
                    HandFeedToMsgBox(SDK.Action.Write, mode);
                }
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Hand Feed ===

        //*********************************************************************

        #region === Eject Mode ===

        Dictionary<SDK.EjectMode, string> ejectmodekp = new Dictionary<SDK.EjectMode, string>()
        {
            {SDK.EjectMode.Off, "Off"}, 
            {SDK.EjectMode.On,  "On" },  
        };

        private void InitEjectModeCombo()
        {
            EjectModeCombo.DataSource = new BindingSource(ejectmodekp, null);
            EjectModeCombo.DisplayMember = "Value";
        }

        private void EjectModeToMsgBox(SDK.Action Action, SDK.EjectMode mode)
        {
            PrinterMsgBox.AppendText("Eject Mode"
                                     + Separator(Action)
                                     + ejectmodekp[mode] 
                                     + Environment.NewLine);
            PrinterMsgBox.AppendText(Environment.NewLine);
        }

        private void SetEjectModeCombo(SDK.EjectMode mode) 
        {
            EjectModeCombo.Text = ejectmodekp[mode]; 
        }

        private SDK.Return GetEjectMode(ref SDK.EjectMode mode)
        {
            SDK.Return SDKReturn = SDK.ID_EjectMode(hSession, SDK.Action.Read, ref mode);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("GetEjectMode", SDKReturn);
            }
            return SDKReturn;
        }

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

            SDK.EjectMode mode = ((KeyValuePair<SDK.EjectMode, string>)EjectModeCombo.SelectedItem).Key;

            if (PrinterActionIsGet())
            {
                if (GetEjectMode(ref mode) == SDK.Return.Success)
                {
                    SetEjectModeCombo(mode);
                    EjectModeToMsgBox(SDK.Action.Read, mode);
                }
            }
            else
            {
                SDK.Return SDKReturn = SDK.ID_EjectMode(hSession, SDK.Action.Write, ref mode);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetEjectMode", SDKReturn);
                }
                else
                {
                    EjectModeToMsgBox(SDK.Action.Write, mode);
                }
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Eject Mode ===

        //*********************************************************************

        #region === Horizontal Eject Mode ===

        Dictionary<SDK.HorzEject, string> horzejectkp = new Dictionary<SDK.HorzEject, string>()
        {
            {SDK.HorzEject.On,  "On" },  
            {SDK.HorzEject.Off, "Off"}, 
        };

        private void InitHorzEjectCombo()
        {
            HorzEjectCombo.DataSource = new BindingSource(horzejectkp, null);
            HorzEjectCombo.DisplayMember = "Value";
        }

        private void HorzEjectToMsgBox(SDK.Action Action, SDK.HorzEject mode)
        {
            string sep = Separator(Action);
            PrinterMsgBox.AppendText("HorzEject" + sep + horzejectkp[mode] + Environment.NewLine);
            PrinterMsgBox.AppendText(Environment.NewLine);
        }

        private void SetHorzEjectCombo(SDK.HorzEject mode) 
        {
            HorzEjectCombo.Text = horzejectkp[mode]; 
        }

        private SDK.Return GetHorzEject(ref SDK.HorzEject mode)
        {
            SDK.Return SDKReturn = SDK.ID_HorzEject(hSession, SDK.Action.Read, ref mode);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("HorzEject", SDKReturn);
            }
            return SDKReturn;
        }

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

            SDK.HorzEject mode = ((KeyValuePair<SDK.HorzEject, string>)HorzEjectCombo.SelectedItem).Key;

            if (PrinterActionIsGet())
            {
                if (GetHorzEject(ref mode) == SDK.Return.Success)
                {
                    SetHorzEjectCombo(mode);
                    HorzEjectToMsgBox(SDK.Action.Read, mode);
                }
            }
            else
            {
                SDK.Return SDKReturn = SDK.ID_HorzEject(hSession, SDK.Action.Write, ref mode);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetHorzEject", SDKReturn);
                }
                else
                {
                    HorzEjectToMsgBox(SDK.Action.Write, mode);
                }
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Horizontal Eject Mode ===

        //*********************************************************************

        #region === Smart Mode ===

        Dictionary<SDK.SmartMode, string> smartmodekp = new Dictionary<SDK.SmartMode, string>()
        {
            {SDK.SmartMode.Default, "Default"}, 
            {SDK.SmartMode.Platen,  "Platen"},  
            {SDK.SmartMode.XLI,     "XLI"},  
        };

        private void InitSmartModeCombo()
        {
            SmartModeCombo.DataSource = new BindingSource(smartmodekp, null);
            SmartModeCombo.DisplayMember = "Value";
        }

        private void SmartModeToMsgBox(SDK.Action Action, SDK.SmartMode mode)
        {
            string sep = Separator(Action);
            PrinterMsgBox.AppendText("Smart Mode" + sep + smartmodekp[mode] + Environment.NewLine);
            PrinterMsgBox.AppendText(Environment.NewLine);
        }

        private void SetSmartModeCombo(SDK.SmartMode mode) 
        {
            SmartModeCombo.Text = smartmodekp[mode]; 
        }

        private SDK.Return GetSmartMode(ref SDK.SmartMode Mode)
        {
            SDK.Return SDKReturn = SDK.ID_SmartMode(hSession, SDK.Action.Read, ref Mode);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("GetSmartMode", SDKReturn);
            }
            return SDKReturn;
        }

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

            SDK.SmartMode mode = ((KeyValuePair<SDK.SmartMode, string>)SmartModeCombo.SelectedItem).Key;

            if (PrinterActionIsGet())
            {
                if (GetSmartMode(ref mode) == SDK.Return.Success)
                {
                    SetSmartModeCombo(mode);
                    SmartModeToMsgBox(SDK.Action.Read, mode);
                }
            }
            else
            {
                SDK.Return SDKReturn = SDK.ID_SmartMode(hSession, SDK.Action.Write, ref mode);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetSmartMode", SDKReturn);
                }
                else
                {
                    SmartModeToMsgBox(SDK.Action.Write, mode);
                }
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Smart Mode ===

        //*********************************************************************

        #region === Smart Offset ===

        private SDK.Return GetSmartOffset(ref byte Offset)
        {
            SDK.Return SDKReturn = SDK.ID_SmartOffset(hSession, SDK.Action.Read, ref Offset);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("GetSmartOffset", SDKReturn);
            }
            return SDKReturn;
        }

        private void SmartOffsetToMsgBox(SDK.Action Action, byte offset)
        {
            string sep = Separator(Action);
            PrinterMsgBox.AppendText("Smart Offset" + sep + offset + Environment.NewLine);
            PrinterMsgBox.AppendText(Environment.NewLine);
        }

        private void SetSmartOffset(int Offset) 
        { 
            SmartOffsetBox.Value = Offset; 
        }

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

            byte Offset = decimal.ToByte(SmartOffsetBox.Value);

            if (PrinterActionIsGet())
            {
                if (GetSmartOffset(ref Offset) == SDK.Return.Success)
                {
                    SetSmartOffset(Offset);
                    SmartOffsetToMsgBox(SDK.Action.Read, Offset);
                }
            }
            else
            {
                SDK.Return SDKReturn = SDK.ID_SmartOffset(hSession, SDK.Action.Write, ref Offset);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetSmartOffset", SDKReturn);
                }

                else
                {
                    SmartOffsetToMsgBox(SDK.Action.Write, Offset);
                }
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Smart Offset ===

        //*********************************************************************

        #region === Erase Speed ===

        Dictionary<SDK.EraseSpeed, string> erasespeedkp = new Dictionary<SDK.EraseSpeed, string>()
        {
            {SDK.EraseSpeed.Thorough, "Thorough"}, 
            {SDK.EraseSpeed.Quick,    "Quick"},    
        };

        private void InitEraseSpeedCombo()
        {
            EraseSpeedCombo.DataSource = new BindingSource(erasespeedkp, null);
            EraseSpeedCombo.DisplayMember = "Value";
        }

        private void EraseSpeedToMsgBox(SDK.Action Action, SDK.EraseSpeed speed)
        {
            string sep = Separator(Action);
            PrinterMsgBox.AppendText("Erase Speed" + sep + erasespeedkp[speed] + Environment.NewLine);
            PrinterMsgBox.AppendText(Environment.NewLine);
        }

        private void SetEraseSpeedCombo(SDK.EraseSpeed speed) 
        {
            EraseSpeedCombo.Text = erasespeedkp[speed]; 
        }

        private SDK.Return GetEraseSpeed(ref SDK.EraseSpeed Speed)
        {
            SDK.Return SDKReturn = SDK.ID_EraseSpeed(hSession, SDK.Action.Read, ref Speed);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("GetEraseSpeed", SDKReturn);
            }
            return SDKReturn;
        }

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

            SDK.EraseSpeed speed = ((KeyValuePair<SDK.EraseSpeed, string>)EraseSpeedCombo.SelectedItem).Key;

            if (PrinterActionIsGet())
            {
                if (GetEraseSpeed(ref speed) == SDK.Return.Success)
                {
                    SetEraseSpeedCombo(speed);
                    EraseSpeedToMsgBox(SDK.Action.Read, speed);
                }
            }
            else
            {
                SDK.Return SDKReturn = SDK.ID_EraseSpeed(hSession, SDK.Action.Write, ref speed);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetEraseSpeed", SDKReturn);
                }
                else
                {
                    EraseSpeedToMsgBox(SDK.Action.Write, speed);
                }
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === Erase Speed ===

        //*********************************************************************

        #region === IP Settings ===

        Dictionary<SDK.IPMode, string> ipaddresskp = new Dictionary<SDK.IPMode, string>()
        {
            {SDK.IPMode.Dynamic, "Dynamic"}, 
            {SDK.IPMode.Static,  "Static"},    
        };

        private void InitIPModeCombo()
        {
            IPModeCombo.DataSource    = new BindingSource(ipaddresskp, null);
            IPModeCombo.DisplayMember = "Value";
        }

        private string IntToIPAddressString(int value) 
        {
            var temp = IPAddress.HostToNetworkOrder(value);
            return new IPAddress(BitConverter.GetBytes(temp)).ToString();
        }

        private int IPAddressStringToInt(string IPAddr)
        {
            return IPAddress.NetworkToHostOrder(BitConverter.ToInt32(IPAddress.Parse(IPAddr).GetAddressBytes(), 0));
        }

        private void IPSettingsToMsgBox(SDK.Action Action, SDK.IPData settings)
        {
            string sep = Separator(Action);
            PrinterMsgBox.AppendText("Address Mode: " + ipaddresskp[settings.Mode] + Environment.NewLine);
            PrinterMsgBox.AppendText("IP Address"  + sep + IntToIPAddressString(settings.Address) + Environment.NewLine);
            PrinterMsgBox.AppendText("Subnet Mask" + sep + IntToIPAddressString(settings.Subnet)  + Environment.NewLine);
            PrinterMsgBox.AppendText("Gateway"     + sep + IntToIPAddressString(settings.Gateway) + Environment.NewLine);
            PrinterMsgBox.AppendText(Environment.NewLine);
        }

        private void IPSettingsToCtrl(SDK.IPData settings)
        {
            IPModeCombo.Text  = ipaddresskp[settings.Mode];
            IPAddressBox.Text = IntToIPAddressString(settings.Address);
            IPSubnetBox.Text  = IntToIPAddressString(settings.Subnet);
            IPGatewayBox.Text = IntToIPAddressString(settings.Gateway);
        }

        private SDK.Return GetIPSettings(ref SDK.IPData settings)
        {
            SDK.Return SDKReturn = SDK.ID_IPSettings(hSession, SDK.Action.Read, settings);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("GetIPSettings", SDKReturn);
            }
            return SDKReturn;
        }

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

            SDK.IPData settings = new SDK.IPData();

            if (PrinterActionIsGet())
            {
                if (GetIPSettings(ref settings) == SDK.Return.Success)
                {
                    IPSettingsToMsgBox(SDK.Action.Read, settings);
                    IPSettingsToCtrl(settings);
                }
            }
            else
            {
                GetIPSettings(ref settings);
                settings.Mode    = ((KeyValuePair<SDK.IPMode, string>)IPModeCombo.SelectedItem).Key;
                settings.Address = IPAddressStringToInt(IPAddressBox.Text);
                settings.Subnet  = IPAddressStringToInt(IPSubnetBox.Text);
                settings.Gateway = IPAddressStringToInt(IPGatewayBox.Text);

                SDK.Return SDKReturn = SDK.ID_IPSettings(hSession, SDK.Action.Write, settings);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetEraseSpeed", SDKReturn);
                }
                else
                {
                    IPSettingsToMsgBox(SDK.Action.Write, settings);
                }
            }

            Cursor.Current = Cursors.Default;
        }

        #endregion === IP Settings ===

        //*********************************************************************

        #region === Card Location ===

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

            SDK.CardLocation location = new SDK.CardLocation();
            SDK.Return SDKReturn = SDK.ID_CardLocation(hSession, ref location);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("CardLocation", SDKReturn);
            }

            else
            {
                string temp_string;
                switch (location)
                {
                case SDK.CardLocation.Unknown:    temp_string = "Unknown"; break;
                case SDK.CardLocation.NoCard:     temp_string = "No Card"; break;
                case SDK.CardLocation.PrintReady: temp_string = "Standby"; break;
                case SDK.CardLocation.Encoder:    temp_string = "Encoder"; break;
                default:                          temp_string = "?????";   break;
                }
                PrinterMsgBox.AppendText("Card Location: " + temp_string + Environment.NewLine);
                PrinterMsgBox.AppendText(Environment.NewLine);
            }
            
            Cursor.Current = Cursors.Default;
        }

        #endregion === Card Location ===

    }
}
