
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging

Public Class MainWindow

  ' Constants to define the size and spacing of our Slides
  Const Gutter As Integer = 8
  Const SlideSpace As Integer = 120 + Gutter

  Private StartPos As Point
  Private DraggingStart As Boolean = False
  Private DraggingStartLocation As Point
  Private DraggingFinish As Boolean = False
  Private draggingFinishLocation As Point
  Private ScaleFactor As Double ' for reducing the preview images

  Dim WithEvents FrameA As New FrameType
  Dim WithEvents FrameB As New FrameType

  Private CursorPos, PreviousCursorPos As Integer

  Declare Auto Function GetAsyncKeyState Lib "user32.dll" (ByVal key As Keys) As Integer

  Private Sub MainWindow_Closing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    ExitProgram()
    e.Cancel = True
  End Sub
  Private Sub MainWindow_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
    CheckBox3.Checked = ShowCaption
    Dim S As New Rectangle
    S = Screen.PrimaryScreen.Bounds
    ScreenSize.Width = S.Width
    ScreenSize.Height = S.Height
    WsFactor = 1
    ChangeScreenSize(False)
    CustomSizeToolStripMenuItem.Checked = True
    EnablePanControls("NULL")
    pnlSlides.AutoScrollMargin = New Size(Gutter, 0)
    CursorPos = -1
    PreviousCursorPos = -1
    AddHandler FrameA.Finished, AddressOf StartB
    AddHandler FrameB.Finished, AddressOf StartA
    mediaAlias("Movie")
    Dim args() As String
    args = System.Environment.GetCommandLineArgs()
    If args.Count > 1 Then
      If LCase(Microsoft.VisualBasic.Right(args(1), 4)) = ".mgl" Then
        LoadSlideShow(args(1))
      End If
    End If
  End Sub
  Private Sub StartA()
    FrameA.Focus()
    FrameA.Start(1)
  End Sub
  Private Sub StartB()
    FrameB.Focus()
    FrameB.Start(1)
  End Sub
  Public Sub KeyPressed(ByVal c)
    Select Case c
      Case 9 ' TAB
        ShowCaption = Not ShowCaption
        CheckBox3.Checked = ShowCaption
        If ShowCaption Then
          FrameA.Label1.Show() : FrameB.Label1.Show()
        Else
          FrameA.Label1.Hide() : FrameB.Label1.Hide()
        End If
      Case 27 ' ESCAPE
        mediaClose()
        FrameA.Hide() : FrameB.Hide() : Background.Hide()
        FrameA.Timer1.Enabled = False
        FrameB.Timer1.Enabled = False
        testing = False
        SetSelectedSlide(CurrentSlide)
      Case 120 ' F9
        Paused = True
        RenameSlide(CurrentSlide)
    End Select
  End Sub
  Private Sub ChangeScreenSize(ByVal Flag)
    ScaleFactor = ScreenSize.Width * WsFactor / 360
    If ScreenSize.Height > 220 * ScaleFactor Then ScaleFactor = ScreenSize.Height / 220
    pnlPhotoStart.Width = ScreenSize.Width * WsFactor / ScaleFactor
    pnlPhotoStart.Height = ScreenSize.Height / ScaleFactor
    pnlPhotoFinish.Width = ScreenSize.Width * WsFactor / ScaleFactor
    pnlPhotoFinish.Height = ScreenSize.Height / ScaleFactor
    pnlPhotoStart.Left = 188 - pnlPhotoStart.Width / 2
    pnlPhotoStart.Top = 120 - pnlPhotoStart.Height / 2
    pnlPhotoFinish.Left = 596 - pnlPhotoFinish.Width / 2
    pnlPhotoFinish.Top = 120 - pnlPhotoFinish.Height / 2
    ReDrawPhotoStart(SelectedSlide)
    ReDrawPhotoFinish(SelectedSlide)
    Label4.Text = ScreenSize.ToString & "  Compression factor =" & Str(WsFactor)
    If Flag And pnlSlides.Controls.Count > 0 Then
      If MsgBox("The screen size has been changed. Do you want to reset all the slides to reflect this fact?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
        ResetAllSlides()
      End If
    End If
    ResetScreensizeMenu()
  End Sub
  Private Sub ExitProgram()
    If Modified AndAlso MsgBox("This slide show has been modified. Click 'OK' to exit without saving your changes.", MsgBoxStyle.OkCancel) = MsgBoxResult.Cancel Then Exit Sub
    End
  End Sub
  Private Sub Modify(ByVal f)
    Modified = f
    If f Then Me.Text = CurrentFilename & " *" Else Me.Text = CurrentFilename
  End Sub

#Region "Slide routines"
  Public Function FindNextSlide()
    Dim s, cs As SlideType
    cs = CurrentSlide
    Dim i As Integer = 9999999
    Dim j As Integer
    For Each c As Control In pnlSlides.Controls
      If c.GetType Is GetType(SlideType) Then
        s = c
        j = s.Index - CurrentSlide.Index
        If BackOneSlide Then j = -j
        If s.EnableFlag And j > 0 And j < i Then cs = s : i = j
      End If
    Next
    BackOneSlide = False
    If i < 9999999 Then CurrentSlide = cs : Return True
    Return False
  End Function
  Private Sub OnSlideMouseDown(ByVal sender As System.Object, ByVal e As MouseEventArgs)
    If sender.GetType Is GetType(SlideType) Then
      If MouseButtons = Windows.Forms.MouseButtons.Left Then
        If Control.ModifierKeys = Keys.Shift Then
          'enable / disable slide
          Dim s As SlideType = DirectCast(sender, SlideType)
          s.EnableFlag = Not s.EnableFlag
          s.DrawSlide()
        Else
          'select slide
          If sender IsNot SelectedSlide Then
            SetSelectedSlide(DirectCast(sender, SlideType))
          End If
        End If
      Else
        'drag slide
        Dim sl As SlideType = DirectCast(sender, SlideType)
        Dim ScrollPosition As Integer = -pnlSlides.AutoScrollPosition.X
        Dim bm As New Bitmap(sl.DisplayRectangle.Width, sl.DisplayRectangle.Height)
        Dim ox As Integer = e.X
        Dim oy As Integer = e.Y
        sl.DrawToBitmap(bm, sl.DisplayRectangle)
        Using DragForm As New Form
          DragForm.Width = bm.Width
          DragForm.Height = bm.Height
          DragForm.BackgroundImage = bm
          DragForm.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedSingle
          DragForm.ControlBox = False
          DragForm.Opacity = 0.5
          DragForm.Location = New Point(MousePosition.X - ox, MousePosition.Y - oy)
          DragForm.ShowInTaskbar = False
          DragForm.Show()
          Dim invalidateFlag As Boolean = False
          Dim MouseLocationX, MouseLocationY As Integer
          Dim OnPanel, OnBin As Boolean
          While GetAsyncKeyState(Keys.RButton) <> 0
            MouseLocationX = MousePosition.X - Me.Location.X
            MouseLocationY = MousePosition.Y - Me.Location.Y
            OnPanel = (MouseLocationY > 400 And MouseLocationY < 530)
            OnBin = (MouseLocationX >= 920 And MouseLocationX <= 940 And MouseLocationY >= 350 And MouseLocationY <= 374)
            Select Case True
              Case OnPanel
                DragForm.Show()
                DragForm.Location = New Point(MousePosition.X - ox, MousePosition.Y - oy)
                If MouseLocationX < 0 And pnlSlides.HorizontalScroll.Value >= 16 Then
                  pnlSlides.HorizontalScroll.Value -= 4
                  invalidateFlag = True
                End If
                If MouseLocationX > 900 And pnlSlides.HorizontalScroll.Value < pnlSlides.HorizontalScroll.Maximum - 16 Then
                  pnlSlides.HorizontalScroll.Value += 4
                  invalidateFlag = True
                End If
                CursorPos = (DragForm.Location.X - Me.Location.X + pnlSlides.HorizontalScroll.Value + 120) \ SlideSpace
                If CursorPos <> PreviousCursorPos Then
                  PreviousCursorPos = CursorPos
                  invalidateFlag = True
                End If
                If invalidateFlag Then
                  pnlSlides.Invalidate()
                  Application.DoEvents()
                  invalidateFlag = False
                End If
              Case OnBin
                DragForm.Show()
                DragForm.Location = New Point(MousePosition.X - ox, MousePosition.Y - oy)
              Case Else
                DragForm.Hide()
            End Select
          End While
          Select Case True
            Case OnPanel
              MoveSlide(sl.Index, CursorPos)
              RepositionSlides()
              pnlSlides.AutoScrollPosition = New Point(ScrollPosition, 0)
              Modify(True)
            Case OnBin
              RemoveSlide(sl.Index)
              Modify(True)
          End Select
        End Using
      End If
    End If
  End Sub
  Private Sub RemoveSlide(ByVal index)
    Dim s As SlideType
    For Each c As Control In pnlSlides.Controls
      s = c
      If s.Index = index Then
        If s.SelectFlag Then SetSelectedSlide(Nothing)
        's.Image.Dispose()
        s.Dispose()
        pnlSlides.Controls.Remove(c) ' Remove the current Slide
        RecalculateIndices()
        RepositionSlides()
        Exit For
      End If
    Next
  End Sub
  Private Sub MoveSlide(ByVal oldpos, ByVal newpos)
    If newpos > oldpos Or newpos < oldpos - 1 Then
      If newpos > oldpos Then
        For Each s As SlideType In pnlSlides.Controls
          Select Case True
            Case ((s.Index > oldpos) And (s.Index <= newpos)) : s.Index -= 1
            Case s.Index = oldpos : s.Index = newpos
          End Select
        Next
      Else
        newpos += 1
        For Each s As SlideType In pnlSlides.Controls
          Select Case True
            Case s.Index >= newpos And s.Index < oldpos : s.Index += 1
            Case s.Index = oldpos : s.Index = newpos
          End Select
        Next
      End If
    End If
  End Sub
  Public Sub SetSelectedSlide(ByVal slide)
    If SelectedSlide IsNot Nothing Then
      SelectedSlide.SelectSlide(False)
    End If
    SelectedSlide = slide
    If slide Is Nothing Then
      ClearStartFinishPanels()
      EnablePanControls("NULL")
    Else
      SelectedSlide.SelectSlide(True)
      RedrawStartFinishPanels()
    End If
  End Sub
  Private Sub RedrawPanControls(ByVal slide)
    NumericUpDown1.Value = MinMax(slide.Interval2 / 1000, NumericUpDown1.Maximum, NumericUpDown1.Minimum)
    NumericUpDown2.Value = slide.Interval1 / 1000
    NumericUpDown3.Value = slide.Interval3 / 1000
    CheckBox1.Checked = slide.PanFlag
    CheckBox2.Checked = slide.PauseFlag
    EnablePanControls(slide.Type)
    ScrollPanel(slide.Index)
  End Sub
  Private Function MinMax(ByVal a, ByVal b, ByVal c)
    If a > b Then Return b
    If a < c Then Return c
    Return a
  End Function
  Private Sub EnablePanControls(ByVal type)
    Dim f As Boolean = (type = "IMAGE")
    Dim g As Boolean = (type = "IMAGE" Or type = "BLANK")
    CheckBox1.Enabled = f
    CheckBox2.Enabled = g
    NumericUpDown1.Enabled = g
    NumericUpDown2.Enabled = g
    NumericUpDown3.Enabled = g
    Label2.Enabled = f
    Label6.Enabled = f
    Label7.Enabled = f
    Button2.Enabled = f
    RestoreMinButton1.Enabled = f
    RestoreMaxButton1.Enabled = f
    RestoreMinButton2.Enabled = f
    RestoreMaxButton2.Enabled = f
  End Sub
  Private Sub ClearStartFinishPanels()
    picPhotoStart.Image = Nothing
    picPhotoFinish.Image = Nothing
    CheckBox1.Checked = False
    NumericUpDown1.Value = 0
  End Sub
  Private Sub RedrawStartFinishPanels()
    If SelectedSlide Is Nothing Then Exit Sub
    Using TemporaryImage As Bitmap = SelectedSlide.GetImage
      picPhotoStart.Image = New Bitmap(TemporaryImage)
      picPhotoFinish.Image = picPhotoStart.Image
    End Using
    ReDrawPhotoStart(SelectedSlide)
    ReDrawPhotoFinish(SelectedSlide)
    RedrawPanControls(SelectedSlide)
  End Sub
  Public Function AddSlide(ByVal Type As String, ByVal f As Boolean) As SlideType
    'if f = true then adds after selected slide, otherwise at end
    Dim NewSlide As SlideType = New SlideType(Type)
    If SelectedSlide Is Nothing Then f = False
    NewSlide.Index = pnlSlides.Controls.Count + 1
    pnlSlides.Controls.Add(NewSlide)
    pnlSlides.Controls(NewSlide.Index - 1).Top = 8
    pnlSlides.Controls(NewSlide.Index - 1).Left = (NewSlide.Index - 1) * SlideSpace + Gutter + pnlSlides.AutoScrollPosition.X
    ScrollPanel(NewSlide.Index)
    pnlSlides.Invalidate() : Application.DoEvents()
    Modify(True)
    ' Set up the event handler
    AddHandler NewSlide.SlideMouseDown, AddressOf OnSlideMouseDown
    If f Then
      MoveSlide(NewSlide.Index, SelectedSlide.Index)
      SetSelectedSlide(NewSlide)
    End If
    Return NewSlide
  End Function
  Public Sub RemoveSlides(ByVal f)
    ' f = True - remove all slides else remove disabled slides only
    Dim s As SlideType
    Dim done As Boolean
    'must repeat several times as the for-each loop misses out
    'a control every time one is removed
    Do
      done = True
      For Each c As Control In pnlSlides.Controls
        s = c
        If s.EnableFlag = False Or f Then
          If s.SelectFlag Then SetSelectedSlide(Nothing)
          's.Image.Dispose()
          s.Dispose()
          pnlSlides.Controls.Remove(c) ' Remove the current Slide
          Modify(True)
          done = False
        End If
      Next
    Loop Until done
    RecalculateIndices()
    RepositionSlides()
  End Sub
  Private Sub SetPauseFlags(ByVal f)
    Dim s As SlideType
    For Each c As Control In pnlSlides.Controls
      s = c
      s.PauseFlag = f
    Next
    Me.CheckBox2.Checked = f
  End Sub
  Private Sub ResetAllSlides()
    If MsgBox("You are about to reset all the slides. Please confirm.", MsgBoxStyle.OkCancel) = MsgBoxResult.Ok Then
      Dim s As SlideType
      For Each c As Control In pnlSlides.Controls
        s = c
        s.SetDefaultFactors()
      Next
      If SelectedSlide IsNot Nothing Then
        ReDrawPhotoStart(SelectedSlide)
        ReDrawPhotoFinish(SelectedSlide)
        RedrawPanControls(SelectedSlide)
      End If
      Modify(True)
    End If
  End Sub
  Private Sub RecalculateIndices()
    Dim index As Integer = 0
    Dim cs As SlideType = Nothing
    Do
      cs = FindNextSlide(index)
      If cs IsNot Nothing Then index += 1 : cs.Index = index
    Loop Until cs Is Nothing
  End Sub
  Private Function FindNextSlide(ByVal index)
    Dim s, cs As SlideType
    cs = Nothing
    Dim i As Integer = 9999999
    Dim j As Integer
    For Each c As Control In pnlSlides.Controls
      If c.GetType Is GetType(SlideType) Then
        s = c
        j = s.Index - index
        If j > 0 And j < i Then cs = s : i = j
      End If
    Next
    Return cs
  End Function
  Private Function FindnextblankslideIndex(ByVal index)
    Dim s, cs As SlideType
    cs = Nothing
    Dim i As Integer = 9999999
    Dim j As Integer
    For Each c As Control In pnlSlides.Controls
      If c.GetType Is GetType(SlideType) Then
        s = c
        If s.Type = "BLANK" Then
          j = s.Index - index
          If j > 0 And j < i Then cs = s : i = j
        End If
      End If
    Next
    If cs IsNot Nothing Then Return cs.Index
    Return pnlSlides.Controls.Count + 1
  End Function
  Private Sub RepositionSlides()
    Dim s As SlideType
    For Each c As Control In pnlSlides.Controls
      If c.GetType Is GetType(SlideType) Then
        s = c
        c.Left = (s.Index - 1) * SlideSpace + Gutter + pnlSlides.AutoScrollPosition.X
        c.Top = 8
      End If
    Next
    Modify(True)
  End Sub
  Private Sub UpdateTotalTime()
    Dim totaltime As Integer = 0
    For Each c As Control In pnlSlides.Controls
      If c.GetType Is GetType(SlideType) Then
        Dim s As SlideType = c
        totaltime += My.Settings.FadeTime * 1000 + s.Interval1 + s.Interval2 + s.Interval3
      End If
    Next
    totaltime = CInt(totaltime / 60000)
    Label5.Text = "Total time =" & Str(totaltime) & " minutes"
    Modify(True)
  End Sub
#End Region

#Region "Drawing routines"
  Private Sub ReDrawPhotoStart(ByVal slide As SlideType)
    If slide IsNot Nothing Then
      picPhotoStart.Height = CInt(picPhotoStart.Image.Height * slide.ZfactorStart / ScaleFactor)
      picPhotoStart.Width = CInt(picPhotoStart.Image.Width * slide.ZfactorStart / ScaleFactor)
      picPhotoStart.Location = New Point(slide.OriginStart.X / ScaleFactor, slide.OriginStart.Y / ScaleFactor)
      picPhotoStart.Refresh()
      picPhotoStart.Show()
    Else
      picPhotoStart.Hide()
    End If
  End Sub
  Private Sub ReDrawPhotoFinish(ByVal slide As SlideType)
    If slide IsNot Nothing Then
      picPhotoFinish.Height = CInt(picPhotoFinish.Image.Height * slide.ZfactorFinish / ScaleFactor)
      picPhotoFinish.Width = CInt(picPhotoFinish.Image.Width * slide.ZfactorFinish / ScaleFactor)
      picPhotoFinish.Location = New Point(slide.OriginFinish.X / ScaleFactor, slide.OriginFinish.Y / ScaleFactor)
      picPhotoFinish.Refresh()
      picPhotoFinish.Show()
    Else
      picPhotoFinish.Hide()
    End If
  End Sub
#End Region

#Region "Button routines"
  Private Sub RestoreMinButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RestoreMinButton1.Click
    If SelectedSlide IsNot Nothing Then
      SelectedSlide.ZfactorStart = SelectedSlide.ZFactorMin
      SelectedSlide.OriginStart = SelectedSlide.FindCentreStart
      ReDrawPhotoStart(SelectedSlide)
      SelectedSlide.SetInterval2()
      RedrawPanControls(SelectedSlide)
    End If
  End Sub
  Private Sub RestoreMaxButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RestoreMaxButton1.Click
    If SelectedSlide IsNot Nothing Then
      SelectedSlide.ZfactorStart = SelectedSlide.ZFactorMax(False)
      SelectedSlide.OriginStart = SelectedSlide.FindCentreStart()
      ReDrawPhotoStart(SelectedSlide)
      SelectedSlide.SetInterval2()
      RedrawPanControls(SelectedSlide)
    End If
  End Sub
  Private Sub RestoreMinButton2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RestoreMinButton2.Click
    If SelectedSlide IsNot Nothing Then
      SelectedSlide.ZfactorFinish = SelectedSlide.ZFactorMin()
      SelectedSlide.OriginFinish = SelectedSlide.FindCentreFinish()
      ReDrawPhotoFinish(SelectedSlide)
      SelectedSlide.SetInterval2()
      RedrawPanControls(SelectedSlide)
    End If
  End Sub
  Private Sub RestoreMaxButton2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RestoreMaxButton2.Click
    If SelectedSlide IsNot Nothing Then
      SelectedSlide.ZfactorFinish = SelectedSlide.ZFactorMax(False)
      SelectedSlide.OriginFinish = SelectedSlide.FindCentreFinish()
      ReDrawPhotoFinish(SelectedSlide)
      SelectedSlide.SetInterval2()
      RedrawPanControls(SelectedSlide)
    End If
  End Sub
  Private Sub EqualiseButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
    If SelectedSlide IsNot Nothing Then
      SelectedSlide.ZfactorFinish = SelectedSlide.ZfactorStart
      SelectedSlide.OriginFinish = SelectedSlide.OriginStart
      ReDrawPhotoFinish(SelectedSlide)
      SelectedSlide.SetInterval2()
      RedrawPanControls(SelectedSlide)
    End If
  End Sub
  Private Sub Reset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    If SelectedSlide IsNot Nothing Then
      SelectedSlide.SetDefaultFactors()
      RedrawPanControls(SelectedSlide)
      ReDrawPhotoStart(SelectedSlide)
      ReDrawPhotoFinish(SelectedSlide)
    End If
  End Sub
  Private Sub EditCaption_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    If SelectedSlide Is Nothing Then MsgBox("Please select a slide to edit.") : Exit Sub
    CaptionDialog.TextBox1.Text = SelectedSlide.Caption
    CaptionDialog.NumericUpDown1.Value = limit(SelectedSlide.PointSize, 8, 100)
    If CaptionDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
      SelectedSlide.Caption = CaptionDialog.TextBox1.Text
      SelectedSlide.PointSize = CaptionDialog.NumericUpDown1.Value
      If SelectedSlide.Type = "BLANK" Then SelectedSlide.CreateCaptionSlide()
      SelectedSlide.DrawSlide()
      RedrawStartFinishPanels()
    End If
  End Sub
  Private Sub Rename_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
    If SelectedSlide Is Nothing Then MsgBox("Please select a slide to rename.") : Exit Sub
    RenameSlide(SelectedSlide)
  End Sub
  Private Sub RenameSlide(ByVal slide As SlideType)
    Dim sfile As String = slide.Filename
    RenameDialog.TextBox1.Text = IO.Path.GetFileNameWithoutExtension(sfile)
    RenameDialog.TextBox1.Focus()
    If RenameDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
      If RenameDialog.CheckBox1.Checked Then
        ' delete the source file
        FrameA.Finish()
        FrameB.Finish()
        If Not testing And FindNextSlide() Then FrameA.Start(2)
        My.Computer.FileSystem.DeleteFile(sfile)
        RemoveSlide(slide.Index)
        Modify(True)
      Else
        If RenameDialog.CheckBox3.Checked And RenameDialog.TextBox1.Text <> "" Then
          Dim newname = RenameDialog.TextBox1.Text & IO.Path.GetExtension(sfile)
          If File.Exists(IO.Path.GetDirectoryName(sfile) & "\" & newname) Then
            MsgBox("A file with this name already exists. Choose another name")
          Else
            My.Computer.FileSystem.RenameFile(sfile, newname)
            slide.Filename = IO.Path.GetDirectoryName(sfile) & "\" & newname
            sfile = slide.Filename
            Dim x, y As Integer
            FrameA.Label1.Text = slide.Caption
            FrameB.Label1.Text = slide.Caption
            x = (ScreenSize.Width - FrameA.Label1.Width) / 2
            y = ScreenSize.Height - FrameA.Label1.Height - 50
            FrameA.Label1.Location = New Point(x, y)
            FrameB.Label1.Location = New Point(x, y)
          End If
        End If
        If RenameDialog.CheckBox2.Checked Then
          RotateFile(sfile, RenameDialog.RadioButton2.Checked)
          slide.Filename = sfile ' this updates the thumbnail
          SetSelectedSlide(slide)
          FrameA.Finish()
          FrameB.Finish()
          FrameA.Start(2)
        End If
      End If
    End If
  End Sub
  Private Sub RotateFile(ByVal filename As String, ByVal direction As Boolean)
    ' direction = false : rotate clockwise
    ' direction = true : rotate anti-clockwise
    Dim bm1 As New Bitmap(filename)
    Dim bm2 As New Bitmap(bm1)
    bm1.Dispose()
    If direction Then
      bm2.RotateFlip(RotateFlipType.Rotate270FlipNone)
    Else
      bm2.RotateFlip(RotateFlipType.Rotate90FlipNone)
    End If
    bm2.Save(filename, ImageFormat.Jpeg)
    bm2.Dispose()
  End Sub
  Private Function limit(ByVal a, ByVal b, ByVal c)
    If a < b Then Return b
    If a > c Then Return c
    Return a
  End Function
  Private Sub PlayButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PlayFromStartButton.Click
    CurrentSlide = FindNextSlide(0)
    If CurrentSlide IsNot Nothing Then
      testing = False
      ShowFrames()
    Else
      MsgBox("There are no slides to show.", MsgBoxStyle.Exclamation)
    End If
  End Sub
  Private Sub PlayButton2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PlayFromSlideButton.Click
    If SelectedSlide Is Nothing Then MsgBox("Please select a slide from which to start.") : Exit Sub
    CurrentSlide = SelectedSlide
    testing = False
    ShowFrames()
  End Sub
  Private Sub ShowFrames()
    Background.Show()
    Paused = False
    FrameA.Opacity = 0 : FrameA.Show()
    FrameB.Opacity = 0 : FrameB.Show()
    StartA()
  End Sub
  Private Sub Test_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    If SelectedSlide Is Nothing Then MsgBox("Please select a slide to test.") : Exit Sub
    CurrentSlide = SelectedSlide
    testing = True
    ShowFrames()
  End Sub
  Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
    If SelectedSlide IsNot Nothing Then
      SelectedSlide.PanFlag = CheckBox1.Checked
    End If
  End Sub
  Private Sub CheckBox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged
    If SelectedSlide IsNot Nothing Then
      SelectedSlide.PauseFlag = CheckBox2.Checked
    End If
  End Sub
  Private Sub NumericUpDown1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NumericUpDown1.ValueChanged
    If SelectedSlide IsNot Nothing Then
      SelectedSlide.Interval2 = CInt(NumericUpDown1.Value * 1000)
      UpdateTotalTime()
    End If
  End Sub
  Private Sub NumericUpDown2_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NumericUpDown2.ValueChanged
    If SelectedSlide IsNot Nothing Then
      SelectedSlide.Interval1 = CInt(NumericUpDown2.Value * 1000)
      UpdateTotalTime()
    End If
  End Sub
  Private Sub NumericUpDown3_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NumericUpDown3.ValueChanged
    If SelectedSlide IsNot Nothing Then
      SelectedSlide.Interval3 = CInt(NumericUpDown3.Value * 1000)
      UpdateTotalTime()
    End If
  End Sub
#End Region

#Region "Menu routines"
  Private Sub menuitemLoadNewSlideShow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuitemLoadSlideShow.Click
    If Not Modified OrElse MsgBox("This slideshow has been modified. Click 'OK' if you wish to overwrite it.", MsgBoxStyle.OkCancel) Then
      OpenFileDialog1.Filter = "Slide shows|*.mgl"
      OpenFileDialog1.FileName = ""
      If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
        RemoveSlides(True)
        LoadSlideShow(OpenFileDialog1.FileName)
        CurrentFilename = OpenFileDialog1.FileName
        Modify(False)
      End If
    End If
  End Sub
  Private Sub MenuitemAppendSlideshow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem6.Click
    OpenFileDialog1.Filter = "Slide shows|*.mgl"
    OpenFileDialog1.FileName = ""
    If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
      LoadSlideShow(OpenFileDialog1.FileName)
      Modify(True)
    End If
  End Sub
  Private Sub LoadSlideShow(ByVal f)
    Dim line As String
    Dim s As SlideType = Nothing
    Me.Cursor = Cursors.WaitCursor
    Using Fstream As New FileStream(f, FileMode.Open)
      Using Sreader As New StreamReader(Fstream)
        Try
          line = Sreader.ReadLine
          If line <> "MAGIC LANTERN file" Then Throw New Exception
          While Sreader.Peek > -1
            line = Sreader.ReadLine
            If line.StartsWith("SCREEN SIZE") Then ScreenSize = GetSize(line.Substring(20))
            If line.StartsWith("WIDESCREEN FACTOR") Then WsFactor = line.Substring(20)
            If line.StartsWith("SHOW CAPTION") Then ShowCaption = line.Substring(20) = "True"
            If line.StartsWith("NEW SLIDE") Then s = AddSlide(line.Substring(20), False)
            If s IsNot Nothing Then
              If line.StartsWith("FILENAME") Then s.Filename = line.Substring(20)
              If line.StartsWith("CAPTION") Then
                line = line.Substring(20)
                If line <> "" Then
                  line = line.Replace("|", vbNewLine)
                  s.Caption = line
                  If s.Type = "BLANK" Then s.CreateCaptionSlide()
                  s.DrawSlide()
                End If
              End If
              'duration of movies is set at runtime
              If line.StartsWith("INTERVAL1") Then s.Interval1 = line.Substring(20)
              If line.StartsWith("DURATION") And s.Type <> "MOVIE" Then s.Interval2 = line.Substring(20)
              If line.StartsWith("INTERVAL3") Then s.Interval3 = line.Substring(20)
              If line.StartsWith("POINT SIZE") Then s.PointSize = line.Substring(20)
              If s.PointSize < 8 Then s.PointSize = 8
              If s.Type = "IMAGE" Then
                If line.StartsWith("START ZFACTOR") Then s.ZfactorStart = line.Substring(20)
                If line.StartsWith("FINISH ZFACTOR") Then s.ZfactorFinish = line.Substring(20)
                If line.StartsWith("START ORIGIN") Then s.OriginStart = GetPoint(line.Substring(20))
                If line.StartsWith("FINISH ORIGIN") Then s.OriginFinish = GetPoint(line.Substring(20))
                If line.StartsWith("PAN FLAG") Then s.PanFlag = line.Substring(20)
                If line.StartsWith("PAUSE FLAG") Then s.PauseFlag = line.Substring(20)
                ' only copy enabled flag if file exists
                If line.StartsWith("EANABLE FLAG") Then
                  If s.EnableFlag = True Then
                    s.EnableFlag = line.Substring(20)
                  End If
                End If
              End If
            End If
          End While
          ChangeScreenSize(False)
          UpdateTotalTime()
          CheckBox3.Checked = ShowCaption
        Catch
          MsgBox("This file is either corrupt or not a Magic Lantern file.")
        End Try
      End Using
    End Using
    Me.Cursor = Cursors.Arrow
  End Sub
  Private Function GetSize(ByVal str As String) As Size
    Dim p As Size
    p.Width = Val(str.Substring(str.IndexOf("Width=") + 6))
    p.Height = Val(str.Substring(str.IndexOf("Height=") + 7))
    Return p
  End Function
  Private Function GetPoint(ByVal str As String) As Point
    Dim p As Point
    p.X = Val(str.Substring(str.IndexOf("X=") + 2))
    p.Y = Val(str.Substring(str.IndexOf("Y=") + 2))
    Return p
  End Function
  Private Sub menuitemSaveSlideShow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuitemSaveSlideShow.Click
    SaveFileDialog1.Filter = "Slide shows|*.mgl"
    SaveFileDialog1.FileName = CurrentFilename
    If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
      Try
        Me.Cursor = Cursors.WaitCursor
        Using Fstream As New FileStream(SaveFileDialog1.FileName, FileMode.Create)
          Using Swriter As New StreamWriter(Fstream)
            Swriter.WriteLine("MAGIC LANTERN file")
            Swriter.WriteLine("NB all data must start 20 characters in.")
            Swriter.WriteLine("ie                  here")
            Swriter.WriteLine("SCREEN SIZE:        " & ScreenSize.ToString)
            Swriter.WriteLine("WIDESCREEN FACTOR:  " & WsFactor)
            Swriter.WriteLine("SHOW CAPTION:       " & Showcaption.ToString)
            Swriter.WriteLine("---------------------------------------")
            Dim s As SlideType
            s = FindNextSlide(0)
            Dim line As String
            While s IsNot Nothing
              If s.Type <> "NOT FOUND" Then
                Swriter.WriteLine("NEW SLIDE:          " & s.Type)
                Swriter.WriteLine("FILENAME:           " & s.Filename)
                line = s.Caption
                line = line.Replace(vbNewLine, "|")
                Swriter.WriteLine("CAPTION:            " & line)
                Swriter.WriteLine("POINT SIZE:         " & s.PointSize)
                Swriter.WriteLine("INTERVAL1:          " & s.Interval1)
                Swriter.WriteLine("DURATION:           " & s.Interval2)
                Swriter.WriteLine("INTERVAL3:          " & s.Interval3)
                Swriter.WriteLine("ENABLE FLAG:        " & s.EnableFlag)
                If s.Type = "IMAGE" Then
                  Swriter.WriteLine("START ZFACTOR:      " & s.ZfactorStart)
                  Swriter.WriteLine("FINISH ZFACTOR:     " & s.ZfactorFinish)
                  Swriter.WriteLine("START ORIGIN:       " & s.OriginStart.ToString)
                  Swriter.WriteLine("FINISH ORIGIN:      " & s.OriginFinish.ToString)
                  Swriter.WriteLine("PAN FLAG:           " & s.PanFlag)
                  Swriter.WriteLine("PAUSE FLAG:         " & s.PauseFlag)
                End If
                Swriter.WriteLine("---------------------------------------")
              End If
              s = FindNextSlide(s.Index)
            End While
          End Using
        End Using
        CurrentFilename = SaveFileDialog1.FileName
        Modify(False)
      Catch
        MsgBox("This file may not have been saved correctly. Please check and try again if necessary.")
      End Try
      Me.Cursor = Cursors.Arrow
    End If
  End Sub
  Private Sub DefaultParas_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem8.Click
    DefaultParameters.ShowDialog()
  End Sub
  Private Sub menuitemExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuitemExit.Click
    ExitProgram()
  End Sub
  Private Sub AddBlankSlide_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem1.Click
    CaptionDialog.TextBox1.Text = ""
    CaptionDialog.NumericUpDown1.Value = 20
    If CaptionDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
      Dim newslide As SlideType = AddSlide("BLANK", True)
      newslide.Filename = ""
      newslide.Caption = CaptionDialog.TextBox1.Text
      newslide.PointSize = CaptionDialog.NumericUpDown1.Value
      newslide.CreateCaptionSlide()
      newslide.DrawSlide()
      RepositionSlides()
    End If
  End Sub
  Private Sub AddTerminalSlide_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem5.Click
    Dim newslide As SlideType = AddSlide("BLANK", False)
    newslide.Filename = ""
    newslide.Caption = "The End"
    newslide.PointSize = 36
    newslide.CreateCaptionSlide()
    newslide.DrawSlide()
    RepositionSlides()
  End Sub
  Private Sub menuitemRemoveAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuitemRemoveAll.Click
    RemoveSlides(True)
    Modify(False)
  End Sub
  Private Sub menuitemRemoveSelected_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuitemRemoveSelected.Click
    RemoveSlides(False)
  End Sub
  Private Sub menuitemAddFolder_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuitemAddFolder.Click
    Dim startindex As Integer = pnlSlides.Controls.Count + 1
    Using dlg As New FolderBrowserDialog
      If dlg.ShowDialog = DialogResult.OK Then
        Me.Cursor = Cursors.WaitCursor
        AddSlide("BLANK", False).Filename = dlg.SelectedPath
        For Each objFile As FileInfo In New DirectoryInfo(dlg.SelectedPath).GetFiles()
          Select Case True
            Case IsImage(objFile.FullName) : AddSlide("IMAGE", False).Filename = objFile.FullName
            Case IsMovie(objFile.FullName) : AddSlide("MOVIE", False).Filename = objFile.FullName
          End Select
        Next
        UpdateTotalTime()
        SortSlides(startindex)
        Me.Cursor = Cursors.Arrow
      End If
    End Using
  End Sub
  Private Sub menuitemAddIndividual_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuitemAddIndividual.Click
    Dim dlg As New OpenFileDialog
    dlg.Multiselect = True
    dlg.Filter = "Images and movies|*.jpg;*.jpeg,*.mpg;*.mov"
    Dim iSlideCount As Integer = 0
    ' Show the dialog and check that the user pressed OK to close it - not cancel
    If dlg.ShowDialog = DialogResult.OK Then
      Me.Cursor = Cursors.WaitCursor ' Set the Forms cursor to a hour glass
      Dim filenames() As String = dlg.FileNames
      For i As Integer = 0 To filenames.Length - 1
        Select Case True
          Case IsImage(filenames(i)) : AddSlide("IMAGE", False).Filename = filenames(i)
          Case IsMovie(filenames(i)) : AddSlide("MOVIE", False).Filename = filenames(i)
        End Select
      Next
      RepositionSlides()
      Me.Cursor = Cursors.Arrow ' Return the cursor to an arrow
    End If
    dlg.Dispose()
  End Sub
  Private Sub menuitemEnableAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles menuitemEnableAll.Click
    For Each c As SlideType In pnlSlides.Controls
      If c.EnableFlag = False Then
        c.EnableFlag = True
        c.DrawSlide()
      End If
    Next
  End Sub
  Private Sub SortByNumberToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SortByNumberToolStripMenuItem.Click
    If SelectedSlide Is Nothing Then
      MsgBox("Please select the slide from which you wish the sort to start. Note that sorting is restricted to those slides lying between two caption slides.")
      Exit Sub
    End If
    Dim i As Integer = SelectedSlide.Index
    If SelectedSlide.Type = "BLANK" Then
      i += 1
    End If
    SortSlides(i)
  End Sub
  Private Sub SortSlides(ByVal indexmin As Integer)
    Dim name1 As String = ""
    Dim name2 As String
    Dim s1 As SlideType = Nothing
    Dim s2 As SlideType = Nothing
    Dim index As Integer = 0
    Dim indexmax As Integer
    Dim done As Boolean
    Me.Cursor = Cursors.WaitCursor
    indexmax = FindnextblankslideIndex(indexmin)
    index = indexmin
    Do
      done = True
      name2 = "zzzzzzz"
      ' Find the slide with the current index
      For Each c1 As Control In pnlSlides.Controls
        Dim s As SlideType = c1
        If s.Index = index Then s1 = s
      Next
      For Each c1 As Control In pnlSlides.Controls
        Dim s As SlideType = c1
        If s.Index >= index And s.Index < indexmax Then
          If s.AlphanumericName >= name1 And s.AlphanumericName < name2 Then
            name2 = s.AlphanumericName
            s2 = s
          End If
        End If
      Next
      If name2 <> "zzzzzzz" Then
        'we have found the next slide so swop indices
        done = False
        s1.Index = s2.Index : s2.Index = index
        index += 1
        name1 = name2
      End If
    Loop Until done
    RepositionSlides()
    Me.Cursor = Cursors.Arrow
  End Sub
  Private Sub OffToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OffToolStripMenuItem.Click
    SetPauseFlags(False)
  End Sub
  Private Sub OnToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OnToolStripMenuItem.Click
    SetPauseFlags(True)
  End Sub
  Private Sub ResetAllSlidesToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ResetAllSlidesToolStripMenuItem.Click
    ResetAllSlides()
  End Sub
  Private Sub X900ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles X900ToolStripMenuItem.Click
    ScreenSize = New Size(1440, 900) : WsFactor = 1
    ChangeScreenSize(True)
    X900ToolStripMenuItem.Checked = True
  End Sub
  Private Sub X800ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles X800ToolStripMenuItem.Click
    ScreenSize = New Size(1280, 800) : WsFactor = 1
    ChangeScreenSize(True)
    X800ToolStripMenuItem.Checked = True
  End Sub
  Private Sub X768ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles X768ToolStripMenuItem.Click
    ScreenSize = New Size(1024, 768) : WsFactor = 1
    ChangeScreenSize(True)
    X768ToolStripMenuItem.Checked = True
  End Sub
  Private Sub X768WideToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles X768WideToolStripMenuItem.Click
    ScreenSize = New Size(1024, 768) : WsFactor = 1.33
    ChangeScreenSize(True)
    X768WideToolStripMenuItem.Checked = True
  End Sub
  Private Sub ToolStripMenuItem2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem2.Click
    ScreenSize = New Size(1280, 720) : WsFactor = 1
    ChangeScreenSize(True)
    ToolStripMenuItem2.Checked = True
  End Sub
  Private Sub ToolStripMenuItem3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem3.Click
    ScreenSize = New Size(1920, 1080) : WsFactor = 1
    ChangeScreenSize(True)
    ToolStripMenuItem3.Checked = True
  End Sub
  Private Sub CustomSizeToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CustomSizeToolStripMenuItem.Click
    If Custom_screen_parameters.ShowDialog = Windows.Forms.DialogResult.OK Then
      Dim x, y As Integer
      Dim z As Double
      x = Val(Custom_screen_parameters.ComboBox1.Text)
      y = Val(Custom_screen_parameters.ComboBox2.Text)
      z = Val(Custom_screen_parameters.ComboBox3.Text)
      If x < 400 Or x > 4000 Or y < 400 Or y > 4000 Or z < 0.5 Or z > 2 Then
        MsgBox("These parameters are unlikely.")
      Else
        ScreenSize = New Size(x, y) : WsFactor = z
        ChangeScreenSize(True)
        CustomSizeToolStripMenuItem.Checked = True
      End If
    End If
  End Sub
  Private Sub ResetScreensizeMenu()
    X768ToolStripMenuItem.Checked = False
    X768WideToolStripMenuItem.Checked = False
    X800ToolStripMenuItem.Checked = False
    X900ToolStripMenuItem.Checked = False
    ToolStripMenuItem2.Checked = False
    ToolStripMenuItem3.Checked = False
    CustomSizeToolStripMenuItem.Checked = False
  End Sub
  Private Sub HelpToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles HelpToolStripMenuItem.Click
    If File.Exists("Magic Lantern Help.chm") Then
      Process.Start("Magic Lantern Help.chm")
    Else
      MsgBox("I cannot find a help file")
    End If
  End Sub
  Private Sub AboutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutToolStripMenuItem.Click
    AboutBox.Label4.Text = Version
    AboutBox.Show()
  End Sub
#End Region

#Region "Panel routines"
  Private Sub pnlSlides_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles pnlSlides.DragDrop
    Dim startindex As Integer = pnlSlides.Controls.Count + 1
    Dim filenames() As String = e.Data.GetData(DataFormats.FileDrop)
    For Each f As String In filenames
      Select Case True
        Case IsImage(f) : AddSlide("IMAGE", True).Filename = f
        Case IsMovie(f) : AddSlide("MOVIE", True).Filename = f
        Case IsTextfile(f) : LoadSlideShow(f)
        Case Directory.Exists(f)
          Me.Cursor = Cursors.WaitCursor
          Dim newslide As SlideType = AddSlide("BLANK", True)
          newslide.Filename = f
          newslide.CreateCaptionSlide()
          For Each objFile As FileInfo In New DirectoryInfo(f).GetFiles()
            Select Case True
              Case IsImage(objFile.FullName) : AddSlide("IMAGE", True).Filename = objFile.FullName
              Case IsMovie(objFile.FullName) : AddSlide("MOVIE", True).Filename = objFile.FullName
            End Select
          Next
          Me.Cursor = Cursors.Arrow
      End Select
    Next
    SortSlides(startindex)
    RedrawStartFinishPanels()
    UpdateTotalTime()
  End Sub
  Private Function IsImage(ByVal f)
    Return f.EndsWith(".jpg") Or f.EndsWith(".JPG") Or f.EndsWith(".JPEG") Or f.EndsWith(".jpeg")
  End Function
  Private Function IsMovie(ByVal f As String)
    Dim filetype As String = f.Substring(f.LastIndexOf(".") + 1)
    filetype = Strings.UCase(filetype)
    Return filetype = "MPG" Or filetype = "MOV" Or filetype = "AVI" Or filetype = "WMV"
  End Function
  Private Function IsTextfile(ByVal f)
    Return f.EndsWith(".txt") Or f.EndsWith(".TXT")
  End Function
  Private Sub pnlSlides_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles pnlSlides.DragEnter
    If e.Data.GetDataPresent(DataFormats.FileDrop) Then
      e.Effect = DragDropEffects.Copy
    Else
      e.Effect = DragDropEffects.None
    End If
  End Sub
  Private Sub pnlSlides_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles pnlSlides.Paint
    If CursorPos >= 0 Then
      Dim x As Integer = SlideSpace * CursorPos + pnlSlides.AutoScrollPosition.X + 2
      'Debug.Print(Str(CursorPos) & Str(pnlSlides.HorizontalScroll.Value) & Str(x))
      Dim r As New Rectangle(x, 0, 4, 140)
      e.Graphics.FillRectangle(Brushes.Black, r)
    End If
  End Sub
  Private Sub ScrollPanel(ByVal index)
    pnlSlides.AutoScrollPosition = New Point((index - 3) * SlideSpace, 0)
  End Sub
#End Region

#Region "Preview window routines"
  Private Sub picPhotoStart_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles picPhotoStart.MouseEnter
    picPhotoStart.Focus()
  End Sub
  Private Sub picPhotoStart_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picPhotoStart.MouseDown
    DraggingStart = True
    DraggingStartLocation = e.Location
  End Sub
  Private Sub picPhotoStart_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picPhotoStart.MouseMove
    If DraggingStart Then
      Dim x, y As Integer
      x = picPhotoStart.Location.X
      y = picPhotoStart.Location.Y
      x += e.Location.X - DraggingStartLocation.X
      y += e.Location.Y - DraggingStartLocation.Y
      SelectedSlide.OriginStart.X = x * ScaleFactor
      SelectedSlide.OriginStart.Y = y * ScaleFactor
      picPhotoStart.Location = New Point(x, y)
    End If
  End Sub
  Private Sub picPhotoStart_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picPhotoStart.MouseUp
    DraggingStart = False
    ReDrawPhotoStart(SelectedSlide)
    SelectedSlide.SetInterval2()
    RedrawPanControls(SelectedSlide)
  End Sub
  Private Sub picPhotoStart_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picPhotoStart.MouseWheel
    Dim z As Double = 1.2
    If e.Delta < 0 Then z = 1 / z
    If SelectedSlide.ZfactorStart > 10 And z > 1 Then Exit Sub
    SelectedSlide.ZfactorStart *= z
    SelectedSlide.OriginStart.X = ScaleFactor * pnlPhotoStart.Width * (1 - z) / 2 + SelectedSlide.OriginStart.X * z
    SelectedSlide.OriginStart.Y = ScaleFactor * pnlPhotoStart.Width * (1 - z) / 2 + SelectedSlide.OriginStart.Y * z
    SelectedSlide.SetPanFlag()
    ReDrawPhotoStart(SelectedSlide)
    SelectedSlide.SetInterval2()
    RedrawPanControls(SelectedSlide)
  End Sub
  Private Sub picPhotoFinish_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles picPhotoFinish.MouseEnter
    picPhotoFinish.Focus()
  End Sub
  Private Sub picPhotoFinish_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picPhotoFinish.MouseDown
    DraggingFinish = True
    draggingFinishLocation = e.Location
  End Sub
  Private Sub picPhotoFinish_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picPhotoFinish.MouseMove
    If DraggingFinish Then
      Dim x, y As Integer
      x = picPhotoFinish.Location.X
      y = picPhotoFinish.Location.Y
      x += e.Location.X - draggingFinishLocation.X
      y += e.Location.Y - draggingFinishLocation.Y
      SelectedSlide.OriginFinish.X = x * ScaleFactor
      SelectedSlide.OriginFinish.Y = y * ScaleFactor
      picPhotoFinish.Location = New Point(x, y)
    End If
  End Sub
  Private Sub picPhotoFinish_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picPhotoFinish.MouseUp
    DraggingFinish = False
    ReDrawPhotoFinish(SelectedSlide)
    SelectedSlide.SetInterval2()
    RedrawPanControls(SelectedSlide)
  End Sub
  Private Sub picPhotoFinish_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picPhotoFinish.MouseWheel
    Dim z As Double = 1.2
    If e.Delta < 0 Then z = 1 / z
    If SelectedSlide.ZfactorStart > 10 And z > 1 Then Exit Sub
    SelectedSlide.ZfactorFinish *= z
    SelectedSlide.OriginFinish.X = ScaleFactor * pnlPhotoFinish.Width * (1 - z) / 2 + SelectedSlide.OriginFinish.X * z
    SelectedSlide.OriginFinish.Y = ScaleFactor * pnlPhotoFinish.Width * (1 - z) / 2 + SelectedSlide.OriginFinish.Y * z
    SelectedSlide.SetPanFlag()
    ReDrawPhotoFinish(SelectedSlide)
    SelectedSlide.SetInterval2()
    RedrawPanControls(SelectedSlide)
  End Sub
#End Region

  Private Sub CheckBox3_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox3.CheckedChanged
    ShowCaption = CheckBox3.Checked
  End Sub


End Class
