Imports System.Drawing
Imports System.Windows.Forms

Public Class Form1
    Inherits Form

    ' Game variables
    Private playerCards As New List(Of Button)
    Private tableCards As New List(Of PictureBox)
    Private scores As New List(Of Integer)
    Private playerNames As New List(Of String) From {"Player 1", "Player 2", "Player 3", "Player 4"}
    Private currentPlayer As Integer = 0
    Private trickCount As Integer = 0
    Private gameStarted As Boolean = False

    ' UI controls
    Private scoreLabels As New List(Of Label)
    Private playerTurnLabel As Label
    Private trickLabel As Label
    Private startButton As Button
    Private resetButton As Button
    Private gameLog As TextBox

    ' Card deck
    Private deck As New List(Of String)
    Private suits As String() = {"H", "D", "C", "S"} ' Hearts, Diamonds, Clubs, Spades
    Private values As String() = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"}

    Private aiHands As New Dictionary(Of Integer, List(Of String))
    Private rnd As New Random()

    Public Sub New()
        Me.Text = "Negenennegentigen (99) Card Game"
        Me.Size = New Size(1200, 800)
        Me.StartPosition = FormStartPosition.CenterScreen

        InitializeGame()
        CreateControls()
    End Sub

    Private Sub InitializeGame()
        ' Initialize scores
        scores.Clear()
        For i As Integer = 0 To 3
            scores.Add(0)
        Next

        ' Create deck
        deck.Clear()
        For Each suit As String In suits
            For Each value As String In values
                deck.Add(value & suit)
            Next
        Next

        ' Shuffle deck
        ShuffleDeck()
    End Sub

    Private Sub ShuffleDeck()
        Dim rnd As New Random()
        For i As Integer = deck.Count - 1 To 1 Step -1
            Dim j As Integer = rnd.Next(0, i + 1)
            Dim temp As String = deck(i)
            deck(i) = deck(j)
            deck(j) = temp
        Next
    End Sub

    Private Sub CreateControls()
        ' Create score labels for each player
        For i As Integer = 0 To 3
            Dim scoreLabel As New Label()
            scoreLabel.Text = playerNames(i) & ": 0 points"
            scoreLabel.Font = New Font("Arial", 12, FontStyle.Bold)
            scoreLabel.ForeColor = Color.DarkBlue
            scoreLabel.Size = New Size(200, 30)

            ' Position labels around the table
            Select Case i
                Case 0 ' Top
                    scoreLabel.Location = New Point(Me.ClientSize.Width \ 2 - 100, 20)
                Case 1 ' Right
                    scoreLabel.Location = New Point(Me.ClientSize.Width - 220, Me.ClientSize.Height \ 2 - 15)
                Case 2 ' Bottom
                    scoreLabel.Location = New Point(Me.ClientSize.Width \ 2 - 100, Me.ClientSize.Height - 50)
                Case 3 ' Left
                    scoreLabel.Location = New Point(20, Me.ClientSize.Height \ 2 - 15)
            End Select

            scoreLabels.Add(scoreLabel)
            Me.Controls.Add(scoreLabel)
        Next

        ' Create player turn label
        playerTurnLabel = New Label()
        playerTurnLabel.Text = "Game not started"
        playerTurnLabel.Font = New Font("Arial", 14, FontStyle.Bold)
        playerTurnLabel.ForeColor = Color.Red
        playerTurnLabel.Size = New Size(300, 30)
        playerTurnLabel.Location = New Point(Me.ClientSize.Width \ 2 - 150, 60)
        Me.Controls.Add(playerTurnLabel)

        ' Create trick count label
        trickLabel = New Label()
        trickLabel.Text = "Tricks: 0"
        trickLabel.Font = New Font("Arial", 12)
        trickLabel.Size = New Size(100, 25)
        trickLabel.Location = New Point(Me.ClientSize.Width \ 2 - 50, 100)
        Me.Controls.Add(trickLabel)

        ' Create start button
        startButton = New Button()
        startButton.Text = "Start Game"
        startButton.Font = New Font("Arial", 12)
        startButton.Size = New Size(120, 40)
        startButton.Location = New Point(Me.ClientSize.Width \ 2 - 130, Me.ClientSize.Height - 100)
        AddHandler startButton.Click, AddressOf StartGame
        Me.Controls.Add(startButton)

        ' Create reset button
        resetButton = New Button()
        resetButton.Text = "Reset Game"
        resetButton.Font = New Font("Arial", 12)
        resetButton.Size = New Size(120, 40)
        resetButton.Location = New Point(Me.ClientSize.Width \ 2 + 10, Me.ClientSize.Height - 100)
        AddHandler resetButton.Click, AddressOf ResetGame
        Me.Controls.Add(resetButton)

        ' Create game log
        gameLog = New TextBox()
        gameLog.Multiline = True
        gameLog.ScrollBars = ScrollBars.Vertical
        gameLog.Font = New Font("Consolas", 10)
        gameLog.Size = New Size(300, 200)
        gameLog.Location = New Point(Me.ClientSize.Width - 320, 150)
        gameLog.ReadOnly = True
        Me.Controls.Add(gameLog)

        ' Create table cards area (center of screen)
        For i As Integer = 0 To 3
            Dim cardPic As New PictureBox()
            cardPic.Size = New Size(80, 120)
            cardPic.BackColor = Color.LightGray
            cardPic.BorderStyle = BorderStyle.FixedSingle
            cardPic.Visible = False

            ' Position cards around center
            Select Case i
                Case 0 ' Top position
                    cardPic.Location = New Point(Me.ClientSize.Width \ 2 - 40, Me.ClientSize.Height \ 2 - 200)
                Case 1 ' Right position
                    cardPic.Location = New Point(Me.ClientSize.Width \ 2 + 100, Me.ClientSize.Height \ 2 - 60)
                Case 2 ' Bottom position
                    cardPic.Location = New Point(Me.ClientSize.Width \ 2 - 40, Me.ClientSize.Height \ 2 + 80)
                Case 3 ' Left position
                    cardPic.Location = New Point(Me.ClientSize.Width \ 2 - 180, Me.ClientSize.Height \ 2 - 60)
            End Select

            tableCards.Add(cardPic)
            Me.Controls.Add(cardPic)
        Next

        ' Create player cards (for bottom player)
        For i As Integer = 0 To 12
            Dim cardButton As New Button()
            cardButton.Text = "Card " & (i + 1)
            cardButton.Font = New Font("Arial", 8)
            cardButton.Size = New Size(60, 90)
            cardButton.Location = New Point(200 + i * 65, Me.ClientSize.Height - 150)
            cardButton.Visible = False
            cardButton.Tag = i
            AddHandler cardButton.Click, AddressOf CardClicked
            playerCards.Add(cardButton)
            Me.Controls.Add(cardButton)
        Next
    End Sub

    Private Sub StartGame(sender As Object, e As EventArgs)
        If gameStarted Then
            LogMessage("Game already in progress!")
            Return
        End If

        gameStarted = True
        trickCount = 0
        currentPlayer = 0

        ' Reset scores
        For i As Integer = 0 To 3
            scores(i) = 0
            scoreLabels(i).Text = playerNames(i) & ": 0 points"
            scoreLabels(i).ForeColor = Color.DarkBlue
        Next

        ' Shuffle and deal cards
        ShuffleDeck()
        DealCards()

        ' Update UI
        playerTurnLabel.Text = playerNames(currentPlayer) & "'s turn"
        playerTurnLabel.ForeColor = Color.Green
        trickLabel.Text = "Tricks: " & trickCount

        ' Show player cards
        For Each card As Button In playerCards
            card.Visible = True
        Next

        If currentPlayer <> 2 Then

            Dim timer As New Timer()

            timer.Interval = 1000

            AddHandler timer.Tick,
        Sub(s, ev)

            timer.Stop()
            timer.Dispose()

            AIPlay()

        End Sub

            timer.Start()

        End If

        LogMessage("Game started! " & playerNames(currentPlayer) & " goes first.")
    End Sub

    Private Sub DealCards()

        aiHands.Clear()

        aiHands.Add(0, New List(Of String)) ' Player 1
        aiHands.Add(1, New List(Of String)) ' Player 2
        aiHands.Add(3, New List(Of String)) ' Player 4

        Dim deckIndex As Integer = 0

        For cardIndex As Integer = 0 To 12

            ' Player 1
            aiHands(0).Add(deck(deckIndex))
            deckIndex += 1

            ' Player 2
            aiHands(1).Add(deck(deckIndex))
            deckIndex += 1

            ' Human player (Player 3)
            playerCards(cardIndex).Text = GetCardDisplay(deck(deckIndex))
            playerCards(cardIndex).Tag = deck(deckIndex)
            deckIndex += 1

            ' Player 4
            aiHands(3).Add(deck(deckIndex))
            deckIndex += 1

        Next

    End Sub

    Private Function GetCardDisplay(cardCode As String) As String
        If cardCode.Length < 2 Then Return "??"

        Dim value As String = cardCode.Substring(0, cardCode.Length - 1)
        Dim suit As String = cardCode.Substring(cardCode.Length - 1)

        Dim suitSymbol As String = ""
        Select Case suit
            Case "H" : suitSymbol = "♥"
            Case "D" : suitSymbol = "♦"
            Case "C" : suitSymbol = "♣"
            Case "S" : suitSymbol = "♠"
        End Select

        Return value & vbCrLf & suitSymbol
    End Function

    Private Sub CardClicked(sender As Object, e As EventArgs)
        If Not gameStarted Then Return

        Dim clickedCard As Button = DirectCast(sender, Button)

        ' Check if it's current player's turn (bottom player is always player 2 in this demo)
        If currentPlayer <> 2 Then
            LogMessage("Not your turn! It's " & playerNames(currentPlayer) & "'s turn.")
            Return
        End If

        ' Play the card
        PlayCard(clickedCard)
    End Sub

    Private Sub PlayCard(cardButton As Button)
        Dim cardCode As String = cardButton.Tag.ToString()

        ' Add card to table
        tableCards(currentPlayer).BackColor = Color.White
        tableCards(currentPlayer).Image = CreateCardImage(cardCode)
        tableCards(currentPlayer).Visible = True

        ' Remove card from player's hand
        cardButton.Visible = False

        ' Calculate points for the card
        Dim points As Integer = CalculatePoints(cardCode)
        scores(currentPlayer) += points

        ' Update score display
        scoreLabels(currentPlayer).Text = playerNames(currentPlayer) & ": " & scores(currentPlayer) & " points"

        ' Check if player exceeded 99
        If scores(currentPlayer) > 99 Then
            scoreLabels(currentPlayer).ForeColor = Color.Red
            LogMessage(playerNames(currentPlayer) & " exceeded 99 points!")
        End If

        LogMessage(playerNames(currentPlayer) & " played " & cardCode & " worth " & points & " points")

        ' Move to next player
        currentPlayer = (currentPlayer + 1) Mod 4

        ' If all players have played, complete the trick
        If currentPlayer = 0 Then
            CompleteTrick()
            trickCount += 1
            trickLabel.Text = "Tricks: " & trickCount

            ' Check game end condition
            If trickCount >= 13 Then
                EndGame()
                Return
            End If
        End If

        playerTurnLabel.Text = playerNames(currentPlayer) & "'s turn"

        ' For demo purposes, simulate AI players
        If currentPlayer <> 2 And gameStarted Then
            ' Schedule AI move after a short delay
            Dim timer As New Timer()
            timer.Interval = 1000
            AddHandler timer.Tick, Sub(s, ev)
                                       AIPlay()
                                       timer.Stop()
                                       timer.Dispose()
                                   End Sub
            timer.Start()
        End If
    End Sub

    Private Sub AIPlay()

        If Not aiHands.ContainsKey(currentPlayer) Then Return

        Dim hand As List(Of String) = aiHands(currentPlayer)

        If hand.Count = 0 Then Return

        Dim aiCard As String = ChooseBestCard(hand, scores(currentPlayer))

        hand.Remove(aiCard)

        Dim points As Integer = CalculatePoints(aiCard)

        scores(currentPlayer) += points

        scoreLabels(currentPlayer).Text =
        playerNames(currentPlayer) &
        ": " &
        scores(currentPlayer) &
        " points"

        tableCards(currentPlayer).BackColor = Color.White
        tableCards(currentPlayer).Image = CreateCardImage(aiCard)
        tableCards(currentPlayer).Visible = True

        If scores(currentPlayer) > 99 Then
            scoreLabels(currentPlayer).ForeColor = Color.Red
        End If

        LogMessage(playerNames(currentPlayer) &
               " played " &
               aiCard &
               " worth " &
               points &
               " points")

        currentPlayer = (currentPlayer + 1) Mod 4

        If currentPlayer = 0 Then

            CompleteTrick()

            trickCount += 1
            trickLabel.Text = "Tricks: " & trickCount

            If trickCount >= 13 Then
                EndGame()
                Return
            End If

        End If

        playerTurnLabel.Text =
        playerNames(currentPlayer) & "'s turn"

        If currentPlayer <> 2 Then

            Dim timer As New Timer()

            timer.Interval = 1000

            AddHandler timer.Tick,
            Sub(s, ev)

                timer.Stop()
                timer.Dispose()

                AIPlay()

            End Sub

            timer.Start()

        End If

    End Sub

    Private Function CalculatePoints(cardCode As String) As Integer
        If String.IsNullOrEmpty(cardCode) Or cardCode.Length < 2 Then Return 0

        Dim value As String = cardCode.Substring(0, cardCode.Length - 1)

        Select Case value
            Case "A" : Return 11
            Case "K" : Return 4
            Case "Q" : Return 3
            Case "J" : Return 2
            Case "10" : Return 10
            Case "9" : Return 9
            Case "8" : Return 8
            Case "7" : Return 7
            Case "6" : Return 6
            Case "5" : Return 5
            Case "4" : Return 4
            Case "3" : Return 3
            Case "2" : Return 2
            Case Else : Return 0
        End Select
    End Function

    Private Sub CompleteTrick()
        ' Determine winner of the trick (simplified - highest card wins)
        LogMessage("Trick completed!")

        ' Clear table cards after a delay
        Dim timer As New Timer()
        timer.Interval = 2000
        AddHandler timer.Tick, Sub(s, ev)
                                   For Each cardPic As PictureBox In tableCards
                                       cardPic.Visible = False
                                       cardPic.Image = Nothing
                                   Next
                                   timer.Stop()
                                   timer.Dispose()
                               End Sub
        timer.Start()
    End Sub

    Private Sub EndGame()
        gameStarted = False
        playerTurnLabel.Text = "Game Over!"

        ' Determine winner (lowest score wins)
        Dim minScore As Integer = Integer.MaxValue
        Dim winnerIndex As Integer = -1

        For i As Integer = 0 To 3
            If scores(i) <= 99 And scores(i) < minScore Then
                minScore = scores(i)
                winnerIndex = i
            End If
        Next

        If winnerIndex >= 0 Then
            LogMessage("Game Over! " & playerNames(winnerIndex) & " wins with " & minScore & " points!")
        Else
            LogMessage("Game Over! All players exceeded 99 points!")
        End If
    End Sub

    Private Sub ResetGame(sender As Object, e As EventArgs)
        gameStarted = False

        ' Hide all cards
        For Each card As Button In playerCards
            card.Visible = False
        Next

        For Each cardPic As PictureBox In tableCards
            cardPic.Visible = False
            cardPic.Image = Nothing
        Next

        ' Reset UI
        playerTurnLabel.Text = "Game not started"
        trickLabel.Text = "Tricks: 0"

        ' Reinitialize game
        InitializeGame()

        LogMessage("Game reset. Click 'Start Game' to begin.")
    End Sub

    Private Function CreateCardImage(cardCode As String) As Image
        ' Create a simple card image
        Dim bmp As New Bitmap(80, 120)
        Using g As Graphics = Graphics.FromImage(bmp)
            g.Clear(Color.White)

            ' Draw border
            g.DrawRectangle(Pens.Black, 0, 0, 79, 119)

            ' Draw card value and suit
            If cardCode.Length >= 2 Then
                Dim value As String = cardCode.Substring(0, cardCode.Length - 1)
                Dim suit As String = cardCode.Substring(cardCode.Length - 1)

                Dim suitColor As Color = If(suit = "H" Or suit = "D", Color.Red, Color.Black)
                Dim suitSymbol As String = ""

                Select Case suit
                    Case "H" : suitSymbol = "♥"
                    Case "D" : suitSymbol = "♦"
                    Case "C" : suitSymbol = "♣"
                    Case "S" : suitSymbol = "♠"
                End Select

                Using font As New Font("Arial", 12, FontStyle.Bold)
                    Using brush As New SolidBrush(suitColor)
                        g.DrawString(value & suitSymbol, font, brush, 5, 5)
                    End Using
                End Using
            End If
        End Using

        Return bmp
    End Function

    Private Sub LogMessage(message As String)
        gameLog.AppendText(DateTime.Now.ToString("HH:mm:ss") & " - " & message & vbCrLf)
        gameLog.SelectionStart = gameLog.Text.Length
        gameLog.ScrollToCaret()
    End Sub

    Private Function ChooseBestCard(hand As List(Of String), currentScore As Integer) As String

        If hand.Count = 0 Then Return Nothing

        Dim bestCard As String = hand(0)
        Dim bestValue As Integer = Integer.MaxValue

        For Each card As String In hand

            Dim points As Integer = CalculatePoints(card)

            If currentScore + points <= 99 Then

                If points < bestValue Then
                    bestValue = points
                    bestCard = card
                End If

            End If

        Next

        Return bestCard

    End Function

    ' Entry point
    Public Shared Sub Main()
        Application.EnableVisualStyles()
        Application.SetCompatibleTextRenderingDefault(False)
        Application.Run(New Form1())
    End Sub

End Class
