Imports System.Threading
Imports System.Text
Imports System.Runtime.InteropServices

Imports Microsoft.VisualBasic.CompilerServices

Imports Stax
Imports Stax.UI
Imports Stax.Win32

<DesignerGenerated()> _
Public Class ProcessForm
    Inherits ExtendedForm

#Region " Designer "
    Private components As System.ComponentModel.IContainer

    Friend WithEvents SmartTagProvider As Stax.UI.Design.SmartTagProvider
    Friend WithEvents ProgressBar1 As System.Windows.Forms.ProgressBar
    Friend WithEvents bAbort As System.Windows.Forms.Button
    Friend WithEvents lWhenfinisheddo As System.Windows.Forms.Label
    Friend WithEvents cbShutdown As System.Windows.Forms.ComboBox
    Friend WithEvents NotifyIcon As System.Windows.Forms.NotifyIcon
    Friend WithEvents bPause As System.Windows.Forms.Button
    Friend WithEvents tbLog As System.Windows.Forms.TextBox

    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing AndAlso components IsNot Nothing Then
            components.Dispose()
        End If
        MyBase.Dispose(disposing)
    End Sub

    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container
        Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(ProcessForm))
        Me.SmartTagProvider = New Stax.UI.Design.SmartTagProvider
        Me.ProgressBar1 = New System.Windows.Forms.ProgressBar
        Me.bAbort = New System.Windows.Forms.Button
        Me.lWhenfinisheddo = New System.Windows.Forms.Label
        Me.cbShutdown = New System.Windows.Forms.ComboBox
        Me.tbLog = New System.Windows.Forms.TextBox
        Me.NotifyIcon = New System.Windows.Forms.NotifyIcon(Me.components)
        Me.bPause = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'ProgressBar1
        '
        Me.ProgressBar1.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.ProgressBar1.Location = New System.Drawing.Point(13, 190)
        Me.ProgressBar1.MarqueeAnimationSpeed = 200
        Me.ProgressBar1.Name = "ProgressBar1"
        Me.ProgressBar1.Size = New System.Drawing.Size(367, 13)
        Me.ProgressBar1.Style = System.Windows.Forms.ProgressBarStyle.Marquee
        Me.ProgressBar1.TabIndex = 0
        '
        'bAbort
        '
        Me.bAbort.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.bAbort.Location = New System.Drawing.Point(305, 270)
        Me.bAbort.Name = "bAbort"
        Me.bAbort.Size = New System.Drawing.Size(75, 24)
        Me.bAbort.TabIndex = 2
        Me.bAbort.Text = "Abort"
        '
        'lWhenfinisheddo
        '
        Me.lWhenfinisheddo.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
        Me.lWhenfinisheddo.AutoSize = True
        Me.lWhenfinisheddo.Location = New System.Drawing.Point(12, 274)
        Me.lWhenfinisheddo.Name = "lWhenfinisheddo"
        Me.lWhenfinisheddo.Size = New System.Drawing.Size(90, 13)
        Me.lWhenfinisheddo.TabIndex = 6
        Me.lWhenfinisheddo.Text = "When finished do"
        '
        'cbShutdown
        '
        Me.cbShutdown.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
        Me.cbShutdown.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
        Me.cbShutdown.FormattingEnabled = True
        Me.cbShutdown.Location = New System.Drawing.Point(104, 271)
        Me.cbShutdown.Name = "cbShutdown"
        Me.cbShutdown.Size = New System.Drawing.Size(81, 21)
        Me.cbShutdown.TabIndex = 5
        '
        'tbLog
        '
        Me.tbLog.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
                    Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.tbLog.Font = New System.Drawing.Font("Courier New", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.tbLog.Location = New System.Drawing.Point(13, 13)
        Me.tbLog.Multiline = True
        Me.tbLog.Name = "tbLog"
        Me.tbLog.ReadOnly = True
        Me.tbLog.ScrollBars = System.Windows.Forms.ScrollBars.Both
        Me.tbLog.Size = New System.Drawing.Size(367, 251)
        Me.tbLog.TabIndex = 7
        Me.tbLog.WordWrap = False
        '
        'NotifyIcon
        '
        Me.NotifyIcon.Icon = CType(resources.GetObject("NotifyIcon.Icon"), System.Drawing.Icon)
        Me.NotifyIcon.Text = "StaxRip"
        '
        'bPause
        '
        Me.bPause.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.bPause.Location = New System.Drawing.Point(224, 270)
        Me.bPause.Name = "bPause"
        Me.bPause.Size = New System.Drawing.Size(75, 24)
        Me.bPause.TabIndex = 8
        Me.bPause.Text = "Pause"
        Me.bPause.UseVisualStyleBackColor = True
        '
        'ProcessForm
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(392, 306)
        Me.Controls.Add(Me.bPause)
        Me.Controls.Add(Me.tbLog)
        Me.Controls.Add(Me.lWhenfinisheddo)
        Me.Controls.Add(Me.cbShutdown)
        Me.Controls.Add(Me.bAbort)
        Me.Controls.Add(Me.ProgressBar1)
        Me.Icon = CType(resources.GetObject("$this.Icon"), System.Drawing.Icon)
        Me.KeyPreview = True
        Me.MinimumSize = New System.Drawing.Size(400, 277)
        Me.Name = "ProcessForm"
        Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show
        Me.Text = "StaxRip - Log"
        Me.ResumeLayout(False)
        Me.PerformLayout()

    End Sub
#End Region

    Private Shared Instance As ProcessForm
    Private Shared Message As String
    Private Shared ShutdownVisible As Boolean

    Dim ThreadHandle As IntPtr

    Public Sub New()
        InitializeComponent()

        For Each i As ShutdownMode In System.Enum.GetValues(GetType(ShutdownMode))
            cbShutdown.Items.Add(i)
        Next

        cbShutdown.SelectedItem = g.ShutdownMode

        lWhenfinisheddo.Visible = ShutdownVisible
        cbShutdown.Visible = ShutdownVisible

        AddHandler Log.Update, AddressOf LogUpdate
    End Sub

    Private Shared ProcessWrapperValue As ProcessWrapper

    Public Shared Property ProcessWrapper() As ProcessWrapper
        Get
            Return ProcessWrapperValue
        End Get
        Set(ByVal Value As ProcessWrapper)
            ProcessWrapperValue = Value
        End Set
    End Property

    Public Sub LogUpdate(ByVal sb As StringBuilder)
        Message = sb.ToString
        Instance.Invoke(New SubDelegate(AddressOf LogUpdate))
    End Sub

    Private Sub LogUpdate()
        tbLog.Text = Message
        tbLog.SelectionStart = tbLog.TextLength
        tbLog.ScrollToCaret()
    End Sub

    Public Shared Sub ShowForm(ByVal shutdownVisible As Boolean)
        StaxRip.ProcessForm.ShutdownVisible = shutdownVisible

        If Instance Is Nothing Then
            g.MainForm.Hide()
            Dim t As Thread = New Thread(AddressOf ShowForm)
            t.Start()

            While Instance Is Nothing OrElse Not Instance.IsHandleCreated
                Thread.Sleep(50)
            End While
        Else
            Instance.Invoke(New SubDelegate(AddressOf SetMessage))
        End If
    End Sub

    Private Shared Sub SetMessage()
        Instance.tbLog.Text = Message
    End Sub

    Private Shared Sub ShowForm()
        Dim f As New ProcessForm
        Instance = f
        f.tbLog.Text = Message
        Application.Run(f)
    End Sub

    Private Shared Sub CloseFormMethod()
        Try
            Instance.Close()
            Instance.Dispose()
            Instance = Nothing
        Catch ex As Exception
        End Try
    End Sub

    Public Shared Sub CloseProcessForm()
        Try
            If Not Instance Is Nothing Then
                g.MainForm.Show()
                Instance.Invoke(New SubDelegate(AddressOf CloseFormMethod))
            End If
        Catch
        End Try
    End Sub

    Private Sub bAbort_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bAbort.Click
        ProcessWrapper.KillAndThrow()
    End Sub

    Private Sub TaskForm_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing
        RemoveHandler Log.Update, AddressOf LogUpdate
    End Sub

    Private Sub cbShutdown_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles cbShutdown.SelectedIndexChanged
        g.ShutdownMode = DirectCast(cbShutdown.SelectedItem, ShutdownMode)
    End Sub

    Protected Overrides Sub WndProc(ByRef m As Message)
        If m.Msg = WM.SYSCOMMAND Then
            Select Case m.WParam.ToInt32
                Case SC.MINIMIZE
                    Win32Window.Hide(ProcessForm.ProcessWrapper.Process.MainWindowHandle)
                    Hide()
                    NotifyIcon.Visible = True
                    Exit Sub
                Case SC.CLOSE
                    Exit Sub
            End Select
        End If

        MyBase.WndProc(m)
    End Sub

    Private Sub NotifyIcon_MouseClick(ByVal sender As Object, ByVal e As MouseEventArgs) Handles NotifyIcon.MouseClick
        Win32Window.Show(ProcessForm.ProcessWrapper.Process.MainWindowHandle)
        Show()
        NotifyIcon.Visible = False
    End Sub

    <DllImport("kernel32.dll")> _
    Shared Function SuspendThread(ByVal hThread As IntPtr) As UInt32
    End Function

    <DllImport("kernel32.dll")> _
    Shared Function OpenThread(ByVal dwDesiredAccess As ThreadAccess, ByVal bInheritHandle As Boolean, ByVal dwThreadId As UInt32) As IntPtr
    End Function

    <DllImport("kernel32.dll")> _
    Shared Function ResumeThread(ByVal hThread As IntPtr) As UInt32
    End Function

    <DllImport("kernel32.dll")> _
    Shared Function CloseHandle(ByVal hObject As IntPtr) As Boolean
    End Function

    <Flags()> _
    Public Enum ThreadAccess As Integer
        TERMINATE = &H1
        SUSPEND_RESUME = &H2
        GET_CONTEXT = &H8
        SET_CONTEXT = &H10
        SET_INFORMATION = &H20
        QUERY_INFORMATION = &H40
        SET_THREAD_TOKEN = &H80
        IMPERSONATE = &H100
        DIRECT_IMPERSONATION = &H200
    End Enum

    Private Sub bPause_Click(ByVal sender As Object, ByVal e As EventArgs) Handles bPause.Click
        If bPause.Text = "Pause" Then
            Msg.Show("Pause/Resume is experimental since it is not tested with all applications and CPU types. It might work, it might not work and it might even crash.", s.StringList)

            Dim max As TimeSpan
            Dim id As Integer

            For Each i As ProcessThread In ProcessWrapper.Process.Threads
                If i.TotalProcessorTime > max Then
                    max = i.TotalProcessorTime
                    id = i.Id
                End If
            Next

            ThreadHandle = OpenThread(ThreadAccess.SUSPEND_RESUME, False, Convert.ToUInt32(id))
            SuspendThread(ThreadHandle)
            bPause.Text = "Resume"
        Else
            ResumeThread(ThreadHandle)
            CloseHandle(ThreadHandle)
            bPause.Text = "Pause"
        End If
    End Sub
End Class