/***************************************************************************/
/**                                                                       **/
/**                               MAGICARD                                **/
/**                                                                       **/
/***************************************************************************/
/**                                                                       **/
/**  PROJECT      : SDK C# Demo - Ultima Printers                         **/
/**                                                                       **/
/**  MODULE NAME  : Driver1.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 InitDriver1Tab()
        {
            InitCorrectionCombos();
            InitSideCombos();
        }

        Dictionary<SDK.Side, string> sidekp = new Dictionary<SDK.Side, string>()
        {
            {SDK.Side.Front, "Front"},  
            {SDK.Side.Back,  "Back"}, 
        };

        private void InitSideCombos()
        {
            ResinAreaSideCombo.DataSource       = new BindingSource(sidekp, null);
            ResinAreaSideCombo.DisplayMember    = "Value";
            CardSettingsSideCombo.DataSource    = new BindingSource(sidekp, null);
            CardSettingsSideCombo.DisplayMember = "Value";
            HoloKoteSideCombo.DataSource        = new BindingSource(sidekp, null);
            HoloKoteSideCombo.DisplayMember     = "Value";
            ColourAreaSideCombo.DataSource      = new BindingSource(sidekp, null);
            ColourAreaSideCombo.DisplayMember   = "Value";
        }

        #endregion === Initialisation ===

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

        #region === Local Methods ===

        private void Driver1Controls(bool control)
        {
            GUIUser.Enabled                   = control;
            GUIPrinter.Enabled                = control;
            SharpnessUpDown.Enabled           = control;
            CorrectionCombo.Enabled           = control;
            YMCPowerUpDown.Enabled            = control;
            ResinPowerUpDown.Enabled          = control;
            OvercoatPowerUpDown.Enabled       = control;
            ResinAreaLeftUpDown.Enabled       = control;
            ResinAreaWidthUpDown.Enabled      = control;
            ResinAreaBottomUpDown.Enabled     = control;
            ResinAreaHeightUpDown.Enabled     = control;
            ColourAreaCorrectionCombo.Enabled = control;
            ColourAreaLeftUpDown.Enabled      = control;
            ColourAreaWidthUpDown.Enabled     = control;
            ColourAreaBottomUpDown.Enabled    = control;
            ColourAreaHeightUpDown.Enabled    = control;
        }

        private bool Driver1ActionIsGet()
        {
            return Driver1GetRadio.Checked;
        }

        private void ClearDriver1MsgBoxButton_Click(object sender, EventArgs e)
        {
            Driver1MsgBox.Clear();
        }

        private void Driver1ActionGetRadio_CheckedChanged(object sender, EventArgs e)
        {
            Driver1Controls(false);
        }

        private void Driver1ActionSetRadio_CheckedChanged(object sender, EventArgs e)
        {
            Driver1Controls(true);
        }

        #endregion === Local Methods ===

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

        #region === GUI Control ===

        private void GUIControlToMsgBox(SDK.Action action, SDK.GUIControl control)
        {
            string sep = Separator(action);
            Driver1MsgBox.AppendText("GUI User" + sep + control.User + Environment.NewLine);
            Driver1MsgBox.AppendText("GUI Printer" + sep + control.Printer + Environment.NewLine);
            Driver1MsgBox.AppendText(Environment.NewLine);
        }

        private void SetGUIControl(SDK.GUIControl control) 
        {
            GUIUser.Checked = control.User;
            GUIPrinter.Checked = control.Printer;
        }

        private SDK.Return GetGUIControl(ref SDK.GUIControl control)
        {
            SDK.Return SDKReturn = SDK.ID_GUIControl(hSession, SDK.Action.Read, control);
            if (SDKReturn == SDK.Return.Success)
            {
                SetGUIControl(control);
            }
            else
            {
                HandleError("GetGUIControl", SDKReturn);
            }
            return SDKReturn;
        }

        private void GUIControlButton_Click(object sender, EventArgs e)
        {
            SDK.GUIControl control = new SDK.GUIControl();

            if (Driver1ActionIsGet())
            {
                if (GetGUIControl(ref control) == SDK.Return.Success)
                {
                    GUIControlToMsgBox(SDK.Action.Read, control);
                }
            }
            else
            {
                control.User    = GUIUser.Checked;
                control.Printer = GUIPrinter.Checked;

                SDK.Return SDKReturn = SDK.ID_GUIControl(hSession, SDK.Action.Write, control);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetGUIControl", SDKReturn);
                }
                else
                {
                    GUIControlToMsgBox(SDK.Action.Write, control);
                }
            }
        }

        #endregion === GUI Control ===
        
        //----------------------------------------------------------------------

        #region === Sharpness ===

        private SDK.Return GetSharpness(ref sbyte sharpness)
        {
            SDK.Return SDKReturn = SDK.ID_Sharpness(hSession, SDK.Action.Read, ref sharpness);
            if (SDKReturn == SDK.Return.Success)
            {
                SetSharpness(sharpness);
            }
            else
            {
                HandleError("GetSharpness", SDKReturn);
            }
            return SDKReturn;
        }

        private void SharpnessToMsgBox(SDK.Action action, sbyte sharpness)
        {
            string sep = Separator(action);
            Driver1MsgBox.AppendText("Sharpness" + sep + sharpness + Environment.NewLine);
            Driver1MsgBox.AppendText(Environment.NewLine);
        }

        private void SetSharpness(sbyte sharpness) 
        { 
            SharpnessUpDown.Value = sharpness; 
        }

        private void SharpnessButton_Click(object sender, EventArgs e)
        {
            sbyte sharpness = decimal.ToSByte(SharpnessUpDown.Value);

            if (Driver1ActionIsGet())
            {
                if (GetSharpness(ref sharpness) == SDK.Return.Success)
                {
                    SharpnessToMsgBox(SDK.Action.Read, sharpness);
                }
            }
            else
            {
                SDK.Return SDKReturn = SDK.ID_Sharpness(hSession, SDK.Action.Write, ref sharpness);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetSharpness", SDKReturn);
                }
                else
                {
                    SharpnessToMsgBox(SDK.Action.Write, sharpness);
                }
            }
        }

        #endregion === Sharpness ===

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

        #region === Colour Correction ===

        Dictionary<SDK.Correction, string> correctionkp = new Dictionary<SDK.Correction, string>()
        {
            {SDK.Correction.None,            "None"},
            {SDK.Correction.Perceptual,      "Perceptual"},
            {SDK.Correction.Saturation,      "Saturation"},
            {SDK.Correction.RelColorimetric, "Rel Colorimetric"},
            {SDK.Correction.AbsColorimetric, "Abs Colorimetric"},
            {SDK.Correction.ICC_External,    "ICC External"},
        };

        private void InitCorrectionCombos()
        {
            CorrectionCombo.DataSource              = new BindingSource(correctionkp, null);
            CorrectionCombo.DisplayMember           = "Value";
            ColourAreaCorrectionCombo.DataSource    = new BindingSource(correctionkp, null);
            ColourAreaCorrectionCombo.DisplayMember = "Value";
        }

        private void CorrectionToMsgBox(SDK.Action action, SDK.Correction Correction)
        {
            string sep = Separator(action);
            Driver1MsgBox.AppendText("Colour Correction" + sep + correctionkp[Correction] + Environment.NewLine);
            Driver1MsgBox.AppendText(Environment.NewLine);
        }

        private void SetCorrectionCombo(SDK.Correction Correction) 
        {
            CorrectionCombo.Text = correctionkp[Correction]; 
        }

        private SDK.Return GetColourCorrection(ref SDK.Correction Correction)
        {
            SDK.Return SDKReturn = SDK.ID_ColourCorrection(hSession, SDK.Action.Read, ref Correction);
            if (SDKReturn == SDK.Return.Success)
            {
                SetCorrectionCombo(Correction);
            }
            else
            {
                HandleError("GetColourCorrection", SDKReturn);
            }
            return SDKReturn;
        }

        private void ColourCorrectionButton_Click(object sender, EventArgs e)
        {
            SDK.Correction correction = ((KeyValuePair<SDK.Correction, string>)CorrectionCombo.SelectedItem).Key;

            if (Driver1ActionIsGet())
            {
                if (GetColourCorrection(ref correction) == SDK.Return.Success)
                {
                    CorrectionToMsgBox(SDK.Action.Read, correction);
                }
            }
            else
            {
                SDK.Return SDKReturn = SDK.ID_ColourCorrection(hSession, SDK.Action.Write, ref correction);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetColourCorrection", SDKReturn);
                }
                else
                {
                    CorrectionToMsgBox(SDK.Action.Write, correction);
                }
            }
        }

        #endregion === Colour Correction ===

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

        #region === Power Levels ===

        private SDK.Return GetPowerLevels(ref SDK.PowerLevel levels)
        {
            SDK.Return SDKReturn = SDK.ID_PowerLevel(hSession, SDK.Action.Read, levels);
            if (SDKReturn == SDK.Return.Success)
            {
                SetPowerLevels(levels);
            }
            else
            {
                HandleError("GetPowerLevel", SDKReturn);
            }
            return SDKReturn;
        }

        private void PowerLevelsToMsgBox(SDK.Action action, SDK.PowerLevel powerLevel)
        {
            string sep = Separator(action);
            Driver1MsgBox.AppendText("Power Level YMC"      + sep + powerLevel.YMC + Environment.NewLine);
            Driver1MsgBox.AppendText("Power Level Resin"    + sep + powerLevel.Resin + Environment.NewLine);
            Driver1MsgBox.AppendText("Power Level Overcoat" + sep + powerLevel.Overcoat + Environment.NewLine);
            Driver1MsgBox.AppendText(Environment.NewLine);
        }

        private void SetPowerLevels(SDK.PowerLevel powerLevel)
        {
            YMCPowerUpDown.Value      = powerLevel.YMC;
            ResinPowerUpDown.Value    = powerLevel.Resin;
            OvercoatPowerUpDown.Value = powerLevel.Overcoat;
        }

        private void PowerLevelButton_Click(object sender, EventArgs e)
        {
            SDK.PowerLevel powerLevel = new SDK.PowerLevel();

            if (Driver1ActionIsGet())
            {
                if (GetPowerLevels(ref powerLevel) == SDK.Return.Success)
                {
                    PowerLevelsToMsgBox(SDK.Action.Read, powerLevel);
                }
            }
            else
            {
                powerLevel.YMC      = decimal.ToByte(YMCPowerUpDown.Value);
                powerLevel.Resin    = decimal.ToByte(ResinPowerUpDown.Value);
                powerLevel.Overcoat = decimal.ToByte(OvercoatPowerUpDown.Value);

                SDK.Return SDKReturn = SDK.ID_PowerLevel(hSession, SDK.Action.Write, powerLevel);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetPowerLevel", SDKReturn);
                }
                else
                {
                    PowerLevelsToMsgBox(SDK.Action.Write, powerLevel);
                }
            }
        }

        #endregion === Power Levels ===

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

        #region === Resin Areas ===

        private void ResinArea_Changed(object sender, EventArgs e)
        {
            SDK.Area Area = new SDK.Area();
            SDK.Return SDKReturn = GetResinArea(((KeyValuePair<SDK.Side, string>)ResinAreaSideCombo.SelectedItem).Key,
                                                decimal.ToByte(ResinAreaNoUpDown.Value),
                                                ref Area);
            if (SDKReturn == SDK.Return.Success)
            {
                SetResinArea(Area);
            }
        }

        private SDK.Return GetResinArea(SDK.Side side, byte areaNo, ref SDK.Area area)
        {
            SDK.Return SDKReturn = SDK.ID_ResinArea(hSession, 
                                                    SDK.Action.Read, 
                                                    side,
                                                    areaNo, 
                                                    area);
            if (SDKReturn == SDK.Return.Success)
            {
                SetResinArea(area);
            }
            else
            {
                HandleError("GetResinArea", SDKReturn);
            }
            return SDKReturn;
        }

        private void ResinAreaToMsgBox(SDK.Action action, SDK.Side side, SDK.Area area)
        {
            string sep = Separator(action);
            Driver1MsgBox.AppendText("Resin Area " + sidekp[side] + " " + ResinAreaNoUpDown.Value + Environment.NewLine);
            Driver1MsgBox.AppendText("Area Left"   + sep + area.Left   + Environment.NewLine);
            Driver1MsgBox.AppendText("Area Width"  + sep + area.Width  + Environment.NewLine);
            Driver1MsgBox.AppendText("Area Bottom" + sep + area.Bottom + Environment.NewLine);
            Driver1MsgBox.AppendText("Area Height" + sep + area.Height + Environment.NewLine);
            Driver1MsgBox.AppendText(Environment.NewLine);
        }

        private void SetResinArea(SDK.Area area)
        {
            ResinAreaLeftUpDown.Value   = area.Left;
            ResinAreaWidthUpDown.Value  = area.Width;
            ResinAreaBottomUpDown.Value = area.Bottom;
            ResinAreaHeightUpDown.Value = area.Height;
        }

        private void ResinAreaButton_Click(object sender, EventArgs e)
        {
            SDK.Area area = new SDK.Area();
            SDK.Side side = ((KeyValuePair<SDK.Side, string>)ResinAreaSideCombo.SelectedItem).Key;

            if (Driver1ActionIsGet())
            {
                if (GetResinArea(side,
                                 decimal.ToByte(ResinAreaNoUpDown.Value),
                                 ref area) == SDK.Return.Success)
                {
                    ResinAreaToMsgBox(SDK.Action.Read, side, area);
                }
            }
            else
            {
                area.Left   = decimal.ToInt32(ResinAreaLeftUpDown.Value);
                area.Width  = decimal.ToInt32(ResinAreaWidthUpDown.Value);
                area.Bottom = decimal.ToInt32(ResinAreaBottomUpDown.Value);
                area.Height = decimal.ToInt32(ResinAreaHeightUpDown.Value);

                SDK.Return SDKReturn = SDK.ID_ResinArea(hSession, 
                                                              SDK.Action.Write,
                                                              side,
                                                              decimal.ToByte(ResinAreaNoUpDown.Value),
                                                              area);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetResinArea", SDKReturn);
                }
                else
                {
                    ResinAreaToMsgBox(SDK.Action.Write, side, area);
                }
            }
        }

        #endregion === Resin Areas ===

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

        #region === Colour Area Settings ===

        private void ColourArea_Changed(object sender, EventArgs e)
        {
            //Colour Area settings have been changed
            SDK.Area area = new SDK.Area();
            byte areaNo = decimal.ToByte(ColourAreaNo.Value);
            SDK.Correction correction = new SDK.Correction();

            if (GetColourArea(((KeyValuePair<SDK.Side, string>)ColourAreaSideCombo.SelectedItem).Key,
                              areaNo,
                              ref area,
                              ref correction) == SDK.Return.Success)
            {
                SetColourArea(area, correction);
            }
        }

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

        void ColourAreaToMsgBox
        (
            SDK.Action action,
            SDK.Side side,
            int areaNo,
            SDK.Area area,
            SDK.Correction correction
        )
        {
            //Update the message box with the Resin Area settings
            string sep = Separator(action);
            Driver1MsgBox.AppendText("Colour Area " + sidekp[side] + " " + areaNo + Environment.NewLine);
            Driver1MsgBox.AppendText("Left" + sep + area.Left + Environment.NewLine);
            Driver1MsgBox.AppendText("Width" + sep + area.Width + Environment.NewLine);
            Driver1MsgBox.AppendText("Bottom" + sep + area.Bottom + Environment.NewLine);
            Driver1MsgBox.AppendText("Height" + sep + area.Height + Environment.NewLine);
            Driver1MsgBox.AppendText("Correction" + sep + correctionkp[correction] + Environment.NewLine);
            Driver1MsgBox.AppendText(Environment.NewLine);
        }

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

        void SetColourArea(SDK.Area area, SDK.Correction correction)
        {
            //Update the Colour Area controls
	        ColourAreaLeftUpDown.Value   = area.Left;
	        ColourAreaWidthUpDown.Value  = area.Width;
	        ColourAreaBottomUpDown.Value = area.Bottom;
	        ColourAreaHeightUpDown.Value = area.Height;
            ColourAreaCorrectionCombo.Text = correctionkp[correction];
        }

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

        SDK.Return GetColourArea
        (
            SDK.Side side,
            byte areaNo,
            ref SDK.Area area,
            ref SDK.Correction correction
        )
        {
            //Call SDK to read the Resin Area setting
            SDK.Return SDKReturn = SDK.ID_ColourArea(hSession,
                                                     SDK.Action.Read,
                                                     side,
                                                     areaNo,
                                                     area,
                                                     ref correction);
            if (SDKReturn == SDK.Return.Success)
            {
                SetColourArea(area, correction);
            }
            else
            {
                HandleError("GetColourArea", SDKReturn);
            }

            return SDKReturn;
        }

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

        private void ColourAreaButton_Click(object sender, EventArgs e)
        {
            SDK.Area area = new SDK.Area();
            byte areaNo = decimal.ToByte(ColourAreaNo.Value);
            SDK.Side side = ((KeyValuePair<SDK.Side, string>)ColourAreaSideCombo.SelectedItem).Key;
            SDK.Correction correction = new SDK.Correction();

            if (Driver1ActionIsGet())
            {
                //Get the Resin Area settings
                if (GetColourArea(side, areaNo, ref area, ref correction) == SDK.Return.Success)
                {
                    //Update the display
                    ColourAreaToMsgBox(SDK.Action.Read, side, areaNo, area, correction);
                }
            }

            else
            {
                //Get the selected Colour Area settings

			    area.Left   = decimal.ToInt32(ColourAreaLeftUpDown.Value);
			    area.Width  = decimal.ToInt32(ColourAreaWidthUpDown.Value);
			    area.Bottom = decimal.ToInt32(ColourAreaBottomUpDown.Value);
			    area.Height = decimal.ToInt32(ColourAreaHeightUpDown.Value);
                correction = ((KeyValuePair<SDK.Correction, string>)ColourAreaCorrectionCombo.SelectedItem).Key;

                //Call the SDK to write to the driver
                SDK.Return SDKReturn = SDK.ID_ColourArea(hSession,
                                                         SDK.Action.Write,
                                                         side,
                                                         areaNo,
                                                         area,
                                                         ref correction);
                if (SDKReturn != SDK.Return.Success)
                {
                    HandleError("SetColourArea", SDKReturn);
                }

                else
                {
                    //Update the message box
                    ColourAreaToMsgBox(SDK.Action.Write, side, areaNo, area, correction);
                }
            }
        }

        #endregion === Colour Area Settings ===
    }
}
