Imports System.ComponentModel
Imports System.Text.RegularExpressions
Imports System.Drawing.Design

Imports Stax
Imports Stax.DynamicObject
Imports Stax.UI
Imports Stax.ComponentModel
Imports Stax.AppFramework

Public Class PreviewForm
    Inherits ExtendedForm

#Region " Vom Windows Form Designer generierter Code "
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    ' Für Windows Form-Designer erforderlich
    Private components As System.ComponentModel.IContainer

    'HINWEIS: Die folgende Prozedur ist für den Windows Form-Designer erforderlich
    'Sie kann mit dem Windows Form-Designer modifiziert werden.
    'Verwenden Sie nicht den Code-Editor zur Bearbeitung.
    Friend WithEvents pVideo As System.Windows.Forms.Panel
    Friend WithEvents pTrack As System.Windows.Forms.Panel
    Private WithEvents bDeleteRange As System.Windows.Forms.Button
    Private WithEvents bForward1 As System.Windows.Forms.Button
    Private WithEvents bRangeStart As System.Windows.Forms.Button
    Private WithEvents bRangeEnd As System.Windows.Forms.Button
    Private WithEvents bForward10 As System.Windows.Forms.Button
    Private WithEvents bBackward10 As System.Windows.Forms.Button
    Private WithEvents bExtras As System.Windows.Forms.Button
    Private WithEvents bForward100 As System.Windows.Forms.Button
    Private WithEvents bBackward100 As System.Windows.Forms.Button
    Private WithEvents bBackward1 As System.Windows.Forms.Button
    Friend WithEvents il2212 As System.Windows.Forms.ImageList
    Friend WithEvents cmsMain As System.Windows.Forms.ContextMenuStrip
    Friend WithEvents ToolTip As System.Windows.Forms.ToolTip
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container
        Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(PreviewForm))
        Me.bDeleteRange = New System.Windows.Forms.Button
        Me.il2212 = New System.Windows.Forms.ImageList(Me.components)
        Me.bForward1 = New System.Windows.Forms.Button
        Me.bBackward1 = New System.Windows.Forms.Button
        Me.bRangeStart = New System.Windows.Forms.Button
        Me.bRangeEnd = New System.Windows.Forms.Button
        Me.bForward10 = New System.Windows.Forms.Button
        Me.bBackward10 = New System.Windows.Forms.Button
        Me.bExtras = New System.Windows.Forms.Button
        Me.bForward100 = New System.Windows.Forms.Button
        Me.bBackward100 = New System.Windows.Forms.Button
        Me.pVideo = New System.Windows.Forms.Panel
        Me.cmsMain = New System.Windows.Forms.ContextMenuStrip(Me.components)
        Me.pTrack = New System.Windows.Forms.Panel
        Me.ToolTip = New System.Windows.Forms.ToolTip(Me.components)
        Me.pVideo.SuspendLayout()
        Me.SuspendLayout()
        '
        'bDeleteRange
        '
        Me.bDeleteRange.Anchor = System.Windows.Forms.AnchorStyles.Bottom
        Me.bDeleteRange.BackColor = System.Drawing.Color.White
        Me.bDeleteRange.FlatStyle = System.Windows.Forms.FlatStyle.Flat
        Me.bDeleteRange.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.bDeleteRange.ImageIndex = 5
        Me.bDeleteRange.ImageList = Me.il2212
        Me.bDeleteRange.Location = New System.Drawing.Point(360, 280)
        Me.bDeleteRange.Name = "bDeleteRange"
        Me.bDeleteRange.Size = New System.Drawing.Size(32, 24)
        Me.bDeleteRange.TabIndex = 47
        Me.bDeleteRange.TabStop = False
        Me.ToolTip.SetToolTip(Me.bDeleteRange, "Deletes the cut selection that encloses the current position.")
        Me.bDeleteRange.UseVisualStyleBackColor = False
        '
        'il2212
        '
        Me.il2212.ImageStream = CType(resources.GetObject("il2212.ImageStream"), System.Windows.Forms.ImageListStreamer)
        Me.il2212.Images.SetKeyName(0, "")
        Me.il2212.Images.SetKeyName(1, "")
        Me.il2212.Images.SetKeyName(2, "")
        Me.il2212.Images.SetKeyName(3, "")
        Me.il2212.Images.SetKeyName(4, "")
        Me.il2212.Images.SetKeyName(5, "")
        Me.il2212.Images.SetKeyName(6, "")
        Me.il2212.Images.SetKeyName(7, "")
        Me.il2212.Images.SetKeyName(8, "")
        Me.il2212.Images.SetKeyName(9, "")
        '
        'bForward1
        '
        Me.bForward1.Anchor = System.Windows.Forms.AnchorStyles.Bottom
        Me.bForward1.BackColor = System.Drawing.Color.White
        Me.bForward1.FlatStyle = System.Windows.Forms.FlatStyle.Flat
        Me.bForward1.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.bForward1.ImageIndex = 7
        Me.bForward1.ImageList = Me.il2212
        Me.bForward1.Location = New System.Drawing.Point(240, 280)
        Me.bForward1.Name = "bForward1"
        Me.bForward1.Size = New System.Drawing.Size(32, 24)
        Me.bForward1.TabIndex = 46
        Me.bForward1.TabStop = False
        Me.ToolTip.SetToolTip(Me.bForward1, "Forward 1 Frames")
        Me.bForward1.UseVisualStyleBackColor = False
        '
        'bBackward1
        '
        Me.bBackward1.Anchor = System.Windows.Forms.AnchorStyles.Bottom
        Me.bBackward1.BackColor = System.Drawing.Color.White
        Me.bBackward1.FlatStyle = System.Windows.Forms.FlatStyle.Flat
        Me.bBackward1.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.bBackward1.ImageIndex = 0
        Me.bBackward1.ImageList = Me.il2212
        Me.bBackward1.Location = New System.Drawing.Point(120, 280)
        Me.bBackward1.Name = "bBackward1"
        Me.bBackward1.Size = New System.Drawing.Size(32, 24)
        Me.bBackward1.TabIndex = 45
        Me.bBackward1.TabStop = False
        Me.ToolTip.SetToolTip(Me.bBackward1, "Backward 1 Frame")
        Me.bBackward1.UseVisualStyleBackColor = False
        '
        'bRangeStart
        '
        Me.bRangeStart.Anchor = System.Windows.Forms.AnchorStyles.Bottom
        Me.bRangeStart.BackColor = System.Drawing.Color.White
        Me.bRangeStart.FlatStyle = System.Windows.Forms.FlatStyle.Flat
        Me.bRangeStart.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.bRangeStart.ImageIndex = 4
        Me.bRangeStart.ImageList = Me.il2212
        Me.bRangeStart.Location = New System.Drawing.Point(160, 280)
        Me.bRangeStart.Name = "bRangeStart"
        Me.bRangeStart.Size = New System.Drawing.Size(32, 24)
        Me.bRangeStart.TabIndex = 44
        Me.bRangeStart.TabStop = False
        Me.ToolTip.SetToolTip(Me.bRangeStart, "Sets a start cut point. Please press F1 for help about cutting")
        Me.bRangeStart.UseVisualStyleBackColor = False
        '
        'bRangeEnd
        '
        Me.bRangeEnd.Anchor = System.Windows.Forms.AnchorStyles.Bottom
        Me.bRangeEnd.BackColor = System.Drawing.Color.White
        Me.bRangeEnd.FlatStyle = System.Windows.Forms.FlatStyle.Flat
        Me.bRangeEnd.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.bRangeEnd.ImageIndex = 3
        Me.bRangeEnd.ImageList = Me.il2212
        Me.bRangeEnd.Location = New System.Drawing.Point(200, 280)
        Me.bRangeEnd.Name = "bRangeEnd"
        Me.bRangeEnd.Size = New System.Drawing.Size(32, 24)
        Me.bRangeEnd.TabIndex = 43
        Me.bRangeEnd.TabStop = False
        Me.ToolTip.SetToolTip(Me.bRangeEnd, "Sets a end cut point. Please press F1 for help about cutting")
        Me.bRangeEnd.UseVisualStyleBackColor = False
        '
        'bForward10
        '
        Me.bForward10.Anchor = System.Windows.Forms.AnchorStyles.Bottom
        Me.bForward10.BackColor = System.Drawing.Color.White
        Me.bForward10.FlatStyle = System.Windows.Forms.FlatStyle.Flat
        Me.bForward10.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.bForward10.ImageIndex = 8
        Me.bForward10.ImageList = Me.il2212
        Me.bForward10.Location = New System.Drawing.Point(280, 280)
        Me.bForward10.Name = "bForward10"
        Me.bForward10.Size = New System.Drawing.Size(32, 24)
        Me.bForward10.TabIndex = 42
        Me.bForward10.TabStop = False
        Me.ToolTip.SetToolTip(Me.bForward10, "Forward 10 Frames")
        Me.bForward10.UseVisualStyleBackColor = False
        '
        'bBackward10
        '
        Me.bBackward10.Anchor = System.Windows.Forms.AnchorStyles.Bottom
        Me.bBackward10.BackColor = System.Drawing.Color.White
        Me.bBackward10.FlatStyle = System.Windows.Forms.FlatStyle.Flat
        Me.bBackward10.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.bBackward10.ImageIndex = 1
        Me.bBackward10.ImageList = Me.il2212
        Me.bBackward10.Location = New System.Drawing.Point(80, 280)
        Me.bBackward10.Name = "bBackward10"
        Me.bBackward10.Size = New System.Drawing.Size(32, 24)
        Me.bBackward10.TabIndex = 41
        Me.bBackward10.TabStop = False
        Me.ToolTip.SetToolTip(Me.bBackward10, "Backward 10 Frames")
        Me.bBackward10.UseVisualStyleBackColor = False
        '
        'bExtras
        '
        Me.bExtras.Anchor = System.Windows.Forms.AnchorStyles.Bottom
        Me.bExtras.BackColor = System.Drawing.Color.White
        Me.bExtras.FlatStyle = System.Windows.Forms.FlatStyle.Flat
        Me.bExtras.Font = New System.Drawing.Font("Microsoft Sans Serif", 15.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.bExtras.ForeColor = System.Drawing.SystemColors.ControlText
        Me.bExtras.ImageList = Me.il2212
        Me.bExtras.Location = New System.Drawing.Point(400, 280)
        Me.bExtras.Name = "bExtras"
        Me.bExtras.Size = New System.Drawing.Size(32, 24)
        Me.bExtras.TabIndex = 50
        Me.bExtras.TabStop = False
        Me.ToolTip.SetToolTip(Me.bExtras, "Shows the menu")
        Me.bExtras.UseVisualStyleBackColor = False
        '
        'bForward100
        '
        Me.bForward100.Anchor = System.Windows.Forms.AnchorStyles.Bottom
        Me.bForward100.BackColor = System.Drawing.Color.White
        Me.bForward100.FlatStyle = System.Windows.Forms.FlatStyle.Flat
        Me.bForward100.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.bForward100.ForeColor = System.Drawing.SystemColors.ControlText
        Me.bForward100.ImageIndex = 9
        Me.bForward100.ImageList = Me.il2212
        Me.bForward100.Location = New System.Drawing.Point(320, 280)
        Me.bForward100.Name = "bForward100"
        Me.bForward100.Size = New System.Drawing.Size(32, 24)
        Me.bForward100.TabIndex = 49
        Me.bForward100.TabStop = False
        Me.ToolTip.SetToolTip(Me.bForward100, "Forward 100 Frames")
        Me.bForward100.UseVisualStyleBackColor = False
        '
        'bBackward100
        '
        Me.bBackward100.Anchor = System.Windows.Forms.AnchorStyles.Bottom
        Me.bBackward100.BackColor = System.Drawing.Color.White
        Me.bBackward100.FlatStyle = System.Windows.Forms.FlatStyle.Flat
        Me.bBackward100.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.bBackward100.ForeColor = System.Drawing.SystemColors.ControlText
        Me.bBackward100.ImageIndex = 2
        Me.bBackward100.ImageList = Me.il2212
        Me.bBackward100.Location = New System.Drawing.Point(40, 280)
        Me.bBackward100.Name = "bBackward100"
        Me.bBackward100.Size = New System.Drawing.Size(32, 24)
        Me.bBackward100.TabIndex = 48
        Me.bBackward100.TabStop = False
        Me.ToolTip.SetToolTip(Me.bBackward100, "Backward 100 Frames")
        Me.bBackward100.UseVisualStyleBackColor = False
        '
        'pVideo
        '
        Me.pVideo.ContextMenuStrip = Me.cmsMain
        Me.pVideo.Controls.Add(Me.pTrack)
        Me.pVideo.Controls.Add(Me.bRangeEnd)
        Me.pVideo.Controls.Add(Me.bRangeStart)
        Me.pVideo.Controls.Add(Me.bBackward1)
        Me.pVideo.Controls.Add(Me.bForward1)
        Me.pVideo.Controls.Add(Me.bDeleteRange)
        Me.pVideo.Controls.Add(Me.bBackward100)
        Me.pVideo.Controls.Add(Me.bForward100)
        Me.pVideo.Controls.Add(Me.bExtras)
        Me.pVideo.Controls.Add(Me.bBackward10)
        Me.pVideo.Controls.Add(Me.bForward10)
        Me.pVideo.Location = New System.Drawing.Point(16, 16)
        Me.pVideo.Name = "pVideo"
        Me.pVideo.Size = New System.Drawing.Size(472, 312)
        Me.pVideo.TabIndex = 50
        '
        'cmsMain
        '
        Me.cmsMain.Enabled = True
        Me.cmsMain.GripMargin = New System.Windows.Forms.Padding(2)
        Me.cmsMain.Location = New System.Drawing.Point(24, 65)
        Me.cmsMain.Name = "cmsMain"
        Me.cmsMain.RightToLeft = System.Windows.Forms.RightToLeft.No
        Me.cmsMain.Size = New System.Drawing.Size(61, 4)
        '
        'pTrack
        '
        Me.pTrack.Anchor = CType(((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.pTrack.BackColor = System.Drawing.SystemColors.Control
        Me.pTrack.Cursor = System.Windows.Forms.Cursors.SizeNS
        Me.pTrack.Location = New System.Drawing.Point(16, 256)
        Me.pTrack.Name = "pTrack"
        Me.pTrack.Size = New System.Drawing.Size(440, 12)
        Me.pTrack.TabIndex = 51
        '
        'ToolTip
        '
        Me.ToolTip.AutoPopDelay = 5000
        Me.ToolTip.BackColor = System.Drawing.Color.White
        Me.ToolTip.InitialDelay = 100
        Me.ToolTip.ReshowDelay = 100
        '
        'PreviewForm
        '
        Me.BackColor = System.Drawing.Color.Black
        Me.ClientSize = New System.Drawing.Size(506, 352)
        Me.Controls.Add(Me.pVideo)
        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog
        Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
        Me.KeyPreview = True
        Me.MaximizeBox = False
        Me.MinimizeBox = False
        Me.Name = "PreviewForm"
        Me.Text = "Preview"
        Me.pVideo.ResumeLayout(False)
        Me.ResumeLayout(False)

    End Sub

#End Region

    Public AVI As New AVIFile
    Public RangeStart As Integer = -1

    Private InfoAviSynthDocument As AviSynthDocument
    Private AviSynthDocument As AviSynthDocument
    Private ShowInfo As Boolean
    Private SizeFactor As Double = 1
    Private TargetFrames As Integer
    Private WithEvents GenericMenu As GenericMenu

    Private Const TrackBarBorder As Integer = 1
    Private Const TrackBarGap As Integer = 1
    Private Const TrackBarPosition As Integer = 4
    Private Shared Instances As New List(Of PreviewForm)

    Public Sub New(ByVal aviSynthDocument As AviSynthDocument)
        MyBase.New()
        InitializeComponent()

        GenericMenu = New GenericMenu(AddressOf GetDefaultMenu, _
            s.GenericMenuPreview, Me, cmsMain, Nothing)

        GenericMenu.BuildMenu()

        Instances.Add(Me)

        Me.AviSynthDocument = aviSynthDocument

        RefreshScript()

        If WindowState <> s.WindowStatePreview Then
            SwitchWindowState()
        End If

        ShowButtons(Not s.HidePreviewButtons)

        If Height < 200 Then
            ShowButtons(False)
            pTrack.Visible = False
        End If
    End Sub

    Public Sub RefreshScript()
        TargetFrames = p.TargetAVSDoc.GetFrames

        If ShowInfo Then
            If InfoAviSynthDocument Is Nothing Then
                InfoAviSynthDocument = New AviSynthDocument
                InfoAviSynthDocument.Path = Paths.GetTempDir + p.Name + "_Info.avs"
            End If

            InfoAviSynthDocument.Filters.Clear()

            For Each i As AviSynthFilter In AviSynthDocument.Filters
                InfoAviSynthDocument.Filters.Add(i.GetCopy)
            Next

            InfoAviSynthDocument.Filters.Add(New AviSynthFilter("Info", "Info", "Info()", True))
            InfoAviSynthDocument.Synchronize()

            AVI.Open(InfoAviSynthDocument.Path, pVideo)
        Else
            AVI.Open(AviSynthDocument.Path, pVideo)
        End If

        If WindowState = FormWindowState.Normal Then
            Normal()
        Else
            Full()
        End If

        AVI.Position = g.PreviewLastPosition
        AVI.Draw()

        AfterPositionChanged()
    End Sub

    Private Sub Full()
        pTrack.Visible = False

        FormBorderStyle = Windows.Forms.FormBorderStyle.None
        WindowState = FormWindowState.Maximized

        Dim ratio As Double = AVI.FrameSize.Width / AVI.FrameSize.Height
        Dim fullH As Integer = Screen.PrimaryScreen.Bounds.Height
        Dim fullW As Integer = Screen.PrimaryScreen.Bounds.Width

        pVideo.Dock = DockStyle.None

        If ratio > 1.333 Then
            Dim h As Integer = CInt(fullW / ratio)
            pVideo.Left = 0
            pVideo.Top = CInt((fullH - h) / 2)
            pVideo.Width = fullW
            pVideo.Height = h
        Else
            Dim w As Integer = CInt(fullH * ratio)
            pVideo.Left = CInt((fullW - w) / 2)
            pVideo.Top = 0
            pVideo.Width = w
            pVideo.Height = fullH
        End If

        pTrack.Visible = True
    End Sub

    Private Sub Normal()
        WindowState = FormWindowState.Normal
        FormBorderStyle = Windows.Forms.FormBorderStyle.FixedDialog
        pVideo.Dock = DockStyle.Fill

        ClientSize = New Size(CInt(AVI.FrameSize.Width * SizeFactor), _
            CInt(AVI.FrameSize.Height * SizeFactor))
    End Sub

    <GenericMenuMethod("Switch Window State", "Switches the window state between full and normal.")> _
    Public Sub SwitchWindowState()
        If WindowState = FormWindowState.Normal Then
            Full()
        Else
            Normal()
        End If

        AfterPositionChanged()
    End Sub

    Sub ShowButtons(ByVal vis As Boolean)
        bForward1.Visible = vis
        bBackward1.Visible = vis
        bRangeStart.Visible = vis
        bRangeEnd.Visible = vis
        bDeleteRange.Visible = vis
        bForward10.Visible = vis
        bBackward10.Visible = vis
        bForward100.Visible = vis
        bBackward100.Visible = vis
        bExtras.Visible = vis
    End Sub

    Private Sub bForward1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bForward1.Click
        For Each i As PreviewForm In Instances
            SetRelativePos(1)
        Next
    End Sub

    Private Sub bBackward1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bBackward1.Click
        For Each i As PreviewForm In Instances
            SetRelativePos(-1)
        Next
    End Sub

    Private Sub bRangeStart_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bRangeStart.Click
        For Each i As PreviewForm In Instances
            SetRangeStart()
        Next
    End Sub

    Private Sub bRangeEnd_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bRangeEnd.Click
        For Each i As PreviewForm In Instances
            SetRangeEnd()
        Next
    End Sub

    Private Sub bBackward10_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bBackward10.Click
        For Each i As PreviewForm In Instances
            SetRelativePos(-10)
        Next
    End Sub

    Private Sub bForward10_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bForward10.Click
        For Each i As PreviewForm In Instances
            SetRelativePos(10)
        Next
    End Sub

    Private Sub bDeleteRange_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bDeleteRange.Click
        For Each i As PreviewForm In Instances
            DeleteRange()
        Next
    End Sub

    Private Sub bBackward100_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bBackward100.Click
        For Each i As PreviewForm In Instances
            i.SetRelativePos(-100)
        Next
    End Sub

    Private Sub bForward100_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bForward100.Click
        For Each i As PreviewForm In Instances
            SetRelativePos(100)
        Next
    End Sub

    Private Sub PreviewForm_ActivatedFirstTime() Handles Me.ActivatedFirstTime
        If Not s.StringList.Contains(Me.GetType.FullName) Then
            OpenHelp()
            s.StringList.Add(Me.GetType.FullName)
        End If
    End Sub

    Private Sub Wheel(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseWheel
        If e.Delta > 0 Then
            If Control.ModifierKeys = Keys.Alt Then
                AVI.Position += 1000
            ElseIf Control.ModifierKeys = Keys.Shift Then
                AVI.Position += 100
            ElseIf Control.ModifierKeys = Keys.Control Then
                AVI.Position += 10
            Else
                AVI.Position += 1
            End If
        Else
            If Control.ModifierKeys = Keys.Alt Then
                AVI.Position -= 1000
            ElseIf Control.ModifierKeys = Keys.Shift Then
                AVI.Position -= 100
            ElseIf Control.ModifierKeys = Keys.Control Then
                AVI.Position -= 10
            Else
                AVI.Position -= 1
            End If
        End If

        AVI.Draw()
        DrawTrack()
    End Sub

    Public Sub DrawTrack()
        Dim g As Graphics = pTrack.CreateGraphics()
        g.FillRectangle(Brushes.White, pTrack.ClientRectangle)

        Dim trackWidth As Integer = pTrack.Height - TrackBarBorder * 2 - TrackBarGap * 2

        Dim borderPen As Pen = New Pen(Color.Black, TrackBarBorder)
        borderPen.Alignment = Drawing2D.PenAlignment.Inset
        g.DrawRectangle(borderPen, 0, 0, pTrack.Width - 1, pTrack.Height - 1)
        borderPen.Dispose()

        Dim rangePen As Pen = New Pen(Color.Green, trackWidth)

        For Each i As Range In p.Ranges
            g.DrawLine(rangePen, GetDrawPos(i.Start) - TrackBarPosition \ 2, _
                pTrack.Height \ 2, GetDrawPos(i.End) + TrackBarPosition \ 2, pTrack.Height \ 2)
        Next

        rangePen.Dispose()

        Dim rangeSetPen As Pen = New Pen(Color.Yellow, trackWidth)

        If RangeStart > -1 AndAlso RangeStart <= AVI.Position Then
            g.DrawLine(rangeSetPen, GetDrawPos(RangeStart) - TrackBarPosition \ 2, _
                pTrack.Height \ 2, GetDrawPos(AVI.Position) + _
                TrackBarPosition \ 2, pTrack.Height \ 2)
        End If

        rangeSetPen.Dispose()
        Dim posPen As Pen

        If RangeStart > -1 Then
            posPen = New Pen(Color.Yellow, trackWidth)
        Else
            posPen = New Pen(Color.Blue, trackWidth)
        End If

        Dim pos As Integer = GetDrawPos(AVI.Position)
        g.DrawLine(posPen, pos - TrackBarPosition \ 2, pTrack.Height \ 2, pos + TrackBarPosition \ 2, pTrack.Height \ 2)
        posPen.Dispose()

        g.Dispose()
    End Sub

    Private Function GetDrawPos(ByVal frame As Integer) As Integer
        Dim values As Integer = TrackBarBorder * 2 + TrackBarGap * 2 + TrackBarPosition
        Dim width As Integer = CInt(((pTrack.Width - values) / TargetFrames) * frame)

        Return width + values \ 2
    End Function

    Private Sub pTrack_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles pTrack.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            HandleMouseOntrackBar()
        End If
    End Sub

    Private Sub pTrack_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles pTrack.MouseDown
        HandleMouseOntrackBar()
    End Sub

    Private Sub HandleMouseOntrackBar()
        Dim pos As Integer = CInt((TargetFrames / pTrack.Width) * _
            pTrack.PointToClient(Control.MousePosition).X)

        Dim remainder As Integer = pos Mod 4

        If remainder <> 0 Then
            pos -= remainder
        End If

        For Each i As PreviewForm In Instances
            i.SetAbsolutePos(pos)
        Next
    End Sub

    Private Sub pTrack_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles pTrack.Paint
        DrawTrack()
    End Sub

    Private Sub bExtras_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bExtras.Click
        cmsMain.Show(bExtras, New Point(1, bExtras.Height))
    End Sub

    <GenericMenuMethod("Set Absolute Position", "Sets the absolute position.")> _
    Public Sub SetAbsolutePos(<Name("Position")> ByVal pos As Integer)
        AVI.Position = pos
        AVI.Draw()
        AfterPositionChanged()
    End Sub

    Private Sub AfterPositionChanged()
        g.PreviewLastPosition = AVI.Position
        DrawTrack()
    End Sub

    <GenericMenuMethod("Go To Frame", "Opens a dialog to jump to a specific frame or time.")> _
    Public Sub GoToFrame()
        Dim f As New GoToFrameForm
        Dim milli As Integer = CInt((AVI.Position / AVI.FrameRate) * 1000)
        Dim ts As New TimeSpan(0, 0, 0, 0, milli)

        f.cbValue.Text = _
            ts.Hours.ToString + ":" + _
            ts.Minutes.ToString("00") + ":" + _
            ts.Seconds.ToString("00") + "." + _
            ts.Milliseconds.ToString("000")

        If f.ShowDialog() = Windows.Forms.DialogResult.OK Then
            Dim value As String = f.cbValue.Text

            If Regex.IsMatch(value, "^\d+$") Then
                AVI.Position = CInt(f.cbValue.Text)
            Else
                Dim m As Match = Regex.Match(value, "^(\d{1,2}):(\d{1,2}):(\d{1,2})\.(\d{1,3})$")

                If m.Success Then
                    ts = New TimeSpan(0, _
                        CInt(m.Groups(1).Value), _
                        CInt(m.Groups(2).Value), _
                        CInt(m.Groups(3).Value), _
                        CInt(m.Groups(4).Value))

                    AVI.Position = CInt((ts.TotalMilliseconds / 1000) * AVI.FrameRate)
                End If
            End If

            AVI.Draw()
            DrawTrack()
        End If

        f.Dispose()
    End Sub

    <GenericMenuMethod("Set Relative Position", "Sets the relative position.")> _
    Public Sub SetRelativePos(<Name("Position")> ByVal pos As Integer)
        AVI.Position += pos
        AVI.Draw()
        AfterPositionChanged()
    End Sub

    <GenericMenuMethod("Open Menu Editor", "Opens the menu editor.")> _
    Public Sub OpenMenuEditor()
        s.GenericMenuPreview = GenericMenu.Edit()
    End Sub

    <GenericMenuMethod("Open Help", "Opens the Help.")> _
    Public Sub OpenHelp()
        Dim f As New HelpForm
        f.Document.WriteStart(Text)
        f.Document.WriteParagraph("The preview dialog allows to preview and cut the video. Cutting can be achieved by selecting the sections that should be kept. Selected sections appear green in the trackbar. Everything not green will be trimmed off. It's possible to open more than one instance of the preview for filter comparisons.")
        f.Document.WriteTips(GenericMenu.GetTips)
        f.Document.WriteTable("Shortcut Keys", GenericMenu.GetKeys, False)
        f.Show()
    End Sub

    'obsolete
    <GenericMenuMethod("Execute Command Line", "Executes a command line.")> _
    Public Sub Execute( _
        <Name("File"), _
        Description("Shell supported commands e.g. applications, files, directories, websites etc."), _
        Editor(GetType(OpenFileDialogEditor), GetType(UITypeEditor))> _
        ByVal file As String, _
        <Name("Arguments"), _
        Description("Arguments passed to the application.")> _
        ByVal arguments As String)

        Using pw As New ProcessWrapper
            pw.File = Macro.Solve(file)
            pw.Arguments = Macro.Solve(arguments)
            pw.Start()
        End Using
    End Sub

    <GenericMenuMethod("Execute Command Line", "Executes a command line.")> _
    Public Sub ExecuteCL( _
        <Name("Command Line"), _
        Description("Command Line to be executed."), _
        Editor(GetType(CLTypeEditor), GetType(UITypeEditor))> _
        ByVal commandLine As String)

        Using pw As New ProcessWrapper
            pw.CommandLine = Macro.Solve(commandLine)
            pw.Start()
        End Using
    End Sub

    <GenericMenuMethod("Set Cut Start", "Sets the start cut position.")> _
    Public Sub SetRangeStart()
        If Not IsValidCutPosition() Then
            Msg.Show("The current possition is already selected.", MsgIcon.Warning)
            Exit Sub
        End If

        RangeStart = AVI.Position
        AfterPositionChanged()
    End Sub

    <GenericMenuMethod("Set Cut End", "Sets the end cut position.")> _
    Public Sub SetRangeEnd()
        If Not IsValidCutPosition() Then
            Msg.Show("The current possition is already selected.", MsgIcon.Warning)
            Exit Sub
        End If

        If RangeStart > -1 Then
            p.Ranges.Add(New Range(RangeStart, AVI.Position))
            p.Ranges.Sort()
            RangeStart = -1
            AfterPositionChanged()
        End If
    End Sub

    <GenericMenuMethod("Delete Current Range", "Deletes the range that encloses the current position.")> _
    Public Sub DeleteRange()
        For Each i As Range In p.Ranges.ToArray
            If AVI.Position >= i.Start AndAlso AVI.Position <= i.End Then
                p.Ranges.Remove(i)
            End If
        Next

        AfterPositionChanged()
    End Sub

    <GenericMenuMethod("Show/Hide Buttons", "Shows or hides the buttons.")> _
    Public Sub ShowHideButtons()
        s.HidePreviewButtons = Not s.HidePreviewButtons
        ShowButtons(Not s.HidePreviewButtons)
        AfterPositionChanged()
    End Sub

    <GenericMenuMethod("Show/Hide Trackbar", "Shows or hides the trackbar.")> _
    Public Sub ShowHideTrackbar()
        pTrack.Visible = Not pTrack.Visible
        AfterPositionChanged()
    End Sub

    <GenericMenuMethod("Change Size", "Changes the size.")> _
    Public Sub Zoom(<Name("Factor")> ByVal factor As Single)
        SizeFactor += factor
        Normal()
        AfterPositionChanged()
    End Sub

    <GenericMenuMethod("Show/Hide Infos", "Shows or hides video parameters.")> _
    Public Sub ShowHideInfos()
        ShowInfo = Not ShowInfo
        RefreshScript()
        AfterPositionChanged()
    End Sub

    <GenericMenuMethod("Reload Script", "Reloads the script.")> _
    Public Sub Reload()
        RefreshScript()
        AfterPositionChanged()
    End Sub

    <GenericMenuMethod("Close Dialog", "Closes the dialog.")> _
    Public Sub CloseDialog()
        Close()
    End Sub

    Private Sub pVideo_DoubleClick(ByVal sender As Object, ByVal e As EventArgs) Handles pVideo.DoubleClick
        SwitchWindowState()
    End Sub

    Public MovePoint As Point

    Private Sub pVideo_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles pVideo.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Dim p As System.Drawing.Point = MousePosition

            p.X = p.X - MovePoint.X
            p.Y = p.Y - MovePoint.Y

            Location = p
        End If
    End Sub

    Private Sub pVideo_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles pVideo.MouseDown
        MovePoint.X = MousePosition.X - Location.X
        MovePoint.Y = MousePosition.Y - Location.Y
    End Sub

    <GenericMenuMethod("Previous Cut Point", "Jumps to the previous cut point.")> _
    Public Sub JumpToThePreviousRangePos()
        Dim list As New List(Of Object)

        For Each i As Range In p.Ranges
            list.Add(i.Start)
            list.Add(i.End)
        Next

        list.Add(AVI.Position - 1)

        list.Sort()

        Dim index As Integer = list.IndexOf(AVI.Position - 1) - 1

        If index >= 0 AndAlso index < list.Count Then
            AVI.Position = CInt(list(index))
            AVI.Draw()
            DrawTrack()
        End If
    End Sub

    <GenericMenuMethod("Next Cut Point", "Jumps to the next cut point.")> _
    Public Sub JumpToTheNextRangePos()
        Dim list As New List(Of Object)

        For Each i As Range In p.Ranges
            list.Add(i.Start)
            list.Add(i.End)
        Next

        list.Add(AVI.Position + 1)

        list.Sort()

        Dim index As Integer = list.IndexOf(AVI.Position + 1) + 1

        If index >= 0 AndAlso index < list.Count Then
            AVI.Position = CInt(list(index))
            AVI.Draw()
            DrawTrack()
        End If
    End Sub

    Public Shared Function GetDefaultMenu() As GenericMenuItem
        Dim t As Type = GetType(PreviewForm)

        Dim ret As GenericMenuItem = New GenericMenuItem("Root")

        Dim navigationMenuItem As New GenericMenuItem("Navigation")
        ret.SubItems.Add(navigationMenuItem)

        Dim JumpToStartMenuItem As New GenericMenuItem("Go To Start")
        JumpToStartMenuItem.KeyData = Keys.Control Or Keys.Left
        JumpToStartMenuItem.MethodName = "SetAbsolutePos"
        JumpToStartMenuItem.Parameters.Add(0)
        navigationMenuItem.SubItems.Add(JumpToStartMenuItem)

        Dim jumpToEndMenuItem As New GenericMenuItem("Go To End")
        jumpToEndMenuItem.KeyData = Keys.Control Or Keys.Right
        jumpToEndMenuItem.MethodName = "SetAbsolutePos"
        jumpToEndMenuItem.Parameters.Add(1000000000)
        navigationMenuItem.SubItems.Add(jumpToEndMenuItem)

        Dim goToFrameMenuItem As New GenericMenuItem("Go To Frame")
        goToFrameMenuItem.KeyData = Keys.G
        goToFrameMenuItem.MethodName = "GoToFrame"
        navigationMenuItem.SubItems.Add(goToFrameMenuItem)

        navigationMenuItem.SubItems.Add(New GenericMenuItem("-"))

        Dim previousRangeMenuItem As New GenericMenuItem("Go To Previous Cut Point")
        previousRangeMenuItem.KeyData = Keys.Control Or Keys.Up
        previousRangeMenuItem.MethodName = "JumpToThePreviousRangePos"
        navigationMenuItem.SubItems.Add(previousRangeMenuItem)

        Dim nextRangeMenuItem As New GenericMenuItem("Go To Next Cut Point")
        nextRangeMenuItem.KeyData = Keys.Control Or Keys.Down
        nextRangeMenuItem.MethodName = "JumpToTheNextRangePos"
        navigationMenuItem.SubItems.Add(nextRangeMenuItem)

        navigationMenuItem.SubItems.Add(New GenericMenuItem("-"))

        Dim backward1MenuItem As New GenericMenuItem("Backward 1 Frame")
        backward1MenuItem.KeyData = Keys.Left
        backward1MenuItem.MethodName = "SetRelativePos"
        backward1MenuItem.Parameters.Add(-1)
        navigationMenuItem.SubItems.Add(backward1MenuItem)

        Dim backward10MenuItem As New GenericMenuItem("Backward 10 Frames")
        backward10MenuItem.KeyData = Keys.Up
        backward10MenuItem.MethodName = "SetRelativePos"
        backward10MenuItem.Parameters.Add(-10)
        navigationMenuItem.SubItems.Add(backward10MenuItem)

        Dim backward100MenuItem As New GenericMenuItem("Backward 100 Frames")
        backward100MenuItem.KeyData = Keys.Prior
        backward100MenuItem.MethodName = "SetRelativePos"
        backward100MenuItem.Parameters.Add(-100)
        navigationMenuItem.SubItems.Add(backward100MenuItem)

        Dim backward1000MenuItem As New GenericMenuItem("Backward 1000 Frames")
        backward1000MenuItem.KeyData = Keys.Subtract
        backward1000MenuItem.MethodName = "SetRelativePos"
        backward1000MenuItem.Parameters.Add(-1000)
        navigationMenuItem.SubItems.Add(backward1000MenuItem)

        navigationMenuItem.SubItems.Add(New GenericMenuItem("-"))

        Dim forward1000MenuItem As New GenericMenuItem("Forward 1000 Frames")
        forward1000MenuItem.KeyData = Keys.Add
        forward1000MenuItem.MethodName = "SetRelativePos"
        forward1000MenuItem.Parameters.Add(1000)
        navigationMenuItem.SubItems.Add(forward1000MenuItem)

        Dim forward100MenuItem As New GenericMenuItem("Forward 100 Frames")
        forward100MenuItem.KeyData = Keys.Next
        forward100MenuItem.MethodName = "SetRelativePos"
        forward100MenuItem.Parameters.Add(100)
        navigationMenuItem.SubItems.Add(forward100MenuItem)

        Dim forward10MenuItem As New GenericMenuItem("Forward 10 Frames")
        forward10MenuItem.KeyData = Keys.Down
        forward10MenuItem.MethodName = "SetRelativePos"
        forward10MenuItem.Parameters.Add(10)
        navigationMenuItem.SubItems.Add(forward10MenuItem)

        Dim forward1MenuItem As New GenericMenuItem("Forward 1 Frames")
        forward1MenuItem.KeyData = Keys.Right
        forward1MenuItem.MethodName = "SetRelativePos"
        forward1MenuItem.Parameters.Add(1)
        navigationMenuItem.SubItems.Add(forward1MenuItem)

        Dim rangeMenuItem As New GenericMenuItem("Cut")
        ret.SubItems.Add(rangeMenuItem)

        Dim rangeStartMenuItem As New GenericMenuItem("Begin Selection")
        rangeStartMenuItem.KeyData = Keys.Home
        rangeStartMenuItem.MethodName = "SetRangeStart"
        rangeMenuItem.SubItems.Add(rangeStartMenuItem)

        Dim rangeEndMenuItem As New GenericMenuItem("End Selection")
        rangeEndMenuItem.KeyData = Keys.End
        rangeEndMenuItem.MethodName = "SetRangeEnd"
        rangeMenuItem.SubItems.Add(rangeEndMenuItem)

        Dim rangeDeleteMenuItem As New GenericMenuItem("Delete Selection")
        rangeDeleteMenuItem.KeyData = Keys.Delete
        rangeDeleteMenuItem.MethodName = "DeleteRange"
        rangeMenuItem.SubItems.Add(rangeDeleteMenuItem)

        Dim videoMenuItem As New GenericMenuItem("Video")
        ret.SubItems.Add(videoMenuItem)

        Dim infoMenuItem As New GenericMenuItem("Info")
        infoMenuItem.KeyData = Keys.I
        infoMenuItem.MethodName = "ShowHideInfos"
        videoMenuItem.SubItems.Add(infoMenuItem)

        Dim reloadMenuItem As New GenericMenuItem("Reload")
        reloadMenuItem.KeyData = Keys.R
        reloadMenuItem.MethodName = "Reload"
        videoMenuItem.SubItems.Add(reloadMenuItem)

        Dim externalPreviewMenuItem As New GenericMenuItem("External Preview")
        externalPreviewMenuItem.KeyData = Keys.E
        externalPreviewMenuItem.MethodName = "ExecuteCL"
        externalPreviewMenuItem.Parameters.Add("""%source_dir%%target_name%.avs""")
        videoMenuItem.SubItems.Add(externalPreviewMenuItem)

        Dim dialogMenuItem As New GenericMenuItem("Dialog")
        ret.SubItems.Add(dialogMenuItem)

        Dim fullscreenMenuItem As New GenericMenuItem("Fullscreen")
        fullscreenMenuItem.KeyData = Keys.Enter
        fullscreenMenuItem.MethodName = "SwitchWindowState"
        dialogMenuItem.SubItems.Add(fullscreenMenuItem)

        dialogMenuItem.SubItems.Add(New GenericMenuItem("-"))

        Dim showHideButtonsMenuItem As New GenericMenuItem("Show/Hide Buttons")
        showHideButtonsMenuItem.KeyData = Keys.B
        showHideButtonsMenuItem.MethodName = "ShowHideButtons"
        dialogMenuItem.SubItems.Add(showHideButtonsMenuItem)

        Dim showHideTrackbarMenuItem As New GenericMenuItem("Show/Hide Trackbar")
        showHideTrackbarMenuItem.KeyData = Keys.T
        showHideTrackbarMenuItem.MethodName = "ShowHideTrackbar"
        dialogMenuItem.SubItems.Add(showHideTrackbarMenuItem)

        dialogMenuItem.SubItems.Add(New GenericMenuItem("-"))

        Dim zoomInMenuItem As New GenericMenuItem("Zoom In")
        zoomInMenuItem.KeyData = Keys.OemMinus
        zoomInMenuItem.MethodName = "Zoom"
        zoomInMenuItem.Parameters.Add(-0.25F)
        dialogMenuItem.SubItems.Add(zoomInMenuItem)

        Dim zoomOutMenuItem As New GenericMenuItem("Zoom Out")
        zoomOutMenuItem.KeyData = Keys.Oemplus
        zoomOutMenuItem.MethodName = "Zoom"
        zoomOutMenuItem.Parameters.Add(0.25F)
        dialogMenuItem.SubItems.Add(zoomOutMenuItem)

        dialogMenuItem.SubItems.Add(New GenericMenuItem("-"))

        Dim exitMenuItem As New GenericMenuItem("Exit")
        exitMenuItem.KeyData = Keys.Escape
        exitMenuItem.MethodName = "CloseDialog"
        dialogMenuItem.SubItems.Add(exitMenuItem)

        Dim editMenuMenuItem As New GenericMenuItem("Edit Menu...")
        editMenuMenuItem.KeyData = Keys.M
        editMenuMenuItem.MethodName = "OpenMenuEditor"
        ret.SubItems.Add(editMenuMenuItem)

        ret.SubItems.Add(New GenericMenuItem("-"))

        Dim helpMenuMenuItem As New GenericMenuItem("Help...")
        helpMenuMenuItem.KeyData = Keys.F1
        helpMenuMenuItem.MethodName = "OpenHelp"
        ret.SubItems.Add(helpMenuMenuItem)

        Return ret
    End Function

    Private Sub pVideo_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles pVideo.Paint
        AVI.Draw(e.Graphics)
    End Sub

    Private Sub GenericMenu_Trigger(ByVal item As GenericMenuItem) Handles GenericMenu.Trigger
        If item.MethodName = "CloseDialog" Then
            ProcessMenu(item)
        Else
            For Each i As PreviewForm In Instances
                i.ProcessMenu(item)
            Next
        End If
    End Sub

    Public Sub ProcessMenu(ByVal item As GenericMenuItem)
        AVI.Draw()

        Select Case item.MethodName
            Case ""
            Case Else
                GenericMenu.Invoke(item)
        End Select
    End Sub

    Private Sub PreviewForm_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        AVI.Draw()
    End Sub

    Private Sub bExtras_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles bExtras.Paint
        ButtonHelp.DrawDropDownGlyph(bExtras, e.Graphics, HorizontalAlignment.Center, 12)
    End Sub

    Private Sub PreviewForm_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing
        Instances.Remove(Me)
        g.PreviewLastPosition = AVI.Position
        s.WindowStatePreview = WindowState
        AVI.Close()
        SetTrim()
    End Sub

    Private Sub SetTrim()
        Dim f As AviSynthFilter = p.TargetAVSDoc.GetFilter("Cutting")

        If p.Ranges.Count = 0 Then
            If Not f Is Nothing Then
                p.TargetAVSDoc.Filters.Remove(f)
            End If
        Else
            If f Is Nothing Then
                f = New AviSynthFilter
                p.TargetAVSDoc.Filters.Add(f)
            End If

            f.Name = "Cutting"
            f.Category = "Cutting"
            f.Script = GetTrim()
            f.Active = True
        End If

        g.MainForm.AviSynthListView.Load()
        g.MainForm.SetTargetLength(p.TargetAVSDoc.GetSeconds)
    End Sub

    Public Function GetTrim() As String
        Dim ret As String = ""

        For Each i As Range In p.Ranges
            If ret <> "" Then
                ret += " + "
            End If

            ret += "Trim(" + i.Start.ToString + "," + i.End.ToString + ")"
        Next

        Return ret
    End Function

    Private Sub Control_Enter(ByVal sender As Object, ByVal e As EventArgs) Handles bBackward100.Enter, bBackward10.Enter, bBackward1.Enter, bForward1.Enter, bForward10.Enter, bForward100.Enter, bRangeEnd.Enter, bRangeStart.Enter, bDeleteRange.Enter, bExtras.Enter
        ActiveControl = Nothing
    End Sub

    Private Function IsValidCutPosition() As Boolean
        For Each i As Range In p.Ranges
            If AVI.Position >= i.Start AndAlso AVI.Position <= i.End Then
                Return False
            End If
        Next

        Return True
    End Function
End Class