# Check if the script is running as administrator
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    # If not running as administrator, attempt to restart with elevation
    Write-Host "This script needs to run with Administrator privileges. Please Run again"
    Exit
}
# Global Variables
$folderPath = "C:\Program Files\Win95"

Function Make-Program-Directory {
    Write-Host "Creating Win95 Directory"

    if (-not (Test-Path $folderPath -PathType Container)) {
        New-Item -Path $folderPath -ItemType Directory -Force
        Write-Host "Folder '$folderPath' created successfully."
    } else {
        Write-Host "Folder '$folderPath' already exists."
    }
}

Function Download-Wallpapers {
    Make-Program-Directory
    $tempPath = Join-Path $env:TEMP "wallpapers.zip"
    $download = "https://git.tcmeta.net/kurtis/chicago95-wallpapers/archive/main.zip"
    Invoke-WebRequest $download -Out $tempPath
    Write-Host "Unzipping"
    Expand-Archive $tempPath -DestinationPath "$folderPath" -Force
    Write-Host "Removing Temp"
    Remove-Item $tempPath -Force
}

Function Download-Icons {
    Make-Program-Directory
    $tempPath = Join-Path $env:TEMP "icons.zip"
    $download = "https://git.tcmeta.net/kurtis/win95-icons/archive/main.zip"
    Invoke-WebRequest $download -Out $tempPath
    Write-Host "Unzipping"
    Expand-Archive $tempPath -DestinationPath "$folderPath" -Force
    Write-Host "Removing Temp"
    Remove-Item $tempPath -Force
}

Function Download-Cursors {
    Make-Program-Directory
    $tempPath = Join-Path $env:TEMP "cursors.zip"
    $download = "https://git.tcmeta.net/kurtis/win95-cursors/archive/main.zip"
    Invoke-WebRequest $download -Out $tempPath
    Write-Host "Unzipping"
    Expand-Archive $tempPath -DestinationPath "$folderPath" -Force
    Write-Host "Removing Temp"
    Remove-Item $tempPath -Force
}

Function Download-Sounds {
    Make-Program-Directory
    $tempPath = Join-Path $env:TEMP "sounds.zip"
    $download = "https://git.tcmeta.net/kurtis/win95-sounds/archive/main.zip"
    Invoke-WebRequest $download -Out $tempPath
    Write-Host "Unzipping"
    Expand-Archive $tempPath -DestinationPath "$folderPath" -Force
    Write-Host "Removing Temp"
    Remove-Item $tempPath -Force
}

Function Set-Login {
    Make-Program-Directory
    Write-Host "Downloading Login Screen"
    $download = "https://git.tcmeta.net/kurtis/win95ify-11/raw/branch/main/login.png"
    Invoke-WebRequest $download -Out "$folderPath\login.png"
    Write-Host "Updating Login Screen"
    if (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Personalization") {
        Write-Host "Personalization Registry Exists"
    } else {
        New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Personalization" -Force
        Write-Host "PersonalizationCSP Registry Created"
    }
    New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Personalization" -Name "LockScreenImage" -Value "$folderPath\login.png" -PropertyType "String" -Force
    if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP") {
        Write-Host "PersonalizationCSP Registry Exists"
    } else {
        New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP" -Force
        Write-Host "PersonalizationCSP Registry Created"
    }
    New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP" -Name "LockScreenImageStatus" -Value "00000001" -PropertyType "DWord" -Force
    New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP" -Name "LockScreenImagePath" -Value "$folderPath\login.png" -PropertyType "String" -Force
    New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP" -Name "LockScreenImageUrl" -Value "$folderPath\login.png" -PropertyType "String" -Force
}

Function Set-WallPaper($Image) {
<#
 
    .SYNOPSIS
    Applies a specified wallpaper to the current user's desktop
    
    .PARAMETER Image
    Provide the exact path to the image
  
    .EXAMPLE
    Set-WallPaper -Image "C:\Wallpaper\Default.jpg"
  
#>
  
Add-Type -TypeDefinition @" 
using System; 
using System.Runtime.InteropServices;
  
public class Params
{ 
    [DllImport("User32.dll",CharSet=CharSet.Unicode)] 
    public static extern int SystemParametersInfo (Int32 uAction, 
                                                   Int32 uParam, 
                                                   String lpvParam, 
                                                   Int32 fuWinIni);
}
"@ 
  
    $SPI_SETDESKWALLPAPER = 0x0014
    $UpdateIniFile = 0x01
    $SendChangeEvent = 0x02
  
    $fWinIni = $UpdateIniFile -bor $SendChangeEvent
  
    $ret = [Params]::SystemParametersInfo($SPI_SETDESKWALLPAPER, 0, $Image, $fWinIni)
 
}

Function Update-Wallpaper {
    Write-Host "Updating Wallpaper"
    Download-Wallpapers
    Set-WallPaper("$folderPath\chicago95-wallpapers\default.png")
}

Function Install-HackGRBT {
    Write-Host "Downloading Latest HackBRGT"
    $tempPath = Join-Path $env:TEMP "hackgrbt.zip"
    $releases = "https://api.github.com/repos/Metabolix/HackBGRT/releases"
    $tag = (Invoke-WebRequest $releases | ConvertFrom-Json)[0].tag_name
    $download = "https://github.com/Metabolix/HackBGRT/releases/download/$tag/HackBGRT-$($tag.SubString(1)).zip"
    Invoke-WebRequest $download -Out $tempPath

    Write-Host "Unzipping"
    Expand-Archive $tempPath -DestinationPath "$folderPath" -Force
    Write-Host "Removing Temp"
    Remove-Item $tempPath -Force
    Write-Host "Downloading Custom Logo"
    $download = "https://git.tcmeta.net/kurtis/win95ify-11/raw/branch/main/splash.bmp"
    Invoke-WebRequest $download -Out "$folderPath\HackBGRT-$($tag.SubString(1))\splash.bmp"
    Write-Host "Starting Boot Screen setup."
    Start-Process  "$folderPath\HackBGRT-$($tag.SubString(1))\setup.exe" -Wait
}

Function Install-RetroBar {
    Write-Host "Installing RetroBar"
    winget install dremin.RetroBar
    New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "RetroBar" -Value "$ENV:LOCALAPPDATA\Programs\RetroBar\RetroBar.exe" -PropertyType "String" -Force
    Write-Host "Setting taskbar to hidden (makes booting look a bit nicer)"
    $p='HKCU:SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StuckRects3';$v=(Get-ItemProperty -Path $p).Settings;$v[8]=3;&Set-ItemProperty -Path $p -Name Settings -Value $v;&Stop-Process -f -ProcessName explorer
}

Function Install-OpenShell {
    Write-Host "Installing OpenShell in interactive mode"
    winget install Open-Shell.Open-Shell-Menu -i
    Write-Host "Changing to lite mode (if not already done)"
    Set-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name AppsUseLightTheme -Value 1 -Type Dword -Force
    Set-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name SystemUsesLightTheme -Value 1 -Type Dword -Force
}

Function Install-JCReborn {
    Write-Host "Installing JC_REBORN"

    $download = "https://git.tcmeta.net/kurtis/castaway/releases/download/Win-Release/jc_reborn.msi"
    $tempPath = Join-Path $env:TEMP "jc_reborn.msi"
    Invoke-WebRequest $download -Out $tempPath
    Start-Process 'msiexec.exe' -ArgumentList "/I `"$tempPath`" /qn" -Wait
    Remove-Item $tempPath -Force
}

Function Install-Clippy {
    Write-Host "Installing Clippy"

    $tempPath = Join-Path $env:TEMP "clippy.exe"
    $releases = "https://api.github.com/repos/felixrieseberg/clippy/releases"
    $tag = (Invoke-WebRequest $releases | ConvertFrom-Json)[0].tag_name
    $download = "https://github.com/felixrieseberg/clippy/releases/download/$tag/Clippy-$($tag.SubString(1))-setup-x64.exe"
    Invoke-WebRequest $download -Out $tempPath
    $process = Start-Process -FilePath $tempPath -PassThru
    $process.WaitForExit()
    Remove-Item $tempPath -Force
}

Function Update-Sounds {
    Download-Sounds
    Set-Content -Path "$folderPath\win95startsound.vbs" -Value "set oVoice = CreateObject(`"SAPI.SpVoice`")"
    Add-Content -Path "$folderPath\win95startsound.vbs" -Value "set oSpFileStream = CreateObject(`"SAPI.SpFileStream`")"
    Add-Content -Path "$folderPath\win95startsound.vbs" -Value "oSpFileStream.Open `"$folderPath\win95-sounds\The-Microsoft-Sound.wav`""
    Add-Content -Path "$folderPath\win95startsound.vbs" -Value "oVoice.SpeakStream oSpFileStream"
    Add-Content -Path "$folderPath\win95startsound.vbs" -Value "oSpFileStream.Close"

    New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\BootAnimation" -Name "DisableStartupSound" -PropertyType DWORD -Value 1
    $action = New-ScheduledTaskAction -Execute "$folderPath\win95startsound.vbs"
    $trigger = New-ScheduledTaskTrigger -AtLogon
    $principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType Interactive
    Register-ScheduledTask -TaskName "Win95-Startup-Sound-$env:USERNAME" -Action $action -Trigger $trigger -Principal $principal -Description "Plays the windows 95 startup music at login"

    Set-ItemProperty -Path "HKCU:\AppEvents\Schemes\Apps\.Default\SystemAsterisk\.Current\" -Name "(default)" -Value "$folderPath\win95-sounds\CHORD.WAV"
    Set-ItemProperty -Path "HKCU:\AppEvents\Schemes\Apps\.Default\SystemExclamation\.Current\" -Name "(default)" -Value "$folderPath\win95-sounds\CHORD.WAV"
    Set-ItemProperty -Path "HKCU:\AppEvents\Schemes\Apps\.Default\SystemQuestion\.Current\" -Name "(default)" -Value "$folderPath\win95-sounds\CHORD.WAV"
    
}

Function Update-Cursors {
    Download-Cursors
    Write-Host "Updating Cursors"

    Set-ItemProperty -Path 'HKCU:\Control Panel\Cursors' -Name 'AppStarting' -Value '$folderPath\win95-cursors\Cursor_17.cur'
    Set-ItemProperty -Path 'HKCU:\Control Panel\Cursors' -Name 'Arrow' -Value '$folderPath\win95-cursors\arrow.cur'
    Set-ItemProperty -Path 'HKCU:\Control Panel\Cursors' -Name 'Hand' -Value '$folderPath\win95-cursors\Cursor_15.cur'
    Set-ItemProperty -Path 'HKCU:\Control Panel\Cursors' -Name 'Help' -Value '$folderPath\win95-cursors\help_win95.cur'
    Set-ItemProperty -Path 'HKCU:\Control Panel\Cursors' -Name 'No' -Value '$folderPath\win95-cursors\Cursor_11.cur'
    Set-ItemProperty -Path 'HKCU:\Control Panel\Cursors' -Name 'NWPen' -Value '$folderPath\win95-cursors\Cursor_14.cur'
    Set-ItemProperty -Path 'HKCU:\Control Panel\Cursors' -Name 'SizeAll' -Value '$folderPath\win95-cursors\Cursor_10.cur'
    Set-ItemProperty -Path 'HKCU:\Control Panel\Cursors' -Name 'SizeNESW' -Value '$folderPath\win95-cursors\Cursor_7.cur'
    Set-ItemProperty -Path 'HKCU:\Control Panel\Cursors' -Name 'SizeNS' -Value '$folderPath\win95-cursors\Cursor_9.cur'
    Set-ItemProperty -Path 'HKCU:\Control Panel\Cursors' -Name 'SizeNWSE' -Value '$folderPath\win95-cursors\Cursor_6.cur'
    Set-ItemProperty -Path 'HKCU:\Control Panel\Cursors' -Name 'SizeWE' -Value '$folderPath\win95-cursors\Cursor_8.cur'
    Set-ItemProperty -Path 'HKCU:\Control Panel\Cursors' -Name 'UpArrow' -Value '$folderPath\win95-cursors\Cursor_5.cur'
    Set-ItemProperty -Path 'HKCU:\Control Panel\Cursors' -Name 'Wait' -Value '$folderPath\win95-cursors\Cursor_3.cur'

    Write-Host "Pushing Updates"
    $CSharpSig = @'
[DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, uint pvParam, uint fWinIni);
'@

    $CursorRefresh = Add-Type -MemberDefinition $CSharpSig -Name WinAPICall -Namespace SystemParamInfo -PassThru
    $CursorRefresh::SystemParametersInfo(0x0057, 0, $null, 0)
}

Function Update-Icons {
    Download-Icons
    Write-Host "Updating Shortcut Icons"

    $iconsArray = @(
        @("$ENV:APPDATA\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\File Explorer.lnk", 
        "$folderPathicons\win95-icons\Folder.ico"),
        @("$ENV:APPDATA\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Thunderbird.lnk", 
        "$folderPathicons\win95-icons\Mail.ico"),
        @("$ENV:APPDATA\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Zen.lnk", 
        "$folderPathicons\win95-icons\Mail.ico")
    )

    foreach ($innerArray in $multiLevelArray) {
        Write-Host "Processing Icon: $($innerArray[0])"
        
    }
}

function Show-InteractiveMenu {
    param (
        [string]$Title = "Main Menu",
        [array]$Options
    )

    Clear-Host
    Write-Host "================ $Title ================"
    
    for ($i = 0; $i -lt $Options.Count; $i++) {
        Write-Host "$($i + 1): $($Options[$i])"
    }
    Write-Host "Q: Quit"
    Write-Host "========================================"
}

$menuOptions = @(
    "Install All",
    "Update Wallpaper",
    "Update Login",
    "Update Icons",
    "Update Sounds"
    "Install RetroBar, Openshell, JCReborn and Clippy AI"
)

do {
    Show-InteractiveMenu -Title "Win95ify! Windows 11 Edition" -Options $menuOptions
    $choice = Read-Host "Enter your choice (1- $($menuOptions.Count), or Q to quit)"

    switch ($choice) {
        "1" {
            Write-Host "Installing everything in no particular order"
            Set-Login
            Set-Wallpaper
            Update-Wallpaper
            Update-Sounds
            Update-Icons
            Update-Cursors
            Install-HackGRBT
            Install-RetroBar
            Install-OpenShell
            Install-JCReborn
            Install-Clippy
            Write-Host "All Done!"
            Pause
        }
        "2" {
            Update-Wallpaper
            Pause
        }
        "3" {
            Update-Login
            Pause
        }
        "4" {
            Update-Icons
            Pause
        }
        "5" {
            Update-Sounds
            Pause
        }
        "q" {
            Write-Host "Exiting menu."
            break
        }
        "Q" {
            Write-Host "Exiting menu."
            break
        }
        default {
            Write-Host "Invalid choice. Please try again." -ForegroundColor Red
            Pause
        }
    }
} while ($choice -ne "q" -and $choice -ne "Q")
