##############################################################################
# -*- mode: powershell -*-

$Debug = $False
#$Debug = $True
Set-StrictMode -Version 3.0
$ErrorActionPreference = "Stop"	# エラーで即停止

$global:Selected	= ''

$DialogWidth		= 300
$DialogButtonHeight	= 50

##############################################################################
# BCD リード

function ReadBCD {
	$BcdItems = @{}
	
	foreach($Line in (bcdedit /enum all) -Split '`n'){
		if($Line -eq ''){
			if(Test-Path Variable:BcdItem){
				$BcdItems.Add($BcdItem."identifier", $BcdItem)
				Remove-Variable BcdItem
			}
		}
		
		elseif(!(Test-Path Variable:BcdItem)){
			$BcdItem = @{"title" = $Line}
		}
		
		elseif($Line -cmatch "^(\w+) +(.*)"){
			if($Matches[1] -eq "displayorder"){
				$BcdItem.Add($Matches[1], @($Matches[2]))
			}else{
				$BcdItem.Add($Matches[1], $Matches[2])
			}
		}
		
		elseif($Line -cmatch "^ +(.*)" -and ($BcdItem.ContainsKey("displayorder"))){
			$BcdItem."displayorder" += $Matches[1]
		}
	}
	
	return $BcdItems
}

##############################################################################
# ボタン追加

function AddButton( $Table, [ref]$Pos, $Label, $OnClick ){
	$Button = New-Object System.Windows.Forms.Button
	$Button.Dock			= "Fill"
	$Button.Margin			= 0
	$Button.text			= $Label
	$Button.DialogResult	= "OK"
	$Button.Add_Click($OnClick)
	
	$Table.RowStyles.Add((New-Object System.Windows.Forms.RowStyle([System.Windows.Forms.SizeType]::Percent, 100))) | Out-Null
	$Table.Controls.Add($Button, 0, $Pos.Value)
	++$Pos.Value
}

##############################################################################
# Form 作成

Add-Type -Assembly PresentationCore
Add-Type -AssemblyName System.Windows.Forms

$Form = New-Object System.Windows.Forms.Form
# Form のサイズ
$Form.StartPosition	= "CenterScreen"
$Form.MinimizeBox	= $False
$Form.MaximizeBox	= $False
$Form.TopMost		= $True
$Form.Add_Shown({$Form.WindowState = [System.Windows.Forms.FormWindowState]::Normal})

$Table = New-Object System.Windows.Forms.TableLayoutPanel
$Table.ColumnCount	= 1
$Table.Dock			= "Fill"

# BCD ブートメニューボタン
$ButtonNum		= 0

$Form.Font	= New-Object System.Drawing.Font("Segoe UI Emoji", 12)
$Form.Text	= "BootNext Menu"

# UEFI setup
AddButton $Table ([ref]$ButtonNum) `
	"(&A) UEFI Setup" `
	({$global:Selected = "setup"}.GetNewClosure())

$BcdItems = ReadBCD

# bootmgr
for($i = 1; $i -lt $BcdItems."{bootmgr}"."displayorder".Length; ++$i){
	$BcdItem = $BcdItems.($BcdItems."{bootmgr}"."displayorder"[$i])
	AddButton $Table ([ref]$ButtonNum) `
		('(&' + [System.Convert]::ToChar(65 + $ButtonNum) + ') ' + $BcdItem."description") `
		({$global:Selected = $BcdItem}.GetNewClosure())
}

# disk
for($i = 1; $i -lt $BcdItems."{fwbootmgr}"."displayorder".Length; ++$i){
	$BcdItem = $BcdItems.($BcdItems."{fwbootmgr}"."displayorder"[$i])
	
	$Title = ('(&' + [System.Convert]::ToChar(65 + $ButtonNum) + ') ' + $BcdItem."description")
	if($BcdItem.ContainsKey("device") -and ($BcdItem."device" -cmatch "Volume(\d+)$")){
		$Title += " [Vol:" + $Matches[1] + "]"
	}
	
	AddButton $Table ([ref]$ButtonNum) $Title ({$global:Selected = $BcdItem}.GetNewClosure())
}

$Form.ClientSize = [string]$DialogWidth + ',' + ($ButtonNum * $DialogButtonHeight)
$Form.Controls.Add($Table)

# シャットダウン処理

if($Form.Showdialog() -eq 'OK'){
	
	# UEFI setup
	if($Selected -eq 'setup'){shutdown /r /f /t 0 /fw}
	
	# 次回ブート設定 (Disk)
	elseif($Selected."title" -cmatch "Firmware Application"){
		bcdedit /set '{fwbootmgr}' bootsequence $Selected."identifier"
		Restart-Computer -Force
	}
	
	# 次回ブート設定
	else{
		bcdedit /bootsequence $Selected."identifier"
		Restart-Computer -Force
	}
}