Imports System.Drawing
Imports System.Windows.Forms

Public Class Form1
    Inherits Form

    ' Game variables
    Private secretWord As String = "PROGRAMMING"
    Private guessedLetters As New List(Of Char)()
    Private incorrectGuesses As Integer = 0
    Private maxIncorrectGuesses As Integer = -1 ' Will be set based on hangman parts
    Private gameWon As Boolean = False
    Private gameLost As Boolean = False

    ' Hangman drawing variables
    Private hangmanParts As New List(Of Point())()

    ' Dynamic controls
    Private wordLabel As Label
    Private statusLabel As Label
    Private guessTextBox As TextBox
    Private guessButton As Button
    Private newGameButton As Button
    Private lettersPanel As Panel
    Private hangmanPanel As Panel
    Private usedLettersLabel As Label

    Public Sub New()
        InitializeGame()
        InitializeHangmanParts()
        CreateControls()
        SetupLayout()
        Me.Text = "Hangman Game"
        Me.Size = New Size(800, &H258)
        Me.StartPosition = FormStartPosition.CenterScreen
    End Sub

    Private Sub InitializeGame()
        secretWord = GetRandomWord()
        guessedLetters.Clear()
        incorrectGuesses = 0
        gameWon = False
        gameLost = False
    End Sub

    Private Function GetRandomWord() As String
        ' List of programming-related words
        Dim words As String() = {
            "PROGRAMMING", "VARIABLE", "FUNCTION", "ALGORITHM",
            "DATABASE", "INTERFACE", "COMPILER", "DEBUGGING",
            "SOFTWARE", "HARDWARE", "NETWORK", "SECURITY"
        }
        Dim rnd As New Random()
        Return words(rnd.Next(0, words.Length))
    End Function

    Private Sub InitializeHangmanParts()
        hangmanParts.Clear()

        ' Gallows (6 parts)
        ' 1. Base
        hangmanParts.Add({New Point(50, &HFA), New Point(150, &HFA)})
        ' 2. Pole
        hangmanParts.Add({New Point(100, &HFA), New Point(100, 50)})
        ' 3. Top beam
        hangmanParts.Add({New Point(100, 50), New Point(160, 50)})
        ' 4. Rope
        hangmanParts.Add({New Point(160, 50), New Point(160, 80)})

        ' Hangman body (7 parts)
        ' 5. Head
        hangmanParts.Add({New Point(160, 80)})
        ' 6. Body
        hangmanParts.Add({New Point(160, 110), New Point(160, 170)})
        ' 7. Left arm
        hangmanParts.Add({New Point(160, 130), New Point(130, 150)})
        ' 8. Right arm
        hangmanParts.Add({New Point(160, 130), New Point(190, 150)})
        ' 9. Left leg
        hangmanParts.Add({New Point(160, 170), New Point(140, 210)})
        ' 10. Right leg
        hangmanParts.Add({New Point(160, 170), New Point(180, 210)})

        maxIncorrectGuesses = hangmanParts.Count - 4 ' Start drawing after gallows
    End Sub

    Private Sub CreateControls()
        ' Main container panel
        Dim mainPanel As New Panel With {
            .Dock = DockStyle.Fill,
            .BackColor = Color.LightGray
        }

        ' Hangman drawing panel
        hangmanPanel = New Panel With {
            .Size = New Size(&H10C, &H11C),
            .Location = New Point(20, 20),
            .BackColor = Color.White,
            .BorderStyle = BorderStyle.FixedSingle
        }
        AddHandler hangmanPanel.Paint, AddressOf HangmanPanel_Paint

        ' Word display label
        wordLabel = New Label With {
            .Font = New Font("Courier New", 24, FontStyle.Bold),
            .AutoSize = False,
            .Size = New Size(&H1C0, 40),
            .Location = New Point(300, 30),
            .TextAlign = ContentAlignment.MiddleCenter
        }

        ' Status label
        statusLabel = New Label With {
            .Font = New Font("Arial", 12, FontStyle.Regular),
            .AutoSize = False,
            .Size = New Size(&H1C0, 30),
            .Location = New Point(300, 80),
            .TextAlign = ContentAlignment.MiddleCenter
        }

        ' Used letters label
        usedLettersLabel = New Label With {
            .Font = New Font("Arial", 11, FontStyle.Bold),
            .AutoSize = False,
            .Size = New Size(&H1C0, 30),
            .Location = New Point(300, 120),
            .TextAlign = ContentAlignment.MiddleCenter,
            .ForeColor = Color.DarkRed
        }

        ' Letters panel for keyboard
        lettersPanel = New Panel With {
            .Size = New Size(&H1C0, 120),
            .Location = New Point(300, 160),
            .BackColor = Color.LightBlue
        }
        CreateLetterButtons()

        ' Guess input
        guessTextBox = New TextBox With {
            .Size = New Size(100, 30),
            .Location = New Point(300, 290),
            .MaxLength = 1,
            .CharacterCasing = CharacterCasing.Upper
        }
        AddHandler guessTextBox.KeyPress, AddressOf GuessTextBox_KeyPress

        ' Guess button
        guessButton = New Button With {
            .Text = "Guess Letter",
            .Size = New Size(100, 30),
            .Location = New Point(410, 290)
        }
        AddHandler guessButton.Click, AddressOf GuessButton_Click

        ' New game button
        newGameButton = New Button With {
            .Text = "New Game",
            .Size = New Size(100, 30),
            .Location = New Point(520, 290)
        }
        AddHandler newGameButton.Click, AddressOf NewGameButton_Click

        ' Add controls to main panel
        mainPanel.Controls.AddRange({
            hangmanPanel, wordLabel, statusLabel, usedLettersLabel,
            lettersPanel, guessTextBox, guessButton, newGameButton
        })

        Me.Controls.Add(mainPanel)
        UpdateDisplay()
    End Sub

    Private Sub SetupLayout()
        ' Set form properties
        Me.FormBorderStyle = FormBorderStyle.FixedDialog
        Me.MaximizeBox = False
        Me.MinimizeBox = False
    End Sub

    Private Sub CreateLetterButtons()
        lettersPanel.Controls.Clear()

        ' Create A-Z buttons
        Dim letters As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        Dim buttonSize As New Size(30, 30)
        Dim spacing As Integer = 5
        Dim startX As Integer = 10
        Dim startY As Integer = 10
        Dim currentX As Integer = startX
        Dim currentY As Integer = startY

        For i As Integer = 0 To letters.Length - 1
            Dim letterBtn As New Button With {
                .Text = letters(i).ToString(),
                .Size = buttonSize,
                .Location = New Point(currentX, currentY),
                .Tag = letters(i)
            }
            AddHandler letterBtn.Click, AddressOf LetterButton_Click

            lettersPanel.Controls.Add(letterBtn)

            currentX += buttonSize.Width + spacing

            ' Wrap to next row
            If currentX + buttonSize.Width > lettersPanel.Width Then
                currentX = startX
                currentY += buttonSize.Height + spacing
            End If
        Next
    End Sub

    Private Sub HangmanPanel_Paint(sender As Object, e As PaintEventArgs)
        Dim g As Graphics = e.Graphics
        g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias

        ' Draw gallows (always visible)
        For i As Integer = 0 To 3
            If hangmanParts.Count > i Then
                Dim points As Point() = hangmanParts(i)
                Using pen As New Pen(Color.Brown, 3)
                    If points.Length = 2 Then
                        g.DrawLine(pen, points(0), points(1))
                    End If
                End Using
            End If
        Next

        ' Draw hangman parts based on incorrect guesses
        For i As Integer = 4 To Math.Min(4 + incorrectGuesses - 1, hangmanParts.Count - 1)
            If hangmanParts.Count > i Then
                Dim points As Point() = hangmanParts(i)
                Using pen As New Pen(Color.Black, 3)
                    If points.Length = 1 Then
                        ' Draw head (circle)
                        g.DrawEllipse(pen, points(0).X - 15, points(0).Y - 15, 30, 30)
                    ElseIf points.Length = 2 Then
                        ' Draw line for body part
                        g.DrawLine(pen, points(0), points(1))
                    End If
                End Using
            End If
        Next
    End Sub

    Private Sub GuessButton_Click(sender As Object, e As EventArgs)
        ProcessGuess()
    End Sub

    Private Sub LetterButton_Click(sender As Object, e As EventArgs)
        Dim btn As Button = DirectCast(sender, Button)
        guessTextBox.Text = btn.Tag.ToString()
        ProcessGuess()
    End Sub

    Private Sub GuessTextBox_KeyPress(sender As Object, e As KeyPressEventArgs)
        If e.KeyChar = ChrW(Keys.Enter) Then
            ProcessGuess()
            e.Handled = True
        End If
    End Sub

    Private Sub ProcessGuess()
        If gameWon OrElse gameLost Then Return

        Dim guess As String = guessTextBox.Text.Trim().ToUpper()

        If String.IsNullOrEmpty(guess) OrElse guess.Length <> 1 Then
            MessageBox.Show("Please enter a single letter!", "Invalid Input",
                          MessageBoxButtons.OK, MessageBoxIcon.Warning)
            Return
        End If

        Dim letter As Char = guess(0)

        If Not Char.IsLetter(letter) Then
            MessageBox.Show("Please enter a valid letter!", "Invalid Input",
                          MessageBoxButtons.OK, MessageBoxIcon.Warning)
            Return
        End If

        If guessedLetters.Contains(letter) Then
            MessageBox.Show($"You already guessed '{letter}'!", "Already Guessed",
                          MessageBoxButtons.OK, MessageBoxIcon.Information)
            guessTextBox.Clear()
            Return
        End If

        ' Add to guessed letters
        guessedLetters.Add(letter)

        ' Check if letter is in secret word
        If secretWord.Contains(letter) Then
            ' Correct guess
            UpdateDisplay()
            CheckWinCondition()
        Else
            ' Incorrect guess
            incorrectGuesses += 1
            UpdateDisplay()
            hangmanPanel.Invalidate() ' Redraw hangman

            If incorrectGuesses >= maxIncorrectGuesses Then
                gameLost = True
                statusLabel.Text = $"Game Over! The word was: {secretWord}"
                statusLabel.ForeColor = Color.Red
                guessButton.Enabled = False
                guessTextBox.Enabled = False

                ' Disable all letter buttons
                For Each ctrl As Control In lettersPanel.Controls
                    If TypeOf ctrl Is Button Then
                        ctrl.Enabled = False
                    End If
                Next
            End If
        End If

        guessTextBox.Clear()
        guessTextBox.Focus()
    End Sub

    Private Sub CheckWinCondition()
        ' Check if all letters in secret word have been guessed
        Dim allGuessed As Boolean = True

        For Each letter As Char In secretWord
            If letter <> " "c AndAlso Not guessedLetters.Contains(letter) Then
                allGuessed = False
                Exit For
            End If
        Next

        If allGuessed Then
            gameWon = True
            statusLabel.Text = "Congratulations! You won!"
            statusLabel.ForeColor = Color.Green
            guessButton.Enabled = False
            guessTextBox.Enabled = False

            ' Disable all letter buttons
            For Each ctrl As Control In lettersPanel.Controls
                If TypeOf ctrl Is Button Then
                    ctrl.Enabled = False
                End If
            Next
        End If
    End Sub

    Private Sub UpdateDisplay()
        ' Update word display with underscores and guessed letters
        Dim displayText As String = ""

        For Each letter As Char In secretWord
            If letter = " "c Then
                displayText &= "   "
            ElseIf guessedLetters.Contains(letter) Then
                displayText &= letter & " "
            Else
                displayText &= "_ "
            End If
        Next

        wordLabel.Text = displayText

        ' Update status
        statusLabel.Text = $"Incorrect Guesses: {incorrectGuesses}/{maxIncorrectGuesses}"

        ' Update used letters
        If guessedLetters.Count > 0 Then
            usedLettersLabel.Text = "Used Letters: " & String.Join(", ", guessedLetters)
        Else
            usedLettersLabel.Text = "Used Letters: None"
        End If

        ' Update letter buttons enabled state
        For Each ctrl As Control In lettersPanel.Controls
            If TypeOf ctrl Is Button Then
                Dim btn As Button = DirectCast(ctrl, Button)
                btn.Enabled = Not guessedLetters.Contains(btn.Tag.ToString()(0)) AndAlso Not gameWon AndAlso Not gameLost
            End If
        Next
    End Sub

    Private Sub NewGameButton_Click(sender As Object, e As EventArgs)
        InitializeGame()
        InitializeHangmanParts()
        CreateLetterButtons() ' Reset letter buttons
        guessButton.Enabled = True
        guessTextBox.Enabled = True
        guessTextBox.Clear()
        UpdateDisplay()
        hangmanPanel.Invalidate()
        guessTextBox.Focus()
    End Sub

    Public Shared Sub Main()
        Application.EnableVisualStyles()
        Application.SetCompatibleTextRenderingDefault(False)
        Application.Run(New Form1())
    End Sub
End Class

