/***************************************************************************/
/**                                                                       **/
/**                               MAGICARD                                **/
/**                                                                       **/
/***************************************************************************/
/**                                                                       **/
/**  PROJECT      : SDK C# Demo - Ultima Printers                         **/
/**                                                                       **/
/**  MODULE NAME  : Driver2.cs                                            **/
/**                                                                       **/
/**  COPYRIGHT    : Magicard                                              **/
/**                                                                       **/
/***************************************************************************/
using System;
using System.Text;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
using SDKShim;

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

        private void InitDriver2Tab()
        {
            InitPrintSettings();
            InitCardSettings();
            InitHoloKote();
            InitHoloKoteID();
            InitColourAdjust();
        }

        #endregion === Initialisation

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

        #region === Local Methods ===

        private void Driver2Controls(bool control)
        {
            DuplexCombo.Enabled             = control;
            CardSizeCombo.Enabled           = control;
            CopyCountUpDown.Enabled         = control;
            ColourFormatCombo.Enabled       = control;
            OrientationCombo.Enabled        = control;
            Overcoat.Enabled                = control;
            Rotate.Enabled                  = control;
            HoloKoteImageUpDown.Enabled     = control;
            HoloKoteRotationCombo.Enabled   = control;

            HoloKoteIDSlot.Enabled          = !control;
            HoloKoteIDButton.Enabled        = !control;

            ColourAdjust_Contrast.Enabled   = control;
            ColourAdjust_Brightness.Enabled = control;
            ColourAdjust_Colour.Enabled     = control;
            ColourAdjust_Tint.Enabled       = control;
            ColourAdjust_Red.Enabled        = control;
            ColourAdjust_Green.Enabled      = control;
            ColourAdjust_Blue.Enabled       = control;
            ColourAdjust_Negative.Enabled   = control;
            ColourAdjust_DarkPic.Enabled    = control;
            ColourAdjust_Illuminant.Enabled = control;
            ColourAdjust_BlackRef.Enabled   = control;
            ColourAdjust_WhiteRef.Enabled   = control;
        }

        private bool Driver2ActionIsGet()
        {
            return Driver2GetRadio.Checked;
        }

        private void Driver2ActionGetRadio_CheckedChanged(object sender, EventArgs e)
        {
            Driver2Controls(false);
        }

        private void Driver2ActionSetRadio_CheckedChanged(object sender, EventArgs e)
        {
            Driver2Controls(true);
        }

        private void ClearDriver2MsgBoxButton_Click(object sender, EventArgs e)
        {
            Driver2MsgBox.Clear();
        }

        #endregion === Local Methods ===

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

        #region === Print Settings ===

        Dictionary<SDK.Duplex, string> duplexkp = new Dictionary<SDK.Duplex, string>()
        {
            {SDK.Duplex.FrontOnly, "Front Only"},
            {SDK.Duplex.Both,      "Both Sides"},
            {SDK.Duplex.BackOnly,  "Back Only"},
        };

        Dictionary<int, string> cardsizekp = new Dictionary<int, string>();

        private void InitPrintSettings()
        {
            DuplexCombo.DataSource    = new BindingSource(duplexkp, null);
            DuplexCombo.DisplayMember = "Value";
            DuplexCombo.ValueMember   = "Key";
        }

        private SDK.Return GetPrintSettings(ref SDK.PrintSetting settings)
        {
            SDK.Return SDKReturn = SDK.ID_PrintSettings(hSession, SDK.Action.Read, settings);
            if (SDKReturn == SDK.Return.Success)
            {
                SetPrintSettings(settings);
            }
            else
            {
                HandleError("GetPrintSettings", SDKReturn);
            }
            return SDKReturn;
        }

        private void PrintSettingsToMsgBox(SDK.Action action, SDK.PrintSetting settings)
        {
            string sep = Separator(action);
            Driver2MsgBox.AppendText("Print Settings:" + Environment.NewLine);
            Driver2MsgBox.AppendText("Duplex"     + sep + duplexkp[settings.Duplex] + Environment.NewLine);
            Driver2MsgBox.AppendText("Copy Count" + sep + settings.CopyCount        + Environment.NewLine);
            Driver2MsgBox.AppendText("Card Size"  + sep + cardsizekp[settings.CardSize]);
            Driver2MsgBox.AppendText(Environment.NewLine + Environment.NewLine);
        }

        private void SetPrintSettings(SDK.PrintSetting settings)
        {
            DuplexCombo.Text      = duplexkp[settings.Duplex];
            CopyCountUpDown.Value = settings.CopyCount;
            CardSizeCombo.Text    = cardsizekp[settings.CardSize];
        }

        private void PrintSettingsButton_Click(object sender, EventArgs e)
        {
            SDK.PrintSetting settings = new SDK.PrintSetting();

            if (Driver2ActionIsGet())
            {
                if (GetPrintSettings(ref settings) == SDK.Return.Success)
                {
                    PrintSettingsToMsgBox(SDK.Action.Read, settings);
                }
            }
            else
            {
                settings.Duplex    = ((KeyValuePair<SDK.Duplex, string>)DuplexCombo.SelectedItem).Key;
                settings.CopyCount = decimal.ToByte(CopyCountUpDown.Value);
                settings.CardSize  = ((KeyValuePair<int, string>)CardSizeCombo.SelectedItem).Key;

                SDK.Return SDKReturn = SDK.ID_PrintSettings(hSession, SDK.Action.Write, settings);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetPrintSettings", SDKReturn);
                }
                else
                {
                    PrintSettingsToMsgBox(SDK.Action.Write, settings);
                }
            }
        }

        #endregion === Print Settings ===

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

        #region === Card Settings ===

        Dictionary<SDK.ColourFormat, string> colourkp = new Dictionary<SDK.ColourFormat, string>()
        {
            {SDK.ColourFormat.YMC,  "YMC"},   
            {SDK.ColourFormat.YMCK, "YMCK"},  
            {SDK.ColourFormat.K,    "K-Resin"}
        };

        Dictionary<SDK.Orientation, string> orientkp = new Dictionary<SDK.Orientation, string>()
        {
            {SDK.Orientation.Landscape, "Landscape"},
            {SDK.Orientation.Portrait,  "Portrait"}
        };

        private void InitCardSettings()
        {
            ColourFormatCombo.DataSource    = new BindingSource(colourkp, null);
            ColourFormatCombo.DisplayMember = "Value";

            OrientationCombo.DataSource    = new BindingSource(orientkp, null);
            OrientationCombo.DisplayMember = "Value";
        }

        private void CardSettingsSide_Changed(object sender, EventArgs e)
        {
            SDK.CardSetting settings = new SDK.CardSetting();
            SDK.Return SDKReturn = GetCardSettings(((KeyValuePair<SDK.Side, string>)CardSettingsSideCombo.SelectedItem).Key,
                                                      ref settings);
            if (SDKReturn == SDK.Return.Success)
            {
                SetCardSettings(settings);
            }
        }

        private SDK.Return GetCardSettings(SDK.Side side, ref SDK.CardSetting settings)
        {
            SDK.Return SDKReturn = SDK.ID_CardSettings(hSession, SDK.Action.Read, side, settings);
            if (SDKReturn == SDK.Return.Success)
            {
                SetCardSettings(settings);
            }
            else
            {
                HandleError("GetCardSettings", SDKReturn);
            }
            return SDKReturn;
        }

        private void CardSettingsToMsgBox(SDK.Action action, SDK.Side side, SDK.CardSetting settings)
        {
            string sep = Separator(action);
            Driver2MsgBox.AppendText("Card Settings (" + sidekp[side] + "):" + Environment.NewLine);
            Driver2MsgBox.AppendText("Colour Format" + sep + colourkp[settings.ColourFormat] + Environment.NewLine);
            Driver2MsgBox.AppendText("Orientation"   + sep + orientkp[settings.Orientation]  + Environment.NewLine);
            Driver2MsgBox.AppendText("Overcoat"      + sep + Overcoat.Checked.ToString()     + Environment.NewLine);
            Driver2MsgBox.AppendText("Rotate"        + sep + Rotate.Checked.ToString()       + Environment.NewLine);
            Driver2MsgBox.AppendText(Environment.NewLine);
        }

        private void SetCardSettings(SDK.CardSetting settings)
        {
            ColourFormatCombo.Text = colourkp[settings.ColourFormat];
            OrientationCombo.Text  = orientkp[settings.Orientation];
            Overcoat.Checked     = settings.Overcoat;
            Rotate.Checked       = settings.Rotation;
        }

        private void CardSettingsButton_Click(object sender, EventArgs e)
        {
            SDK.CardSetting settings = new SDK.CardSetting();
            SDK.Side side = ((KeyValuePair<SDK.Side, string>)CardSettingsSideCombo.SelectedItem).Key;

            if (Driver2ActionIsGet())
            {
                if (GetCardSettings(side, ref settings) == SDK.Return.Success)
                {
                    CardSettingsToMsgBox(SDK.Action.Read, side, settings);
                }
            }
            else
            {
                settings.ColourFormat = ((KeyValuePair<SDK.ColourFormat, string>)ColourFormatCombo.SelectedItem).Key;
                settings.Orientation  = ((KeyValuePair<SDK.Orientation, string>)OrientationCombo.SelectedItem).Key;
                settings.Overcoat     = Overcoat.Checked;
                settings.Rotation     = Rotate.Checked;

                SDK.Return SDKReturn = SDK.ID_CardSettings(hSession, SDK.Action.Write, side, settings);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetCardSettings", SDKReturn);
                }
                else
                {
                    CardSettingsToMsgBox(SDK.Action.Write, side, settings);
                }
            }
        }

        #endregion === Card Settings ===

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

        #region === HoloKote Settings ===

        Dictionary<SDK.Rotation, string> hkrotatekp = new Dictionary<SDK.Rotation, string>()
        {
            {SDK.Rotation.None,        "None"},
            {SDK.Rotation.Degrees_90,  "90 Degrees"},
            {SDK.Rotation.Degrees_180, "180 Degrees"},
            {SDK.Rotation.Degrees_270, "270 Degrees"},
        };
        
        private void InitHoloKote()
        {
            HoloKoteRotationCombo.DataSource = new BindingSource(hkrotatekp, null);
            HoloKoteRotationCombo.DisplayMember = "Value";
            HoloKoteRotationCombo.ValueMember   = "Key";
        }

        private void HoloKoteSide_Changed(object sender, EventArgs e)
        {
            SDK.HoloKote HoloKote = new SDK.HoloKote();
            SDK.Return SDKReturn = GetHoloKote(((KeyValuePair<SDK.Side, string>)HoloKoteSideCombo.SelectedItem).Key,
                                                  ref HoloKote);
            if (SDKReturn == SDK.Return.Success)
            {
                SetHoloKote(HoloKote);
            }
        }

        private SDK.Return GetHoloKote(SDK.Side side, ref SDK.HoloKote holokote)
        {
            SDK.Return SDKReturn = SDK.ID_HoloKote(hSession, SDK.Action.Read, side, holokote);
            if (SDKReturn == SDK.Return.Success)
            {
                SetHoloKote(holokote);
            }
            else
            {
                HandleError("GetHoloKote", SDKReturn);
            }
            return SDKReturn;
        }

        private void HoloKoteToMsgBox(SDK.Action action, SDK.Side side, SDK.HoloKote holokote)
        {
            string sep = Separator(action);
            Driver2MsgBox.AppendText("HoloKote (" + sidekp[side] + "): " + Environment.NewLine);
            Driver2MsgBox.AppendText("Image ID"           + sep + holokote.ImageID                     + Environment.NewLine);
            Driver2MsgBox.AppendText("Rotate"             + sep + hkrotatekp[holokote.Rotation]        + Environment.NewLine);
            Driver2MsgBox.AppendText(Environment.NewLine);
        }

        private void SetHoloKote(SDK.HoloKote holokote)
        {
            HoloKoteImageUpDown.Value  = holokote.ImageID;
            HoloKoteRotationCombo.Text = hkrotatekp[holokote.Rotation];
        }

        private void HoloKoteButton_Click(object sender, EventArgs e)
        {
            SDK.HoloKote holokote = new SDK.HoloKote();
            SDK.Side side = ((KeyValuePair<SDK.Side, string>)HoloKoteSideCombo.SelectedItem).Key;

            if (Driver2ActionIsGet())
            {
                if (GetHoloKote(side, ref holokote) == SDK.Return.Success)
                {
                    HoloKoteToMsgBox(SDK.Action.Read, side, holokote);
                }
            }
            else
            {
                holokote.ImageID = decimal.ToByte(HoloKoteImageUpDown.Value);
                holokote.Rotation = ((KeyValuePair<SDK.Rotation, string>)HoloKoteRotationCombo.SelectedItem).Key;

                SDK.Return SDKReturn = SDK.ID_HoloKote(hSession, SDK.Action.Write, side, holokote);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("GetHoloKote", SDKReturn);
                }
                else
                {
                    HoloKoteToMsgBox(SDK.Action.Write, side, holokote);
                }
            }
        }

        #endregion === HoloKote Settings ===

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

        #region === HoloKote ID ===

        private void InitHoloKoteID()
        {
            HoloKoteIDSlot.SelectedIndex = 0;
        }

        private void HoloKoteIDButton_Click(object sender, EventArgs e)
        {
            StringBuilder IDString = new StringBuilder();
            byte slotNo = (byte)HoloKoteIDSlot.SelectedIndex;
            SDK.Return SDKReturn = SDK.ID_HoloKoteIdentity(hSession, slotNo, IDString);
            if (SDKReturn != SDK.Return.Success)
            {
                HandleError("HoloKoteIDs", SDKReturn);
            }
            else
            {
                String temp_string;
                if (HoloKoteIDSlot.SelectedIndex == 0)
                {
                    Driver2MsgBox.AppendText("HoloKote IDs: " + Environment.NewLine);

                    string[] IDs = IDString.ToString().Split(',');
                    int i = 1;
                    foreach (string identity in IDs)
                    {
                        temp_string = i.ToString();
                        temp_string += ": " + identity;
                        temp_string += Environment.NewLine;
                        Driver2MsgBox.AppendText(temp_string);
                        i++;
                    }
                }
                else
                {
                    temp_string = "HoloKote ID ";
                    temp_string += HoloKoteIDSlot.SelectedIndex.ToString();
                    temp_string += ": " + IDString;
                    temp_string += Environment.NewLine;
                    Driver2MsgBox.AppendText(temp_string);
                }
                Driver2MsgBox.AppendText(Environment.NewLine);
            }
        }

        #endregion === HoloKote ID ===

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

        #region === Colour Adjust Settings ===
        Dictionary<SDK.Illuminant, string> illuminantkp = new Dictionary<SDK.Illuminant, string>()
        {
            {SDK.Illuminant.DEFAULT, "Default"},
            {SDK.Illuminant.A,       "Tungsten Lamp"},
            {SDK.Illuminant.B,       "Noon Sunlight"},
            {SDK.Illuminant.C,       "NTSC Sunlight"},
            {SDK.Illuminant.D50,     "Normal Print"},
            {SDK.Illuminant.D55,     "Bond Paper Print"},
            {SDK.Illuminant.D65,     "Standard Daylight"},
            {SDK.Illuminant.D75,     "Northern Daylight"},
            {SDK.Illuminant.F2,      "Cool White Lamp"},
        };
        
        private void InitColourAdjust()
        {
            ColourAdjust_Illuminant.DataSource = new BindingSource(illuminantkp, null);
            ColourAdjust_Illuminant.DisplayMember = "Value";
            ColourAdjust_Illuminant.ValueMember   = "Key";
        }

        private void ColourAdjToMsgBox(SDK.Action action, SDK.ColorAdjustment ca)
        {
            string sep = Separator(action);
            Driver2MsgBox.AppendText("Contrast"         + sep + ca.Contrast     + Environment.NewLine);
	        Driver2MsgBox.AppendText("Brightness"       + sep + ca.Brightness   + Environment.NewLine);
	        Driver2MsgBox.AppendText("Colorfulness"     + sep + ca.Colorfulness + Environment.NewLine);
	        Driver2MsgBox.AppendText("Red Green Tint"   + sep + ca.RedGreenTint + Environment.NewLine);
	        Driver2MsgBox.AppendText("Red Gamma"        + sep + ca.RedGamma     + Environment.NewLine);
	        Driver2MsgBox.AppendText("Green Gamma"      + sep + ca.GreenGamma   + Environment.NewLine);
	        Driver2MsgBox.AppendText("Blue Gamma"       + sep + ca.BlueGamma    + Environment.NewLine);
 	        Driver2MsgBox.AppendText("Illuminant Index" + sep + illuminantkp[ca.IlluminantIndex] + Environment.NewLine);
 	        Driver2MsgBox.AppendText("Dark Picture"    
                                     + sep 
                                     + (ca.Flags.HasFlag(SDK.CAFlags.LogFilter) ? "On" : "Off")
                                     + Environment.NewLine);
 	        Driver2MsgBox.AppendText("Negative"        
                                     + sep 
                                     + (ca.Flags.HasFlag(SDK.CAFlags.Negative) ? "On" : "Off")
                                     + Environment.NewLine);
	        Driver2MsgBox.AppendText("Reference Black"  + sep + ca.ReferenceBlack + Environment.NewLine);
	        Driver2MsgBox.AppendText("Reference White"  + sep + ca.ReferenceWhite + Environment.NewLine);
            Driver2MsgBox.AppendText(Environment.NewLine);
        }

        private void SetColourAdjust(SDK.ColorAdjustment ca) 
        {
	        ColourAdjust_Red.Value        = ca.RedGamma;
	        ColourAdjust_Green.Value      = ca.GreenGamma;
	        ColourAdjust_Blue.Value       = ca.BlueGamma;
	        ColourAdjust_BlackRef.Value   = ca.ReferenceBlack;
	        ColourAdjust_WhiteRef.Value   = ca.ReferenceWhite;
	        ColourAdjust_Contrast.Value   = ca.Contrast;
	        ColourAdjust_Brightness.Value = ca.Brightness;
	        ColourAdjust_Colour.Value     = ca.Colorfulness;
	        ColourAdjust_Tint.Value       = ca.RedGreenTint;

            ColourAdjust_Negative.Checked = ca.Flags.HasFlag(SDK.CAFlags.Negative);
            ColourAdjust_DarkPic.Checked  = ca.Flags.HasFlag(SDK.CAFlags.LogFilter);

            ColourAdjust_Illuminant.Text  = illuminantkp[ca.IlluminantIndex];
        }

        private SDK.Return GetColourAdjust(ref SDK.ColorAdjustment ca)
        {
            SDK.Return SDKReturn = SDK.ID_ColourAdjust(hSession, SDK.Action.Read, ca);
            if (SDKReturn == SDK.Return.Success)
            {
                SetColourAdjust(ca);
            }
            else
            {
                HandleError("GetColourAdjust", SDKReturn);
            }
            return SDKReturn;
        }

        private void ColourAdjustBtn_Click(object sender, EventArgs e)
        {
	        SDK.ColorAdjustment ca = new SDK.ColorAdjustment();
	
            if (Driver2ActionIsGet())
            {
                if (GetColourAdjust(ref ca) == SDK.Return.Success)
		        {
                    ColourAdjToMsgBox(SDK.Action.Read, ca);
		        }
	        }

	        else
	        {
                ca.Size         = (UInt16)Marshal.SizeOf(ca);
                ca.Contrast     = decimal.ToInt16(ColourAdjust_Contrast.Value);
                ca.Brightness   = decimal.ToInt16(ColourAdjust_Brightness.Value);
                ca.Colorfulness = decimal.ToInt16(ColourAdjust_Colour.Value);
                ca.RedGreenTint = decimal.ToInt16(ColourAdjust_Tint.Value);
                ca.RedGamma     = decimal.ToUInt16(ColourAdjust_Red.Value);
                ca.GreenGamma   = decimal.ToUInt16(ColourAdjust_Green.Value);
                ca.BlueGamma    = decimal.ToUInt16(ColourAdjust_Blue.Value);
                ca.Flags = 0;
                if (ColourAdjust_Negative.Checked) ca.Flags |= SDK.CAFlags.Negative;
                if (ColourAdjust_DarkPic.Checked) ca.Flags  |= SDK.CAFlags.LogFilter;
                ca.IlluminantIndex = ((KeyValuePair<SDK.Illuminant, string>)ColourAdjust_Illuminant.SelectedItem).Key;
                ca.ReferenceBlack = decimal.ToUInt16(ColourAdjust_BlackRef.Value);
                ca.ReferenceWhite = decimal.ToUInt16(ColourAdjust_WhiteRef.Value);

			    //Call the SDK to write to the driver
                SDK.Return SDKReturn = SDK.ID_ColourAdjust(hSession, SDK.Action.Write, ca);
			    if (SDKReturn != SDK.Return.Success)
			    {
				    HandleError("SetColourAdjust", SDKReturn);
			    }
			    else
			    {
				    //Update the message box
                    ColourAdjToMsgBox(SDK.Action.Write, ca);
			    }
	        }
        }

        #endregion === Colour Adjust Settings ===

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

        #region === HoloKote Preview ===

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

            int maxHoloKotes = SDK.ID_HoloKoteCount(hSession);
            Bitmap[] buff = new Bitmap[maxHoloKotes];
            for (int i = 0; i < maxHoloKotes; i++)
            {
                buff[i] = new Bitmap(SDK.PreviewWidth, SDK.PreviewHeight, PixelFormat.Format1bppIndexed);
            }

            SDK.Return SDKReturn = SDK.ID_HoloKotePreview(hSession, buff);
            if (SDKReturn != SDK.Return.Success)
			{
				HandleError("HolokotePreview", SDKReturn);
			}
		    else
		    {
                var preview = new HKPreview(buff, maxHoloKotes);
                preview.Show();
		    }

            Cursor.Current = Cursors.Default;
        }

        #endregion === HoloKote Preview ===
    }
}
