
#Region " Compiler Options "

Option Strict On
Option Explicit On
Option Compare Binary

#End Region

#Region " Library Imports "

Imports Un4seen.Bass
Imports Un4seen.BassAsio
Imports Un4seen.Bass.AddOn.Video
#End Region

' Template version 1.2.0.0. Code developed for framework v2.0.50727.1433
' This code is copyright (c) 2008 . All rights reserved.

''' <summary>
''' Test form for Bass Video library
''' </summary>
''' <remarks>
''' -- Change Log --------------------------------------------------------
''' 2/8/2008 7:17:45 PM by Rick - Initial Creation
''' 
''' </remarks>
Public Class MainForm

#Region " Form Events "

#Region " Private Form Declarations "

    Private _HasShown As Boolean = False
    Private _MoveToSecondaryDisplay As Boolean = False
    Private _SetupFonts As Boolean = True

#End Region

    Private Sub Form_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        Me.TerminateBassAndVideo()
    End Sub

    Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If _SetupFonts Then SetupFontsForOs(Me)
        SetupScreenCentering(Me, _MoveToSecondaryDisplay)

        pVideo1.Image = My.Resources.Video256
        pVideo2.Image = My.Resources.Video256

        Me.bRatio.SelectedIndex = 0
    End Sub

    Private Sub Form_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize

    End Sub

    Private Sub Form_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
        If Not _HasShown Then
            _HasShown = True
            Application.DoEvents()
            ' Do Something here
            InitBassAndVideo()
        End If
    End Sub

#Region " Custom Form Properties "

    ''' <summary>
    ''' Determines if the application is running on the Microsoft Windows Vista ? Operating System
    ''' </summary>
    ''' <value></value>
    ''' <returns>Boolean</returns>
    ''' <remarks></remarks>
    Public Shared ReadOnly Property IsVista() As Boolean
        Get
            Return Environment.OSVersion.Platform = PlatformID.Win32NT And Environment.OSVersion.Version.Major >= 6
        End Get
    End Property ' IsVista

#End Region

#Region " Custom Form Methods "

    ''' <summary>
    ''' Since the Segoe UI font doesn't exist in Windows XP ?, we set it to Trebuchet MS instead if not Windows Vista
    ''' </summary>
    ''' <param name="frm">The form to modify</param>
    ''' <remarks></remarks>
    Private Sub SetupFontsForOs(ByVal frm As System.Windows.Forms.Form)
        frm.SuspendLayout()
        If IsVista Then
            frm.Font = New System.Drawing.Font("Segoe UI", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Else
            frm.Font = New System.Drawing.Font("Trebuchet MS", 9.75!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        End If
        frm.ResumeLayout(False)
    End Sub ' SetupFontsForOs

    ''' <summary>
    ''' Centers a form on either a primary or seconday display
    ''' </summary>
    ''' <param name="frm">The form to center</param>
    ''' <param name="moveToSecondarydisplay">Determines if the form gets centered on the primary display or secondary</param>
    ''' <remarks></remarks>
    Private Sub SetupScreenCentering(ByRef frm As System.Windows.Forms.Form, ByVal moveToSecondarydisplay As Boolean)
        Dim SelScreen As System.Windows.Forms.Screen = Nothing
        If moveToSecondarydisplay Then
            If Screen.AllScreens.Length > 1 Then
                SelScreen = Screen.AllScreens(1)
            Else
                SelScreen = Screen.PrimaryScreen
            End If
        Else
            SelScreen = Screen.PrimaryScreen
        End If
        frm.Top = SelScreen.Bounds.Top + CType(((SelScreen.WorkingArea.Height / 2) - (frm.Height / 2)), Integer)
        frm.Left = SelScreen.Bounds.Left + CType(((SelScreen.WorkingArea.Width / 2) - (frm.Width / 2)), Integer)
    End Sub ' SetupScreenCentering

#End Region

#End Region

#Region " Private "

#Region " Private Variable Declarations "

    ''' <summary>
    ''' Current filename that is open
    ''' </summary>
    ''' <remarks></remarks>
    Private Filename As String = ""

    ''' <summary>
    ''' Current stream handle
    ''' </summary>
    ''' <remarks></remarks>
    Private Stream As Integer = 0

    Private VidProc As VIDEOPROC = AddressOf Me.BassVideoProcedure


#End Region

#Region " Private Control Events "

    Private Sub bEject_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bEject.Click
        If Stream <> 0 Then
            Me.CloseFile()
        End If
        Dim sFile As String = Dialogs.ShowOpenDialog("", BassLib.BassLibrary.FileFilter, 0, Me)
        If String.IsNullOrEmpty(sFile) Then Exit Sub
        Filename = sFile
        LoadFile()

    End Sub

    Private Sub bNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bNext.Click

    End Sub

    Private Sub bStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bStop.Click
        BassVideo.BASS_Video_Stop(Stream)
        CloseFile()
    End Sub

    Private Sub bPause_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bPause.Click
        If Un4seen.Bass.Bass.BASS_ChannelIsActive(Stream) = BASSActive.BASS_ACTIVE_PLAYING Then
            BassVideo.BASS_Video_Pause(Stream)
        Else
            BassVideo.BASS_Video_Play(Stream, False)
        End If
    End Sub

    Private Sub bPlay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bPlay.Click
        If Stream = 0 Then
            LoadFile()
        End If
        If Un4seen.Bass.Bass.BASS_ChannelIsActive(Stream) = BASSActive.BASS_ACTIVE_PLAYING Then
            BassVideo.BASS_Video_Pause(Stream)
        Else
            BassVideo.BASS_Video_Play(Stream, True)
        End If
    End Sub

    Private Sub bPrev_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bPrev.Click

    End Sub

    Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        UpdateButtons()
        If Bass.BASS_ChannelIsActive(Stream) <> BASSActive.BASS_ACTIVE_PLAYING Then
            Exit Sub
        End If
        Dim elapsed As Double = Bass.BASS_ChannelBytes2Seconds(Stream, BASS_Video_GetPosition(Stream))
        Dim vlen As Double = Bass.BASS_ChannelBytes2Seconds(Stream, BassVideo.BASS_Video_GetLength(Stream))
        Dim remain As Double = vlen - elapsed

        Dim tmp As String = ""

        tmp += "+" + Un4seen.Bass.Utils.FixTimespan(elapsed, "MMSS")
        tmp += " -" + Un4seen.Bass.Utils.FixTimespan(remain, "MMSS")
        tmp += "  " + Un4seen.Bass.Utils.FixTimespan(vlen, "MMSS")
        UpdateStatus(tmp)
    End Sub

    Private Sub bRatio_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles bRatio.SelectedIndexChanged
        Dim RetVal As Integer = 0
        Select Case bRatio.SelectedIndex
            Case 0
                RetVal = 1
            Case 1
                RetVal = 0
            Case 2
                RetVal = 3
            Case 3
                RetVal = 2
        End Select
        If Stream <> 0 Then BassVideo.BASS_Video_SetRatio(Stream, DirectCast(RetVal, Un4seen.Bass.AddOn.Video.BASSVIDEORatio), 0)
    End Sub

#End Region

#End Region

#Region " Public "

#Region " Public Callbacks "

    ''' <summary>
    ''' User defined callback function to process video action states. 
    ''' </summary>
    ''' <param name="handle">The video handle that the data is from.</param>
    ''' <param name="action">One of the BASSVIDEOAction values to indicate the current video state.</param>
    ''' <param name="param1">The first action parameter (see BASSVIDEOAction for details).</param>
    ''' <param name="param2">The second action parameter (see BASSVIDEOAction for details).</param>
    ''' <param name="user">The user instance data given when BASS_Video_StreamCreateFile was called.</param>
    ''' <remarks>Un4seen.Bass.AddOn.Video.VIDEOPROC</remarks>
    Public Sub BassVideoProcedure(ByVal handle As Integer, ByVal action As Un4seen.Bass.AddOn.Video.BASSVIDEOAction, ByVal param1 As Integer, ByVal param2 As Integer, ByVal user As IntPtr)
        Select Case action
            Case AddOn.Video.BASSVIDEOAction.BassVideo_FoundVideo
                If Stream = 0 Then
                    AddOn.Video.BassVideo.BASS_Video_SetVideoWindow(handle, pVideo1.Handle, pVideo1.ClientRectangle, 0)
                End If
            Case BASSVIDEOAction.BassVideo_Buffering
                UpdateStatus("Video is buffering.")
            Case BASSVIDEOAction.BassVideo_EndStream
                UpdateStatus("Video is at end of stream.")
            Case BASSVIDEOAction.BassVideo_OpenDone
                UpdateStatus("Video opened, ready to play.")
        End Select
    End Sub

#End Region

#Region " Public Methods "

    Public Sub InitBassAndVideo()
        lStatus.Text = "Initializing Bass Sound System."
        lStatus.Invalidate()
        Application.DoEvents()

        BassLib.BassLibrary.ThrowErrorsAsException = False
        BassLib.BassLibrary.InitBass(Me.Handle, My.Application.Info.DirectoryPath, -1, 44100)
        If Not BassVideo.BASS_Video_Init() Then
            BassLib.BassLibrary.ThrowBassError()
        End If

        lStatus.Text = "Ready. Click the Eject button to load a file."
        lStatus.Invalidate()
        Timer1.Enabled = True
    End Sub

    Public Sub TerminateBassAndVideo()
        Timer1.Enabled = False
        If Stream <> 0 Then CloseFile()
        BassVideo.BASS_Video_Free()
        BassLib.BassLibrary.TerminateBass()
    End Sub

    Public Sub LoadFile()
        Me.Stream = BassVideo.BASS_Video_StreamCreateFile(Filename, AddOn.Video.BASSVIDEOFlag.BASSVIDEO_MULTIVIDEO, BASSFlag.BASS_DEFAULT, VidProc, Me.Handle)
        If Stream = 0 Then
            BassLib.BassLibrary.ThrowBassError()
            Exit Sub
        End If
        BassVideo.BASS_Video_AddVideo(Stream, pVideo2.Handle, pVideo2.ClientRectangle)

    End Sub

    Public Sub CloseFile()
        BassVideo.BASS_Video_StreamFree(Stream)
        Stream = 0
    End Sub

    Public Sub UpdateStatus(ByVal statusText As String)
        If lStatus.Text <> statusText Then
            Try
                lStatus.Text = statusText
            Catch ex As Exception

            End Try
            Application.DoEvents()
        End If
    End Sub

    Public Sub UpdateButtons()
        Dim tmp As String = "stopped"
        If Stream = 0 Then
            bStop.Enabled = False
            bPlay.Enabled = False
            bPause.Enabled = False
            Exit Sub
        End If
        Select Case Un4seen.Bass.Bass.BASS_ChannelIsActive(Stream)
            Case BASSActive.BASS_ACTIVE_PAUSED
                tmp = "Paused"
                bStop.Enabled = True
                bPlay.Enabled = False
                bPause.Enabled = True
            Case BASSActive.BASS_ACTIVE_PLAYING
                tmp = "Playing"
                bStop.Enabled = True
                bPlay.Enabled = False
                bPause.Enabled = True
            Case BASSActive.BASS_ACTIVE_STALLED
                tmp = "Stalled"
                bStop.Enabled = True
                bPlay.Enabled = False
                bPause.Enabled = False
            Case BASSActive.BASS_ACTIVE_STOPPED
                tmp = "Stopped"
                bStop.Enabled = False
                bPlay.Enabled = True
                bPause.Enabled = False
        End Select
        'UpdateStatus(tmp)
    End Sub

#End Region

#Region " Public Shared Methods "

    ''' <summary>
    ''' This is a fix for the Bass.NET API, remove once the api has been fixed.
    ''' </summary>
    ''' <param name="handle"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.Runtime.InteropServices.DllImport("BassVideo.dll", EntryPoint:="BASSVideo_GetPosition", CharSet:=System.Runtime.InteropServices.CharSet.Auto)> _
    Public Shared Function BASS_Video_GetPosition(ByVal handle As Integer) As Long
    End Function

    ''' <summary>
    ''' This is a fix for the Bass.NET API, remove once the api has been fixed.
    ''' </summary>
    ''' <param name="handle"></param>
    ''' <param name="pos"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.Runtime.InteropServices.DllImport("BassVideo.dll", EntryPoint:="BASSVideo_SetPosition", CharSet:=System.Runtime.InteropServices.CharSet.Auto)> _
    Public Shared Function BASS_Video_SetPosition(ByVal handle As Integer, ByVal pos As Long) As <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)> Boolean
    End Function

#End Region

#End Region

End Class
