﻿#region XAML window definition
# Right-click XAML and choose WPF/Edit... to edit WPF Design
# in your favorite WPF editing tool
$xaml = @'

<Window
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   MinWidth="200"
   Width ="500"
   SizeToContent="WidthAndHeight"
   Title="VM State Management"
   Topmost="True">
   <Grid Margin="10,40,10,10">
      <Grid.ColumnDefinitions>
         <ColumnDefinition Width="Auto"/>
         <ColumnDefinition Width="Auto"/>
         <ColumnDefinition Width="Auto"/>
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
      </Grid.RowDefinitions>
        <TextBlock Grid.Column="1" Margin="10">Select VM:</TextBlock>

      <TextBlock Grid.Column="0" Grid.Row="1" Margin="5">Running VMs</TextBlock>
      <ComboBox Name="ComboVMRunning" Grid.Column="1" Grid.Row="1" Margin="5"></ComboBox>
      <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0" Grid.Row="1" Grid.Column="2">
      <Button Name="ButStopVMRunning" MinWidth="80" Height="22" Margin="5">Stop VM</Button>
      <Button Name="ButPauseVM" MinWidth="80" Height="22" Margin="5">Pause VM</Button>
      </StackPanel>
      
      <TextBlock Grid.Column="0" Grid.Row="2" Margin="5">Stopped VMs</TextBlock>
      <ComboBox Name="ComboVMStopped" Grid.Column="1" Grid.Row="2" Margin="5"></ComboBox>
      <Button Name="ButStartVM" Grid.Column="2" Grid.Row="2" MinWidth="80" Height="22" Margin="5">Start VM</Button>
      
      <TextBlock Grid.Column="0" Grid.Row="3" Margin="5">Paused VMs</TextBlock>
      <ComboBox Name="ComboVMPaused" Grid.Column="1" Grid.Row="3" Margin="5"></ComboBox>
      <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0" Grid.Row="3" Grid.Column="2">
      <Button Name="ButStopVMPaused" MinWidth="80" Height="22" Margin="5">Stop VM</Button>
      <Button Name="ButResumeVM" Grid.Column="2" Grid.Row="3" MinWidth="80" Height="22" Margin="5">Resume VM</Button>
      </StackPanel>
        
      <Button Name="ButCancel" Grid.Row="4" Grid.ColumnSpan="3" MinWidth="80" Height="22" Margin="5">Cancel</Button>
      
   </Grid>
</Window>

'@

function Convert-XAMLtoWindow
{
   param
   (
    [Parameter(Mandatory)]
    [string]
    $XAML,

    [string[]]
    $NamedElement=$null,

    [switch]
    $PassThru
   )

   Add-Type -AssemblyName PresentationFramework

   $reader = [XML.XMLReader]::Create([System.IO.StringReader]$XAML)
   $result = [Windows.Markup.XAMLReader]::Load($reader)
   foreach($Name in $NamedElement)
   {
    $result | Add-Member NoteProperty -Name $Name -Value $result.FindName($Name) -Force
   }

   if ($PassThru)
   {
    $result
   }
   else
   {
    $null = $window.Dispatcher.InvokeAsync{
      $result = $window.ShowDialog()
      Set-Variable -Name result -Value $result -Scope 1
    }.Wait()
    $result
   }
}


function Show-WPFWindow
{
   param
   (
    [Parameter(Mandatory)]
    [Windows.Window]
    $Window
   )

   $result = $null
   $null = $window.Dispatcher.InvokeAsync{
    $result = $window.ShowDialog()
    Set-Variable -Name result -Value $result -Scope 1
   }.Wait()
   $result
}

function Set-VMCombos
{
   # get the VMs of selected status, put them into an array explicitly (as there might only be one)
   $window.ComboVMRunning.ItemsSource = @(Get-VM | Where-Object State -eq 'Running' | Sort-Object -Property VMName)
   # tell the combobox to use the property "VMName" to display the object in its list
   $window.ComboVMRunning.DisplayMemberPath = 'VMName'
   # tell the combobox to preselect the first element
   $window.ComboVMRunning.SelectedIndex = 0

   $window.ComboVMStopped.ItemsSource = @(Get-VM | Where-Object State -eq 'Off' | Sort-Object -Property VMName)
   $window.ComboVMStopped.DisplayMemberPath = 'VMName'
   $window.ComboVMStopped.SelectedIndex = 0

   $window.ComboVMPaused.ItemsSource = @(Get-VM | Where-Object State -eq 'Paused' | Sort-Object -Property VMName)
   $window.ComboVMPaused.DisplayMemberPath = 'VMName'
   $window.ComboVMPaused.SelectedIndex = 0

}

$window = Convert-XAMLtoWindow -XAML $xaml -NamedElement 'ButCancel', 'ButPauseVM', 'ButResumeVM', 'ButStartVM', 'ButStopVMPaused', 'ButStopVMRunning', 'ComboVMPaused', 'ComboVMRunning', 'ComboVMStopped' -PassThru

# add click handlers
$window.ButStopVMRunning.add_Click{
   # when clicked, take the selected item from the combo box and stop the VM
   $window.ComboVMRunning.SelectedItem | Stop-VM -Force
   # update the combo box 
   Set-VMCombos
}

$window.ButStopVMPaused.add_Click{
   # when clicked, take the selected item from the combo box and stop the VM
   $window.ComboVMPaused.SelectedItem | Stop-VM -Force
   # update the combo box 
   Set-VMCombos
}

$window.ButPauseVM.add_Click{
   # when clicked, take the selected item from the combo box and suspend the VM
   $window.ComboVMRunning.SelectedItem | Suspend-VM
   # update the combo box 
   Set-VMCombos
}

$window.ButResumeVM.add_Click{
   # when clicked, take the selected item from the combo box and resume the VM
   $window.ComboVMPaused.SelectedItem | Resume-VM
   # update the combo box 
   Set-VMCombos
}

$window.ButStartVM.add_Click{
   # when clicked, take the selected item from the combo box and start the VM
   $window.ComboVMStopped.SelectedItem | Start-VM
   # update the combo box 
   Set-VMCombos
}


$window.ButCancel.add_Click{
   # close window
   $window.DialogResult = $false
}

# do the initial filling of the combo boxes
Set-VMCombos
# build and display the window
Show-WPFWindow -Window $window
#endregion