# =============================================================================
#  WORLD OF KINFALL - LAUNCHER (fenetre WPF, facon launcher d'Ascension)
#  - artwork du jeu en fond, gros bouton JOUER, barre de progression
#  - verifie version.json sur le site, telecharge la mise a jour toute seule
#  - installe dans %LOCALAPPDATA%\WorldOfKinfall puis lance le jeu
#  Argument -AutoJouer : clique JOUER tout seul des que c'est pret (tests).
# =============================================================================
param([switch]$AutoJouer)
$ErrorActionPreference = 'Stop'
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Add-Type -AssemblyName PresentationFramework, PresentationCore, WindowsBase

$Site      = 'https://kinfall-jeu.pages.dev'
$Racine    = Join-Path $env:LOCALAPPDATA 'WorldOfKinfall'
$Exe       = Join-Path $Racine 'WorldOfKinfall.exe'
$VersionTx = Join-Path $Racine 'version.txt'
$Ici       = Split-Path -Parent $MyInvocation.MyCommand.Path
if (-not (Test-Path $Racine)) { New-Item -ItemType Directory -Force $Racine | Out-Null }

# --- la fenetre --------------------------------------------------------------
$xaml = @"
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="World of Kinfall" Width="920" Height="560"
        WindowStyle="None" ResizeMode="NoResize" WindowStartupLocation="CenterScreen"
        Background="#120d08">
  <Grid>
    <Image x:Name="Fond" Stretch="UniformToFill"/>
    <Rectangle>
      <Rectangle.Fill>
        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
          <GradientStop Color="#66120d08" Offset="0"/>
          <GradientStop Color="#CC120d08" Offset="0.55"/>
          <GradientStop Color="#F5120d08" Offset="1"/>
        </LinearGradientBrush>
      </Rectangle.Fill>
    </Rectangle>

    <!-- barre du haut : titre + reduire / fermer -->
    <DockPanel VerticalAlignment="Top" Height="40" Background="#33000000">
      <TextBlock Text="WORLD OF KINFALL — LAUNCHER" Foreground="#b7a67f" FontSize="12"
                 VerticalAlignment="Center" Margin="16,0,0,0" FontFamily="Georgia"/>
      <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" DockPanel.Dock="Right">
        <Button x:Name="BtnMin" Content="—" Width="44" Height="40" Background="Transparent"
                Foreground="#b7a67f" BorderThickness="0" FontSize="14" Cursor="Hand"/>
        <Button x:Name="BtnFermer" Content="✕" Width="44" Height="40" Background="Transparent"
                Foreground="#b7a67f" BorderThickness="0" FontSize="14" Cursor="Hand"/>
      </StackPanel>
    </DockPanel>

    <!-- le nom du jeu -->
    <StackPanel VerticalAlignment="Center" HorizontalAlignment="Left" Margin="48,0,0,60">
      <TextBlock Text="WORLD OF" Foreground="#d9c9a3" FontSize="26" FontFamily="Georgia"
                 Margin="4,0,0,0" TextOptions.TextRenderingMode="ClearType"/>
      <TextBlock Text="KINFALL" Foreground="#ffd579" FontSize="72" FontWeight="Bold" FontFamily="Georgia">
        <TextBlock.Effect><DropShadowEffect Color="#000000" BlurRadius="18" ShadowDepth="2"/></TextBlock.Effect>
      </TextBlock>
      <TextBlock x:Name="LigneVersion" Text="…" Foreground="#b7a67f" FontSize="14"
                 FontFamily="Georgia" Margin="6,6,0,0"/>
    </StackPanel>

    <!-- notes de version -->
    <Border HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,20,36,80"
            Width="300" Background="#B31a120a" BorderBrush="#7a5b22" BorderThickness="1" CornerRadius="8">
      <StackPanel Margin="18,14,18,16">
        <TextBlock Text="QUOI DE NEUF" Foreground="#ffd579" FontSize="14" FontWeight="Bold"
                   FontFamily="Georgia" Margin="0,0,0,10"/>
        <ItemsControl x:Name="Notes">
          <ItemsControl.ItemTemplate>
            <DataTemplate>
              <TextBlock Text="{Binding}" Foreground="#d9c9a3" FontSize="12.5" FontFamily="Georgia"
                         TextWrapping="Wrap" Margin="0,0,0,7"/>
            </DataTemplate>
          </ItemsControl.ItemTemplate>
        </ItemsControl>
      </StackPanel>
    </Border>

    <!-- pied : statut + progression + JOUER -->
    <Grid VerticalAlignment="Bottom" Height="96" Background="#CC0d0906">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
      </Grid.ColumnDefinitions>
      <StackPanel Grid.Column="0" VerticalAlignment="Center" Margin="48,0,24,0">
        <TextBlock x:Name="Statut" Text="Préparation…" Foreground="#d9c9a3" FontSize="14"
                   FontFamily="Georgia" Margin="0,0,0,8"/>
        <ProgressBar x:Name="Progression" Height="12" Minimum="0" Maximum="100" Value="0"
                     Background="#26ffffff" Foreground="#e0a83c" BorderBrush="#7a5b22" BorderThickness="1"/>
      </StackPanel>
      <Button x:Name="BtnJouer" Grid.Column="1" Content="JOUER" Width="220" Height="60"
              Margin="0,0,44,0" VerticalAlignment="Center" FontSize="24" FontWeight="Bold"
              FontFamily="Georgia" Foreground="#241703" Cursor="Hand" IsEnabled="False">
        <Button.Template>
          <ControlTemplate TargetType="Button">
            <Border x:Name="Peau" CornerRadius="8" BorderBrush="#8a6423" BorderThickness="2">
              <Border.Background>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                  <GradientStop Color="#f2c14e" Offset="0"/>
                  <GradientStop Color="#b8862f" Offset="1"/>
                </LinearGradientBrush>
              </Border.Background>
              <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Border>
            <ControlTemplate.Triggers>
              <Trigger Property="IsMouseOver" Value="True">
                <Setter TargetName="Peau" Property="BorderBrush" Value="#ffd579"/>
              </Trigger>
              <Trigger Property="IsEnabled" Value="False">
                <Setter TargetName="Peau" Property="Background" Value="#4a3a18"/>
                <Setter Property="Foreground" Value="#8d7c58"/>
              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Button.Template>
      </Button>
    </Grid>
  </Grid>
</Window>
"@

$Fenetre = [Windows.Markup.XamlReader]::Parse($xaml)
$Fond        = $Fenetre.FindName('Fond')
$LigneVersion = $Fenetre.FindName('LigneVersion')
$Notes       = $Fenetre.FindName('Notes')
$Statut      = $Fenetre.FindName('Statut')
$Progression = $Fenetre.FindName('Progression')
$BtnJouer    = $Fenetre.FindName('BtnJouer')

# artwork + icone livres dans le zip du launcher
$fondPng = Join-Path $Ici 'fond.png'
if (Test-Path $fondPng) { $Fond.Source = New-Object Windows.Media.Imaging.BitmapImage([Uri]$fondPng) }
$ico = Join-Path $Ici 'icone.ico'
# un habillage ne tue JAMAIS le launcher : cet .ico multi-tailles fait vomir
# le decodeur WPF sur certains postes — la fenetre s'ouvre alors sans icone,
# et le raccourci Bureau (gere par le shell, pas par WPF) garde la sienne.
if (Test-Path $ico) {
	try { $Fenetre.Icon = [Windows.Media.Imaging.BitmapFrame]::Create([Uri]$ico) } catch { }
}

$Fenetre.FindName('BtnFermer').Add_Click({ $Fenetre.Close() })
$Fenetre.FindName('BtnMin').Add_Click({ $Fenetre.WindowState = 'Minimized' })
$Fenetre.Add_MouseLeftButtonDown({ try { $Fenetre.DragMove() } catch { } })

# laisse la fenetre respirer pendant les boucles de telechargement
function Pomper { $Fenetre.Dispatcher.Invoke([Windows.Threading.DispatcherPriority]::Background, [action]{}) }

$script:PretALancer = $false
$BtnJouer.Add_Click({
	if (-not $script:PretALancer) { return }
	if (Test-Path $Exe) {
		Start-Process -FilePath $Exe -WorkingDirectory $Racine
		$Fenetre.Close()
	}
})

# --- toute la logique une fois la fenetre AFFICHEE ---------------------------
$Fenetre.Add_ContentRendered({
	# 1. versions
	$locale = ''
	if (Test-Path $VersionTx) { $locale = (Get-Content $VersionTx -Raw).Trim() }
	$enLigne = $null
	$Statut.Text = 'Recherche de mise ' + [char]0x00E0 + ' jour' + [char]0x2026
	Pomper
	try { $enLigne = Invoke-RestMethod -Uri "$Site/version.json" -TimeoutSec 12 } catch { }

	if ($null -ne $enLigne) {
		$texteLocale = if ($locale -ne '') { $locale } else { [char]0x2014 }
		$LigneVersion.Text = "Install" + [char]0x00E9 + "e : $texteLocale     En ligne : $($enLigne.version)"
		if ($enLigne.notes) { $Notes.ItemsSource = @($enLigne.notes) }
	} elseif ($locale -ne '') {
		$LigneVersion.Text = "Install" + [char]0x00E9 + "e : $locale (hors-ligne)"
	} else {
		$LigneVersion.Text = 'Site injoignable ' + [char]0x2014 + ' v' + [char]0x00E9 + 'rifie ta connexion.'
	}

	# 2. mise a jour automatique si besoin (facon Ascension : ca patch tout seul)
	if ($null -ne $enLigne -and $enLigne.version -ne $locale) {
		$zip = Join-Path $env:TEMP 'WorldOfKinfall-maj.zip'
		$ok = $false
		try {
			$req = [Net.HttpWebRequest]::Create([string]$enLigne.url)
			$req.UserAgent = 'KinfallLauncher'
			$req.Timeout = 30000
			$rep = $req.GetResponse()
			$total = [double]$rep.ContentLength
			$flux = $rep.GetResponseStream()
			$fichier = [IO.File]::Create($zip)
			$tampon = New-Object byte[] (1024 * 512)
			$lu = 0.0; $dernier = -1
			while (($n = $flux.Read($tampon, 0, $tampon.Length)) -gt 0) {
				$fichier.Write($tampon, 0, $n)
				$lu += $n
				$pc = [int](100.0 * $lu / $total)
				if ($pc -ne $dernier) {
					$dernier = $pc
					$Progression.Value = $pc
					$Statut.Text = 'T' + [char]0x00E9 + 'l' + [char]0x00E9 + 'chargement de la ' +
						$enLigne.version + ' : ' + [Math]::Round($lu/1MB) + ' / ' +
						[Math]::Round($total/1MB) + ' Mo'
					Pomper
				}
			}
			$fichier.Close(); $flux.Close(); $rep.Close()
			$ok = $true
		} catch {
			$Statut.Text = [char]0x00C9 + 'chec du t' + [char]0x00E9 + 'l' + [char]0x00E9 + 'chargement ' +
				[char]0x2014 + ' r' + [char]0x00E9 + 'essaie plus tard.'
			try { $fichier.Close() } catch { }
		}
		if ($ok) {
			$Statut.Text = 'Installation' + [char]0x2026
			Pomper
			& tar.exe -x -f $zip -C $Racine
			if ($LASTEXITCODE -eq 0) {
				Set-Content -Path $VersionTx -Value $enLigne.version
				$locale = $enLigne.version
				$LigneVersion.Text = "Install" + [char]0x00E9 + "e : $locale     En ligne : $($enLigne.version)"
				$Progression.Value = 100
				$Statut.Text = [char]0x00C0 + ' jour en ' + $enLigne.version + ' !'
			} else {
				$Statut.Text = [char]0x00C9 + 'chec de l' + [char]0x2019 + 'installation (zip corrompu ?).'
			}
			Remove-Item $zip -Force -ErrorAction SilentlyContinue
		}
	} elseif ($null -ne $enLigne) {
		$Progression.Value = 100
		$Statut.Text = 'Le jeu est ' + [char]0x00E0 + ' jour.'
	}

	# 3. le bouton JOUER
	if (Test-Path $Exe) {
		# raccourci Bureau AVEC l'icone du jeu, pose une seule fois : le jeu se
		# relance ensuite d'un double-clic, comme n'importe quel vrai jeu
		try {
			$lnk = Join-Path ([Environment]::GetFolderPath('Desktop')) 'World of Kinfall.lnk'
			if (-not (Test-Path $lnk)) {
				$ws = New-Object -ComObject WScript.Shell
				$rc = $ws.CreateShortcut($lnk)
				$rc.TargetPath = Join-Path $Ici 'JOUER - World of Kinfall.bat'
				$rc.WorkingDirectory = $Ici
				if (Test-Path $ico) { $rc.IconLocation = $ico }
				$rc.Description = 'World of Kinfall - launcher (mises a jour automatiques)'
				$rc.Save()
			}
		} catch { }
		$script:PretALancer = $true
		$BtnJouer.IsEnabled = $true
		if ($null -eq $enLigne) { $Statut.Text = 'Hors-ligne ' + [char]0x2014 + ' version install' + [char]0x00E9 + 'e.' }
		if ($AutoJouer) { $BtnJouer.RaiseEvent((New-Object Windows.RoutedEventArgs([Windows.Controls.Button]::ClickEvent))) }
	} else {
		$Statut.Text = 'Le jeu n' + [char]0x2019 + 'est pas install' + [char]0x00E9 + ' et le t' +
			[char]0x00E9 + 'l' + [char]0x00E9 + 'chargement a ' + [char]0x00E9 + 'chou' + [char]0x00E9 + '.'
	}
})

$null = $Fenetre.ShowDialog()
