'/***************************************************************************/
'/**                                                                       **/
'/**                               MAGICARD                                **/
'/**                                                                       **/
'/***************************************************************************/
'/**                                                                       **/
'/**  PROJECT      : SDK VB Demo - Ultima Printers                         **/
'/**                                                                       **/
'/**  MODULE NAME  : PrintDemo.vb                                          **/
'/**                                                                       **/
'/**  COPYRIGHT    : Magicard                                              **/
'/**                                                                       **/
'/***************************************************************************/
Imports System.Runtime.InteropServices

Partial Public Class Main

#Region "=== Initialisation ==="

    Dim printFont As Font
    Dim printBarFont As Font
    Dim backPage As Boolean

    Private Sub InitPrintDemoTab()
        InitColorCombos()
        InitShapeCombos()

#If (x86) Then
        TextFrontBox.Text = "Front - First Line of VB Text (32 bit)"
#Else
        TextFrontBox.Text = "Front - First Line of VB Text (64 bit)"
#End If
        TextFrontXUpDown.Value = 10
        TextFrontYUpDown.Value = 50
        TextFrontSizeUpDown.Value = 10

        ShapeFrontLUpDown.Value = 60
        ShapeFrontTUpDown.Value = 160
        ShapeFrontRUpDown.Value = 320
        ShapeFrontBUpDown.Value = 320
        ShapeFrontWidthUpDown.Value = 5

        LineFrontWidthUpDown.Value = 8
        LineFrontStartXUpDown.Value = 10
        LineFrontStartYUpDown.Value = 10
        LineFrontEndXUpDown.Value = 800
        LineFrontEndYUpDown.Value = 150

        ImageFrontXUpDown.Value = 50
        ImageFrontYUpDown.Value = 110

#If (x86) Then
        TextBackBox.Text = "Back - First Line of VB Text (32 bit)"
#Else
        TextBackBox.Text = "Back - First Line of VB Text (64 bit)"
#End If
        TextBackXUpDown.Value = 10
        TextBackYUpDown.Value = 50
        TextBackSizeUpDown.Value = 10

        ShapeBackLUpDown.Value = 60
        ShapeBackTUpDown.Value = 160
        ShapeBackRUpDown.Value = 320
        ShapeBackBUpDown.Value = 320
        ShapeBackWidthUpDown.Value = 5

        LineBackWidthUpDown.Value = 8
        LineBackStartXUpDown.Value = 10
        LineBackStartYUpDown.Value = 10
        LineBackEndXUpDown.Value = 800
        LineBackEndYUpDown.Value = 150

        ImageBackXUpDown.Value = 50
        ImageBackYUpDown.Value = 110
    End Sub

    Private colorkp As New Dictionary(Of Color, String) From
    {
        {Color.Red, "Red"},
        {Color.Green, "Green"},
        {Color.Blue, "Blue"},
        {Color.Cyan, "Cyan"},
        {Color.Magenta, "Magenta"},
        {Color.Yellow, "Yellow"},
        {Color.White, "White"},
        {Color.Black, "Black"}
    }

    'This key pair is used for the shape fill list boxes and is the same
    'as colorkp but with 'Transparent' added
    Private colorfillkp As New Dictionary(Of Color, String)

    Private Sub InitColorCombos()
        TextFrontColourCombo.DataSource = New BindingSource(colorkp, Nothing)
        TextFrontColourCombo.DisplayMember = "Value"
        TextFrontColourCombo.ValueMember = "Key"

        ShapeFrontOutlineCombo.DataSource = New BindingSource(colorkp, Nothing)
        ShapeFrontOutlineCombo.DisplayMember = "Value"
        ShapeFrontOutlineCombo.ValueMember = "Key"

        LineFrontColourCombo.DataSource = New BindingSource(colorkp, Nothing)
        LineFrontColourCombo.DisplayMember = "Value"
        LineFrontColourCombo.ValueMember = "Key"

        TextBackColourCombo.DataSource = New BindingSource(colorkp, Nothing)
        TextBackColourCombo.DisplayMember = "Value"
        TextBackColourCombo.ValueMember = "Key"

        ShapeBackOutlineCombo.DataSource = New BindingSource(colorkp, Nothing)
        ShapeBackOutlineCombo.DisplayMember = "Value"
        ShapeBackOutlineCombo.ValueMember = "Key"

        LineBackColourCombo.DataSource = New BindingSource(colorkp, Nothing)
        LineBackColourCombo.DisplayMember = "Value"
        LineBackColourCombo.ValueMember = "Key"

        'N.B Transparent also in shape fill combo boxes
        For Each pair In colorkp
            colorfillkp.Add(pair.Key, pair.Value)
        Next
        colorfillkp.Add(Color.Transparent, "Transparent")

        ShapeFrontFillCombo.DataSource = New BindingSource(colorfillkp, Nothing)
        ShapeFrontFillCombo.DisplayMember = "Value"
        ShapeFrontFillCombo.ValueMember = "Key"

        ShapeBackFillCombo.DataSource = New BindingSource(colorfillkp, Nothing)
        ShapeBackFillCombo.DisplayMember = "Value"
        ShapeBackFillCombo.ValueMember = "Key"
    End Sub

    Private shapekp As New Dictionary(Of SDK.Shape, String) From
    {
        {SDK.Shape.Rectangle, "Rectangle"},
        {SDK.Shape.Ellipse, "Ellipse"},
        {SDK.Shape.RoundRect, "RoundRect"},
        {SDK.Shape.Pie, "Pie"},
        {SDK.Shape.Chord, "Chord"}
    }

    Private Sub InitShapeCombos()
        ShapeFrontCombo.DataSource = New BindingSource(shapekp, Nothing)
        ShapeFrontCombo.DisplayMember = "Value"
        ShapeFrontCombo.ValueMember = "Key"

        ShapeBackCombo.DataSource = New BindingSource(shapekp, Nothing)
        ShapeBackCombo.DisplayMember = "Value"
        ShapeBackCombo.ValueMember = "Key"
    End Sub

#End Region

    '----------------------------------------------------------------------

#Region "=== Local Methods ==="

    Private Sub CardFront_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
                Handles CardFront.CheckedChanged
        Dim control As Boolean = CardFront.Checked

        TextFrontEnabled.Enabled = control
        ShapeFrontEnabled.Enabled = control
        LineFrontEnabled.Enabled = control
        ImageFrontEnabled.Enabled = control
        MagDataEnabled.Enabled = control

        TextFrontBox.Enabled = control
        TextFrontColourCombo.Enabled = control
        TextFrontSizeUpDown.Enabled = control
        TextFrontBold.Enabled = control
        TextFrontItalic.Enabled = control
        TextFrontUnderline.Enabled = control
        TextFrontStrikethrough.Enabled = control
        TextFrontXUpDown.Enabled = control
        TextFrontYUpDown.Enabled = control
        TextFrontResin.Enabled = control

        ShapeFrontCombo.Enabled = control
        ShapeFrontOutlineCombo.Enabled = control
        ShapeFrontWidthUpDown.Enabled = control
        ShapeFrontFillCombo.Enabled = control
        ShapeFrontLUpDown.Enabled = control
        ShapeFrontTUpDown.Enabled = control
        ShapeFrontRUpDown.Enabled = control
        ShapeFrontBUpDown.Enabled = control
        ShapeFrontResin.Enabled = control

        LineFrontColourCombo.Enabled = control
        LineFrontWidthUpDown.Enabled = control
        LineFrontStartXUpDown.Enabled = control
        LineFrontStartYUpDown.Enabled = control
        LineFrontEndXUpDown.Enabled = control
        LineFrontEndYUpDown.Enabled = control
        LineFrontResin.Enabled = control

        ImageFrontFileBox.Enabled = control
        ImageFrontXUpDown.Enabled = control
        ImageFrontYUpDown.Enabled = control
        ImageFrontP1UpDown.Enabled = control
        ImageFrontP2UpDown.Enabled = control

        Track1MagData.Enabled = control
        Track2MagData.Enabled = control
        Track3MagData.Enabled = control

        PrintButton.Enabled = (control Or CardBack.Checked)
    End Sub

    Private Sub CardBack_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
                Handles CardBack.CheckedChanged
        Dim control As Boolean = CardBack.Checked

        TextBackEnabled.Enabled = control
        ShapeBackEnabled.Enabled = control
        LineBackEnabled.Enabled = control
        ImageBackEnabled.Enabled = control

        TextBackBox.Enabled = control
        TextBackColourCombo.Enabled = control
        TextBackSizeUpDown.Enabled = control
        TextBackBold.Enabled = control
        TextBackItalic.Enabled = control
        TextBackUnderline.Enabled = control
        TextBackStrikethrough.Enabled = control
        TextBackXUpDown.Enabled = control
        TextBackYUpDown.Enabled = control
        TextBackResin.Enabled = control

        ShapeBackCombo.Enabled = control
        ShapeBackOutlineCombo.Enabled = control
        ShapeBackWidthUpDown.Enabled = control
        ShapeBackFillCombo.Enabled = control
        ShapeBackLUpDown.Enabled = control
        ShapeBackTUpDown.Enabled = control
        ShapeBackRUpDown.Enabled = control
        ShapeBackBUpDown.Enabled = control
        ShapeBackResin.Enabled = control

        LineBackColourCombo.Enabled = control
        LineBackWidthUpDown.Enabled = control
        LineBackStartXUpDown.Enabled = control
        LineBackStartYUpDown.Enabled = control
        LineBackEndXUpDown.Enabled = control
        LineBackEndYUpDown.Enabled = control
        LineBackResin.Enabled = control

        ImageBackFileBox.Enabled = control
        ImageBackXUpDown.Enabled = control
        ImageBackYUpDown.Enabled = control
        ImageBackP1UpDown.Enabled = control
        ImageBackP2UpDown.Enabled = control
        ImageBackResin.Enabled = control

        PrintButton.Enabled = (control Or CardFront.Checked)
    End Sub

    Private Sub nativePrint_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
                Handles nativePrint.CheckedChanged
        Dim control As Boolean = Not nativePrint.Checked

        TextFrontResin.Visible = control
        ShapeFrontResin.Visible = control
        LineFrontResin.Visible = control
        ImageFrontResin.Visible = control
        TextBackResin.Visible = control
        ShapeBackResin.Visible = control
        LineBackResin.Visible = control
        ImageBackResin.Visible = control
    End Sub

#End Region

    '----------------------------------------------------------------------

#Region "=== Front Image Filename ==="

    Private ImageFrontFilename As String

    Private Sub ImageFrontButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ImageFrontButton.Click
        ' Displays an OpenFileDialog so the user can select an image file
        Dim openFileDialog1 As New OpenFileDialog()
        openFileDialog1.Filter = "Image Files (*.bmp;*.jpg;*.png;*.tif)|*.bmp; *.jpg; *.png; *.tif"
        openFileDialog1.Title = "Select an Image File"

        ' Show the dialog and get result.
        Dim result As DialogResult = openFileDialog1.ShowDialog()
        If result = DialogResult.OK Then
            ImageFrontFilename = openFileDialog1.FileName
            ImageFrontFileBox.Text = ImageFrontFilename
        End If
    End Sub

#End Region

    '----------------------------------------------------------------------

#Region "=== Back Image Filename ==="

    Private ImageBackFilename As String

    Private Sub ImageBackButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        ' Displays an OpenFileDialog so the user can select an image file
        Dim openFileDialog1 As New OpenFileDialog()
        openFileDialog1.Filter = "Image Files (*.bmp;*.jpg;*.png;*.tif)|*.bmp; *.jpg; *.png; *.tif"
        openFileDialog1.Title = "Select an Image File"

        ' Show the dialog and get result.
        Dim result As DialogResult = openFileDialog1.ShowDialog()
        If result = DialogResult.OK Then
            ImageBackFilename = openFileDialog1.FileName
            ImageBackFileBox.Text = ImageBackFilename
        End If
    End Sub

#End Region

    '----------------------------------------------------------------------

#Region "=== Print Using Native Functions, Not SDK ==="

    Private Sub NativePrintText(ByVal col As Color,
                                ByVal size As Decimal,
                                ByVal bold As Boolean,
                                ByVal italic As Boolean,
                                ByVal underline As Boolean,
                                ByVal strikeout As Boolean,
                                ByVal textX As Decimal,
                                ByVal textY As Decimal,
                                ByVal text As String)
        'Define the font
        Dim res = FontStyle.Regular
        If bold Then res = res Or FontStyle.Bold
        If italic Then res = res Or FontStyle.Italic
        If underline Then res = res Or FontStyle.Underline
        If strikeout Then res = res Or FontStyle.Strikeout
        Dim font = New Font("Comic Sans MS", size, res)

        Dim brush = New SolidBrush(col)
        g.DrawString(text + " (using GDI)", font, brush, textX, textY)

        printFont.Dispose()
        brush.Dispose()
    End Sub

    Private Sub NativePrintShape(ByVal shape As SDK.Shape,
                                 ByVal outlinecolour As Color,
                                 ByVal penwidth As Decimal,
                                 ByVal fill As Color,
                                 ByVal left As Decimal,
                                 ByVal top As Decimal,
                                 ByVal right As Decimal,
                                 ByVal bottom As Decimal)
        Dim pen = New Pen(outlinecolour)
        pen.Width = penwidth

        Dim r As Rectangle = New Rectangle(left,
                                           top,
                                           right - left,
                                           bottom - top)

        If fill <> Color.Transparent _
        And shape = SDK.Shape.Rectangle Then
            'For demo purposes, only doing filled rectangles 
            Dim brush = New SolidBrush(fill)
            g.FillRectangle(brush, r)
            brush.Dispose()
        End If

        Select Case shape
            Case SDK.Shape.RoundRect 'For demo purposes, rounded rectangles are drawn as normal rectangles
            Case SDK.Shape.Rectangle
                g.DrawRectangle(pen, r)
            Case SDK.Shape.Ellipse
                g.DrawEllipse(pen, r)
            Case SDK.Shape.Pie
                g.DrawPie(pen, r, 45, 60)
            Case SDK.Shape.Chord
                g.DrawArc(pen, r, 45, 60)
        End Select

        pen.Dispose()
    End Sub

    Private Sub NativePrintLine(ByVal col As Color,
                                ByVal width As Decimal,
                                ByVal startX As Decimal,
                                ByVal startY As Decimal,
                                ByVal endX As Decimal,
                                ByVal endY As Decimal)
        Dim pen As New Pen(col)
        pen.Width = width

        g.DrawLine(pen, startX, startY, endX, endY)

        pen.Dispose()
    End Sub

    Private Sub NativePrintImage(ByVal filename As String,
                                 ByVal x As Decimal,
                                 ByVal y As Decimal,
                                 ByVal p1 As Decimal,
                                 ByVal p2 As Decimal)
        Dim Image As Image = Image.FromFile(filename)
        Dim r As Rectangle = getRect(Image, x, y, p1, p2)
        g.DrawImage(Image, r)
        Image.Dispose()
    End Sub

    Private Sub PrintCard_Front(ByVal g As Graphics)
        If TextFrontEnabled.Checked Then
            NativePrintText(TextFrontColourCombo.SelectedItem.Key,
                TextFrontSizeUpDown.Value,
                TextFrontBold.Checked,
                TextFrontItalic.Checked,
                TextFrontUnderline.Checked,
                TextFrontStrikethrough.Checked,
                TextFrontXUpDown.Value,
                TextFrontYUpDown.Value,
                TextFrontBox.Text)
        End If

        If ShapeFrontEnabled.Checked Then
            NativePrintShape(ShapeFrontCombo.SelectedItem.Key,
                             ShapeFrontOutlineCombo.SelectedItem.Key,
                             ShapeFrontWidthUpDown.Value,
                             ShapeFrontFillCombo.SelectedItem.Key,
                             ShapeFrontLUpDown.Value,
                             ShapeFrontTUpDown.Value,
                             ShapeFrontRUpDown.Value,
                             ShapeFrontBUpDown.Value)
        End If

        If LineFrontEnabled.Checked Then
            NativePrintLine(LineFrontColourCombo.SelectedItem.Key,
                            LineFrontWidthUpDown.Value,
                            LineFrontStartXUpDown.Value,
                            LineFrontStartYUpDown.Value,
                            LineFrontEndXUpDown.Value,
                            LineFrontEndYUpDown.Value)
        End If

        If ImageFrontEnabled.Checked _
        And (ImageFrontFileBox.TextLength <> 0) Then
            NativePrintImage(ImageFrontFileBox.Text,
                             ImageFrontXUpDown.Value,
                             ImageFrontYUpDown.Value,
                             ImageFrontP1UpDown.Value,
                             ImageFrontP2UpDown.Value)
        End If
    End Sub

    Private Sub PrintCard_Back(ByVal g As Graphics)
        If TextBackEnabled.Checked Then
            NativePrintText(TextBackColourCombo.SelectedItem.Key,
                TextBackSizeUpDown.Value,
                TextBackBold.Checked,
                TextBackItalic.Checked,
                TextBackUnderline.Checked,
                TextBackStrikethrough.Checked,
                TextBackXUpDown.Value,
                TextBackYUpDown.Value,
                TextBackBox.Text)
        End If

        If ShapeBackEnabled.Checked Then
            NativePrintShape(ShapeBackCombo.SelectedItem.Key,
                             ShapeBackOutlineCombo.SelectedItem.Key,
                             ShapeBackWidthUpDown.Value,
                             ShapeBackFillCombo.SelectedItem.Key,
                             ShapeBackLUpDown.Value,
                             ShapeBackTUpDown.Value,
                             ShapeBackRUpDown.Value,
                             ShapeBackBUpDown.Value)
        End If

        If LineBackEnabled.Checked Then
            NativePrintLine(LineBackColourCombo.SelectedItem.Key,
                            LineBackWidthUpDown.Value,
                            LineBackStartXUpDown.Value,
                            LineBackStartYUpDown.Value,
                            LineBackEndXUpDown.Value,
                            LineBackEndYUpDown.Value)
        End If

        If ImageBackEnabled.Checked _
        And (ImageBackFileBox.TextLength <> 0) Then
            NativePrintImage(ImageBackFileBox.Text,
                             ImageBackXUpDown.Value,
                             ImageBackYUpDown.Value,
                             ImageBackP1UpDown.Value,
                             ImageBackP2UpDown.Value)
        End If
    End Sub

    Private Function getRect(ByVal i As Image,
                             ByVal x As Integer,
                             ByVal y As Integer,
                             ByVal p1 As Integer,
                             ByVal p2 As Integer) As Rectangle
        Dim width As Integer = i.Width
        Dim height As Integer = i.Height
        If p1 = 0 Then
            'No scaling or constraining - Use original size of image
        ElseIf p2 = 0 Then
            'Scaling - Modify image dimensions by scaling with the given percentage
            '(p1), while maintaining the aspect ratio
            width = (width * p1) / 100
            height = (height * p1) / 100
        Else
            'Constraining - Restrict the image to the given rectangle, ignoring aspect ratio
            '(p1 = new width, p2 = new height)
            width = p1
            height = p2
        End If

        Return New Rectangle(x, y, width, height)
    End Function

    Private pageNum As Integer = 0

    Private Sub printCard_PrintPage(ByVal sender As Object, ByVal e As PrintPageEventArgs)
        e.Graphics.PageUnit = GraphicsUnit.Pixel

        Select Case pageNum
            Case 0
                If CardFront.Checked Then
                    PrintCard_Front(e.Graphics)
                    If CardBack.Checked Then
                        e.HasMorePages = True
                        pageNum = 1
                    End If
                Else
                    PrintCard_Back(e.Graphics)
                End If

            Case 1
                If CardBack.Checked Then
                    PrintCard_Back(e.Graphics)
                End If
        End Select

    End Sub

    Private Sub PrintUsingNative()
        Cursor.Current = Cursors.WaitCursor

        Dim printCard As New PrintDocument()
        printCard.DocumentName = "Print Card"
        printCard.PrinterSettings.PrinterName = ps.PrinterName
        AddHandler printCard.PrintPage, AddressOf Me.printCard_PrintPage
        pageNum = 0

        'Update the DevMode
        Dim SDKReturn As SDK.Return = SDK.ID_UpdateDevMode(hSession, printCard)
        If SDKReturn <> SDK.Return.Success Then
            HandleError("UpdateDevMode", SDKReturn)
            Return
        End If

        printCard.Print()

        Cursor.Current = Cursors.Default
    End Sub

#End Region

    '----------------------------------------------------------------------

#Region "=== Print Button ==="

    Private Sub PrintButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
                Handles PrintButton.Click
        If nativePrint.Checked Then
            PrintUsingNative()
            Return
        End If

        ' Determine if the printer is online and ready before proceeding
        'If SDK.ID_PrinterStatus(hSession) <> SDK.PrinterStatus.Ready Then
        '	MessageBox.Show("Cannot Print - Printer is not available")
        '	Return
        'End If

        Cursor.Current = Cursors.WaitCursor

        Dim SDKReturn As SDK.Return

        Dim FrontDC As Long = 0
        Dim BackDC As Long = 0
        Dim FrontResinDC As Long = 0
        Dim BackResinDC As Long = 0

        Dim TextDefn As New SDK.TextDef
        Dim ShapeDefn As New SDK.ShapeDef
        Dim LineDefn As New SDK.LineDef

        Do
            'This single pass do..while loop allows us to exit using 'exit do' (instead of return) and 
            'still reset the cursor at the end :-)

            '************************************************************************************	
            '* Currently, the demo app uses the driver settings as configured under the Driver1 *
            '* and Driver2 tabs.  Should the developer wish to control this dependent on the    *
            '* print selections, and modify these with code, a process such as shown here in    *
            '* could be used.                                                                   *
            '************************************************************************************	
            'Dim PrintSettings As New SDK.PrintSetting
            'Dim OldPrintSettings As New SDK.PrintSetting

            ''Call SDK function to read the print settings for the card so that they can be preserved
            'SDKReturn = SDK.ID_PrintSettings(hSession,
            '                                    SDK.Action.Read,
            '                                    OldPrintSettings)
            'If SDKReturn <> SDK.Return.Success Then
            '    HandleError("OldPrintSettings", SDKReturn)
            '    Exit Do
            'End If

            'PrintSettings = OldPrintSettings

            ''Determine which sides of the card need to be printed
            'If CardFront.Checked And CardBack.Checked Then
            '    PrintSettings.Duplex = SDK.Duplex.Both
            'ElseIf CardFront.Checked Then
            '    PrintSettings.Duplex = SDK.Duplex.FrontOnly
            'Else
            '    PrintSettings.Duplex = SDK.Duplex.BackOnly
            'End If

            ''Change the print settings for the card
            'SDKReturn = SDK.ID_PrintSettings(hSession,
            '                                            SDK.Action.Write,
            '                                            PrintSettings)
            'If SDKReturn <> SDK.Return.Success Then
            '    HandleError("WritePrintSettings", SDKReturn)
            '    Exit Do
            'End If

            Dim Canvas As Long

            'Is there a front to be printed?
            If CardFront.Checked Then
                'Initialise Front Canvas
                SDKReturn = SDK.ID_CanvasInit(hSession, FrontDC, SDK.Canvas.Front)
                If SDKReturn <> SDK.Return.Success Then
                    HandleError("CanvasInitFront", SDKReturn)
                    Exit Do
                End If

                If TextFrontResin.Checked _
                Or ShapeFrontResin.Checked _
                Or LineFrontResin.Checked _
                Or ImageFrontResin.Checked Then
                    SDKReturn = SDK.ID_CanvasInit(hSession, FrontResinDC, SDK.Canvas.FrontResin)
                    If SDKReturn <> SDK.Return.Success Then
                        HandleError("CanvasInitFrontResin", SDKReturn)
                        Exit Do
                    End If
                End If

                If TextFrontEnabled.Checked Then
                    'Front Text....
                    'Define the font
                    TextDefn.FontName = "Comic Sans MS"
                    TextDefn.FontSize = TextFrontSizeUpDown.Value
                    TextDefn.FontColour = TextFrontColourCombo.SelectedItem.Key
                    TextDefn.FontStyle = 0
                    If TextFrontBold.Checked Then TextDefn.FontStyle = TextDefn.FontStyle Or SDK.FontStyle.Bold
                    If TextFrontItalic.Checked Then TextDefn.FontStyle = TextDefn.FontStyle Or SDK.FontStyle.Italic
                    If TextFrontUnderline.Checked Then TextDefn.FontStyle = TextDefn.FontStyle Or SDK.FontStyle.Underline
                    If TextFrontStrikethrough.Checked Then TextDefn.FontStyle = TextDefn.FontStyle Or SDK.FontStyle.Strikeout

                    'Get the location and angle for the text
                    TextDefn.X = TextFrontXUpDown.Value
                    TextDefn.Y = TextFrontYUpDown.Value
                    TextDefn.Angle = 0

                    'Get the text to be drawn
                    TextDefn.Text = TextFrontBox.Text

                    'Call the SDK function to draw the text on the canvas
                    If TextFrontResin.Checked Then
                        Canvas = SDK.Canvas.FrontResin
                    Else
                        Canvas = SDK.Canvas.Front
                    End If

                    SDKReturn = SDK.ID_DrawText(hSession, Canvas, TextDefn)
                    If SDKReturn <> SDK.Return.Success Then
                        HandleError("DrawTextFront", SDKReturn)
                        Exit Do
                    End If
                End If

                If ShapeFrontEnabled.Checked Then
                    'Front Shape...
                    'Get the shape's definition
                    ShapeDefn.Shape = ShapeFrontCombo.SelectedItem.Key
                    ShapeDefn.PenColour = ShapeFrontOutlineCombo.SelectedItem.Key
                    ShapeDefn.FillColour = ShapeFrontFillCombo.SelectedItem.Key
                    ShapeDefn.PenWidth = ShapeFrontWidthUpDown.Value

                    'Get the shape location
                    ShapeDefn.Area = New Rectangle(ShapeFrontLUpDown.Value,
                                                   ShapeFrontTUpDown.Value,
                                                   ShapeFrontRUpDown.Value - ShapeFrontLUpDown.Value,
                                                   ShapeFrontBUpDown.Value - ShapeFrontTUpDown.Value)

                    'Set up the specific parameters for given shapes.
                    'For simplicity, these have been hard codes here rather than GUI selectable
                    Select Case ShapeDefn.Shape
                        Case SDK.Shape.RoundRect
                            ShapeDefn.P1 = 50       ' Corner Width
                            ShapeDefn.P2 = 50       ' Corner Height
                        Case SDK.Shape.Pie
                        Case SDK.Shape.Chord
                            ShapeDefn.P1 = 0        ' Radial 1 X Co-ord
                            ShapeDefn.P2 = 0        ' Radial 1 Y Co-ord
                            ShapeDefn.P3 = 700      ' Radial 2 X Co-ord
                            ShapeDefn.P4 = 115      ' Radial 2 Y Co-ord
                    End Select

                    'Call the SDK function to draw the shape on the canvas
                    If ShapeFrontResin.Checked Then
                        Canvas = SDK.Canvas.FrontResin
                    Else
                        Canvas = SDK.Canvas.Front
                    End If

                    SDKReturn = SDK.ID_DrawShape(hSession, Canvas, ShapeDefn)
                    If SDKReturn <> SDK.Return.Success Then
                        HandleError("DrawShapeFront", SDKReturn)
                        Exit Do
                    End If
                End If

                If LineFrontEnabled.Checked Then
                    'Front Line...
                    'Get the line's definition
                    LineDefn.Colour = LineFrontColourCombo.SelectedItem.Key
                    LineDefn.Width = LineFrontWidthUpDown.Value

                    'Get the line location
                    LineDefn.StartX = LineFrontStartXUpDown.Value
                    LineDefn.StartY = LineFrontStartYUpDown.Value
                    LineDefn.EndX = LineFrontEndXUpDown.Value
                    LineDefn.EndY = LineFrontEndYUpDown.Value

                    'Call the SDK function to draw the line on the canvas
                    If LineFrontResin.Checked Then
                        Canvas = SDK.Canvas.FrontResin
                    Else
                        Canvas = SDK.Canvas.Front
                    End If

                    SDKReturn = SDK.ID_DrawLine(hSession, Canvas, LineDefn)
                    If SDKReturn <> SDK.Return.Success Then
                        HandleError("DrawLineFront", SDKReturn)
                        Exit Do
                    End If
                End If

                If ImageFrontEnabled.Checked Then
                    'Has an image file been selected?
                    If ImageFrontFileBox.TextLength <> 0 Then
                        'Front Image.......
                        Dim Image As New SDK.ImageDef

                        'Get the image boundaries
                        Image.X = ImageFrontXUpDown.Value
                        Image.Y = ImageFrontYUpDown.Value
                        Image.P1 = ImageFrontP1UpDown.Value
                        Image.P2 = ImageFrontP2UpDown.Value

                        Image.Filename = ImageFrontFileBox.Text

                        'Call the SDK function to draw the image on the canvas
                        If ImageFrontResin.Checked Then
                            Canvas = SDK.Canvas.FrontResin
                        Else
                            Canvas = SDK.Canvas.Front
                        End If

                        SDKReturn = SDK.ID_DrawImage(hSession, Canvas, Image)
                        If SDKReturn <> SDK.Return.Success Then
                            HandleError("DrawImageFront", SDKReturn)
                            Exit Do
                        End If
                    End If
                End If

                If MagDataEnabled.Checked Then
                    '===== Front Magnetic Data =====
                    Dim magText As New SDK.MagText

                    If Track1MagData.TextLength <> 0 Then
                        magText.Track = 1
                        magText.Data = Track1MagData.Text

                        'Call the SDK function to draw the image on the canvas
                        SDKReturn = SDK.ID_DrawMagText(hSession, SDK.Side.Front, magText)
                        If SDKReturn <> SDK.Return.Success Then
                            HandleError("Mag1DataFront", SDKReturn)
                            Exit Do
                        End If
                    End If

                    If Track2MagData.TextLength <> 0 Then
                        magText.Track = 2
                        magText.Data = Track2MagData.Text

                        'Call the SDK function to draw the image on the canvas
                        SDKReturn = SDK.ID_DrawMagText(hSession, SDK.Side.Front, magText)
                        If SDKReturn <> SDK.Return.Success Then
                            HandleError("Mag2DataFront", SDKReturn)
                            Exit Do
                        End If
                    End If

                    If Track3MagData.TextLength <> 0 Then
                        magText.Track = 3
                        magText.Data = Track3MagData.Text

                        'Call the SDK function to draw the image on the canvas
                        SDKReturn = SDK.ID_DrawMagText(hSession, SDK.Side.Front, magText)
                        If SDKReturn <> SDK.Return.Success Then
                            HandleError("Mag3DataFront", SDKReturn)
                            Exit Do
                        End If
                    End If
                End If
            End If

            '-------------------------------------------------------------------

            'Is there a back to be printed?
            If CardBack.Checked Then

                '***********************************************************************************	
                '* Similarly, settings for the back of the card are defined under the Driver1 and  *
                '* Driver 2 tabs.  This code block reads the settings to save them for restore     *
                '* later, and modifies the colour settings according to the Print Demo tab         *
                '* selections.                                                                     *
                '***********************************************************************************	
                'Dim BackSettings As New SDK.CardSetting
                'Dim OldBackSettings As New SDK.CardSetting

                ''Read the current settings for the Back of the card
                'SDKReturn = SDK.ID_CardSettings(hSession,
                '                                   SDK.Action.Read,
                '                                   SDK.Side.Back,
                '                                   OldBackSettings)
                'If SDKReturn <> SDK.Return.Success Then
                '    HandleError("OldCardSettings", SDKReturn)
                '    Exit Do
                'End If
                'BackSettings = OldBackSettings

                ''If colour is required, modify the card settings for the back of the card
                'If TextBackColourCombo.SelectedItem.Key <> Color.Black _
                'Or ShapeBackOutlineCombo.SelectedItem.Key <> Color.Black _
                'Or LineBackColourCombo.SelectedItem.Key <> Color.Black _
                'Or ShapeBackFillCombo.SelectedItem.Key <> Color.Black _
                '    And (ShapeBackFillCombo.SelectedItem.Key <> Color.Transparent) Then
                '    BackSettings.ColourFormat = SDK.ColourFormat.YMCK

                '    SDKReturn = SDK.ID_CardSettings(hSession, SDK.Action.Write, SDK.Side.Back, BackSettings)
                '    If SDKReturn <> SDK.Return.Success Then
                '        HandleError("CardSettingsBack", SDKReturn)
                '        Exit Do
                '    End If
                'End If

                'Initialise Rear Canvas
                SDKReturn = SDK.ID_CanvasInit(hSession, BackDC, SDK.Canvas.Back)
                If SDKReturn <> SDK.Return.Success Then
                    HandleError("CanvasInitBack", SDKReturn)
                    Exit Do
                End If

                If TextBackResin.Checked _
                Or ShapeBackResin.Checked _
                Or LineBackResin.Checked _
                Or ImageBackResin.Checked Then
                    SDKReturn = SDK.ID_CanvasInit(hSession, BackResinDC, SDK.Canvas.BackResin)
                    If SDKReturn <> SDK.Return.Success Then
                        HandleError("CanvasInitBackResin", SDKReturn)
                        Exit Do
                    End If
                End If

                'Rear Text
                TextDefn.FontName = "Comic Sans MS"
                TextDefn.FontSize = TextBackSizeUpDown.Value
                TextDefn.FontColour = TextBackColourCombo.SelectedItem.Key
                TextDefn.FontStyle = 0
                If TextBackBold.Checked Then TextDefn.FontStyle = TextDefn.FontStyle Or SDK.FontStyle.Bold
                If TextBackItalic.Checked Then TextDefn.FontStyle = TextDefn.FontStyle Or SDK.FontStyle.Italic
                If TextBackUnderline.Checked Then TextDefn.FontStyle = TextDefn.FontStyle Or SDK.FontStyle.Underline
                If TextBackStrikethrough.Checked Then TextDefn.FontStyle = TextDefn.FontStyle Or SDK.FontStyle.Strikeout
                TextDefn.X = TextBackXUpDown.Value
                TextDefn.Y = TextBackYUpDown.Value
                TextDefn.Angle = 0
                TextDefn.Text = TextBackBox.Text

                If TextBackResin.Checked Then
                    Canvas = SDK.Canvas.BackResin
                Else
                    Canvas = SDK.Canvas.Back
                End If

                SDKReturn = SDK.ID_DrawText(hSession, Canvas, TextDefn)
                If SDKReturn <> SDK.Return.Success Then
                    HandleError("DrawTextBack", SDKReturn)
                    Exit Do
                End If

                'Rear Shape
                ShapeDefn.Shape = ShapeBackCombo.SelectedItem.Key
                ShapeDefn.PenColour = ShapeBackOutlineCombo.SelectedItem.Key
                ShapeDefn.FillColour = ShapeBackFillCombo.SelectedItem.Key
                ShapeDefn.PenWidth = ShapeBackWidthUpDown.Value

                'Get the shape location
                ShapeDefn.Area = New Rectangle(ShapeBackLUpDown.Value,
                                               ShapeBackTUpDown.Value,
                                               ShapeBackRUpDown.Value - ShapeBackLUpDown.Value,
                                               ShapeBackBUpDown.Value - ShapeBackTUpDown.Value)

                Select Case ShapeDefn.Shape
                    Case SDK.Shape.RoundRect
                        ShapeDefn.P1 = 50       ' Corner Width
                        ShapeDefn.P2 = 50       ' Corner Height
                    Case SDK.Shape.Pie
                    Case SDK.Shape.Chord
                        ShapeDefn.P1 = 0        ' Radial 1 X Co-ord
                        ShapeDefn.P2 = 0        ' Radial 1 Y Co-ord
                        ShapeDefn.P3 = 700      ' Radial 2 X Co-ord
                        ShapeDefn.P4 = 115      ' Radial 2 Y Co-ord
                End Select

                If ShapeBackResin.Checked Then
                    Canvas = SDK.Canvas.BackResin
                Else
                    Canvas = SDK.Canvas.Back
                End If

                SDKReturn = SDK.ID_DrawShape(hSession, Canvas, ShapeDefn)
                If SDKReturn <> SDK.Return.Success Then
                    HandleError("DrawShapeBack", SDKReturn)
                    Exit Do
                End If

                'Rear Line...
                'Get the line's definition
                LineDefn.Colour = LineBackColourCombo.SelectedItem.Key
                LineDefn.Width = LineBackWidthUpDown.Value

                'Get the line location
                LineDefn.StartX = LineBackStartXUpDown.Value
                LineDefn.StartY = LineBackStartYUpDown.Value
                LineDefn.EndX = LineBackEndXUpDown.Value
                LineDefn.EndY = LineBackEndYUpDown.Value

                'Call the SDK function to draw the line on the canvas
                If LineBackResin.Checked Then
                    Canvas = SDK.Canvas.BackResin
                Else
                    Canvas = SDK.Canvas.Back
                End If

                SDKReturn = SDK.ID_DrawLine(hSession, Canvas, LineDefn)
                If SDKReturn <> SDK.Return.Success Then
                    HandleError("DrawLineBack", SDKReturn)
                    Exit Do
                End If

                If ImageBackEnabled.Checked Then
                    'Has an image file been selected?
                    If ImageBackFileBox.TextLength <> 0 Then
                        'Front Image.......
                        Dim Image As New SDK.ImageDef

                        'Get the image boundaries
                        Image.X = ImageBackXUpDown.Value
                        Image.Y = ImageBackYUpDown.Value
                        Image.P1 = ImageBackP1UpDown.Value
                        Image.P2 = ImageBackP2UpDown.Value

                        Image.Filename = ImageBackFileBox.Text

                        'Call the SDK function to draw the image on the canvas
                        If ImageBackResin.Checked Then
                            Canvas = SDK.Canvas.BackResin
                        Else
                            Canvas = SDK.Canvas.Back
                        End If

                        SDKReturn = SDK.ID_DrawImage(hSession, Canvas, Image)
                        If SDKReturn <> SDK.Return.Success Then
                            HandleError("DrawImageBack", SDKReturn)
                            Exit Do
                        End If
                    End If
                End If
            End If

            '-------------------------------------------------------------------

            'Print the Card
            SDKReturn = SDK.ID_PrintCard(hSession)
            If SDKReturn <> SDK.Return.Success Then
                HandleError("PrintCard", SDKReturn)
                Exit Do
            End If

            If Not pd.PrintToFile Then
                'Wait for the printing to complete
                WaitForPrinterToFinish()
            End If

            '**************************************************************************************
            '* Restore the settings for the print job, and for the card back, as saved previously *
            '**************************************************************************************
            ''Restore Original Print Settings
            'SDKReturn = SDK.ID_PrintSettings(hSession, SDK.Action.Write, OldPrintSettings)
            'If SDKReturn <> SDK.Return.Success Then
            '    HandleError("RestorePrintSettings", SDKReturn)
            '    Exit Do
            'End If

            ''Restore the Original Settings for the Back of the Card
            'SDKReturn = SDK.ID_CardSettings(hSession, SDK.Action.Write, SDK.Side.Back, OldBackSettings)
            'If SDKReturn <> SDK.Return.Success Then
            '    HandleError("RestoreBackSettings", SDKReturn)
            'End If
        Loop While False 'End of single pass do..while loop

        If FrontDC <> 0 Then
            SDK.ID_CanvasDelete(hSession, SDK.Canvas.Front)
        End If
        If FrontResinDC <> 0 Then
            SDK.ID_CanvasDelete(hSession, SDK.Canvas.FrontResin)
        End If
        If BackDC <> 0 Then
            SDK.ID_CanvasDelete(hSession, SDK.Canvas.Back)
        End If
        If BackResinDC <> 0 Then
            SDK.ID_CanvasDelete(hSession, SDK.Canvas.BackResin)
        End If

        'All 'breaks' from the single pass do..while loop come here
        Cursor.Current = Cursors.Default
    End Sub

#End Region

    '----------------------------------------------------------------------

#Region "=== Printer Preferences ==="

    <DllImport("winspool.Drv", EntryPoint:="DocumentPropertiesW", _
                               SetLastError:=True, _
                               ExactSpelling:=True, _
                               CallingConvention:=CallingConvention.StdCall)> _
    Private Shared Function DocumentProperties(ByVal hwnd As IntPtr, _
                                               ByVal hPrinter As IntPtr, _
                                               <MarshalAs(UnmanagedType.LPWStr)> ByVal pDeviceName As String, _
                                               ByVal pDevmodeOutput As IntPtr, _
                                               ByVal pDevmodeInput As IntPtr, _
                                               ByVal fMode As Integer) As Integer
    End Function

    <DllImport("kernel32.dll", ExactSpelling:=True)> _
    Friend Shared Function GlobalLock(ByVal handle As IntPtr) As IntPtr
    End Function

    <DllImport("kernel32.dll", ExactSpelling:=True)> _
    Friend Shared Function GlobalUnlock(ByVal handle As IntPtr) As Boolean
    End Function

    Private Const DM_OUT_BUFFER As Integer = 2
    Private Const DM_IN_PROMPT As Integer = 4
    Private Const DM_IN_BUFFER As Integer = 8

    Private Sub PrinterPrefs_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
                Handles PrinterPrefs.Click
        If nativePrint.Checked Then
            'Use native Windows API calls, etc. to display and save printer 
            'preferences(locally)
            Dim hDevMode As IntPtr = ps.GetHdevmode(ps.DefaultPageSettings)
            Dim pDevMode As IntPtr = GlobalLock(hDevMode)
            Dim sizeNeeded As Integer = DocumentProperties(Me.Handle,
                                                IntPtr.Zero,
                                                ps.PrinterName,
                                                IntPtr.Zero,
                                                pDevMode,
                                                0)

            Dim devModeData As IntPtr = Marshal.AllocHGlobal(sizeNeeded)
            DocumentProperties(Me.Handle,
                               IntPtr.Zero,
                               ps.PrinterName,
                               devModeData,
                               pDevMode,
                               DM_OUT_BUFFER Or DM_IN_PROMPT Or DM_IN_BUFFER)
            GlobalUnlock(hDevMode)

            'Update Printer Settings to save any changes made.
            ps.SetHdevmode(devModeData)
            ps.DefaultPageSettings.SetHdevmode(devModeData)

            Marshal.FreeHGlobal(devModeData)
        Else
            'Use the SDK to display and save any changes to the printer preferences in the driver
            Dim SDKReturn As SDK.Return = SDK.ID_PrinterPrefs(hSession, Me.Handle)
            If SDKReturn <> SDK.Return.Success Then
                HandleError("PrinterPrefs", SDKReturn)
            End If
        End If
    End Sub

#End Region

End Class
