Imports System
Imports System.Windows
Imports System.Windows.Data
Imports System.Windows.Media
Imports System.Windows.Media.Imaging
Imports Microsoft.Kinect
Imports Microsoft.Kinect.Toolkit

''' <summary>
''' Interaction logic for MainWindow.xaml
''' </summary>
Class MainWindow
    Private Shared ReadOnly Bgr32BytesPerPixel As Integer = Fix((PixelFormats.Bgr32.BitsPerPixel + 7) / 8)
    Private ReadOnly sensorChooser As New KinectSensorChooser()
    Private colorImageWritableBitmap As WriteableBitmap
    Private colorImageData() As Byte
    Private currentColorImageFormat As ColorImageFormat = ColorImageFormat.Undefined

    Public Sub New()

        ' この呼び出しはデザイナーで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。
        Dim faceTrackingViewerBinding As New Binding("Kinect") With {.Source = sensorChooser}
        faceTrackingViewer.SetBinding(FaceTrackingViewer.KinectProperty, faceTrackingViewerBinding)

        AddHandler sensorChooser.KinectChanged, AddressOf SensorChooserOnKinectChanged

        sensorChooser.Start()
    End Sub

    Private Sub SensorChooserOnKinectChanged(sender As Object,
                                             e As KinectChangedEventArgs)
        Dim oldSensor As KinectSensor = e.OldSensor
        Dim newSensor As KinectSensor = e.NewSensor

        If (oldSensor IsNot Nothing) Then
            RemoveHandler oldSensor.AllFramesReady, AddressOf KinectSensorOnAllFramesReady
            oldSensor.ColorStream.Disable()
            oldSensor.DepthStream.Disable()
            oldSensor.DepthStream.Range = DepthRange.Default
            oldSensor.SkeletonStream.Disable()
            oldSensor.SkeletonStream.EnableTrackingInNearRange = False
            oldSensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Default
        End If

        If (newSensor IsNot Nothing) Then
            Try
                newSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30)
                newSensor.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30)
                Try
                    If (CType(CType(Me.Mode_ComboBox.SelectedItem, FrameworkElement).Tag, String) = "2") Then
                        ' me will throw on non Kinect For Windows devices.
                        newSensor.DepthStream.Range = DepthRange.Near
                        newSensor.SkeletonStream.EnableTrackingInNearRange = True
                    Else
                        newSensor.DepthStream.Range = DepthRange.Default
                        newSensor.SkeletonStream.EnableTrackingInNearRange = False
                    End If
                    catch ex as InvalidOperationException
                    newSensor.DepthStream.Range = DepthRange.Default
                    newSensor.SkeletonStream.EnableTrackingInNearRange = False
                End Try

                newSensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated
                newSensor.SkeletonStream.Enable()
                AddHandler newSensor.AllFramesReady, AddressOf KinectSensorOnAllFramesReady
            Catch ex As InvalidOperationException
                ' me exception can be thrown when we are trying to
                ' enable streams on a device that has gone away.  me
                ' can occur, say, in app shutdown scenarios when the sensor
                ' goes away between the time it changed status and the
                ' time we get the sensor changed notification.
                '
                ' Behavior here is to just eat the exception and assume
                ' another notification will come along if a sensor
                ' comes back.
            End Try
        End If
    End Sub

    Private Sub WindowClosed(sender As Object, e As EventArgs)
        sensorChooser.Stop()
        faceTrackingViewer.Dispose()
    End Sub

    Private Sub KinectSensorOnAllFramesReady(sender As Object,
                                             e As AllFramesReadyEventArgs)
        Using frame As ColorImageFrame = e.OpenColorImageFrame()
            If (frame Is Nothing) Then
                Exit Sub
            End If

            ' Make a copy of the color frame for displaying.
            Dim haveNewFormat As Boolean = Me.currentColorImageFormat <> frame.Format
            If (haveNewFormat) Then
                Me.currentColorImageFormat = frame.Format
                ReDim Me.colorImageData(frame.PixelDataLength - 1)
                Me.colorImageWritableBitmap = New WriteableBitmap(frame.Width,
                                                                  frame.Height,
                                                                  96,
                                                                  96,
                                                                  PixelFormats.Bgr32,
                                                                  Nothing)
                Me.Rgb_Image.Source = Me.colorImageWritableBitmap
            End If

            frame.CopyPixelDataTo(Me.colorImageData)
            Me.colorImageWritableBitmap.WritePixels(New Int32Rect(0, 0, frame.Width, frame.Height),
                                                    Me.colorImageData,
                                                    frame.Width * Bgr32BytesPerPixel,
                                                    0)
        End Using
    End Sub

    Private Sub Mode_ComboBox_SelectionChanged(sender As Object,
                                                e As System.Windows.Controls.SelectionChangedEventArgs)
        If (Me.sensorChooser.Kinect IsNot Nothing AndAlso Me.sensorChooser.Kinect.SkeletonStream IsNot Nothing) Then
            Dim tagValue As String = CType(CType(Me.Mode_ComboBox.SelectedItem, FrameworkElement).Tag, String)
            Select Case tagValue
                Case "1"
                    Me.sensorChooser.Kinect.SkeletonStream.TrackingMode = SkeletonTrackingMode.Default
                Case "2"
                    Me.sensorChooser.Kinect.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated
            End Select
        End If
    End Sub
End Class
