Imports System.Drawing
Imports System.Windows.Forms

Public Class Form1
    Inherits Form

    Private WithEvents startButton As Button
    Private WithEvents dealButton As Button
    Private WithEvents playButton As Button
    Private WithEvents scoreButton As Button
    Private WithEvents resetButton As Button

    Private cardPanel As Panel
    Private playerPanel As Panel
    Private scoreLabel As Label
    Private statusLabel As Label
    Private currentPlayerLabel As Label

    Private deck As New List(Of Card)
    Private players As New List(Of Player)
    Private currentPlayerIndex As Integer = 0
    Private selectedCards As New List(Of Card)
    Private gameStarted As Boolean = False
    Private gamePhase2 As GamePhase = GamePhase.NotStarted

    Private Enum GamePhase
        NotStarted
        Dealing
        Playing
        Scoring
    End Enum

    Private Class Card
        Public Property Suit As String
        Public Property Rank As String
        Public Property Value As Integer
        Public Property IsJoker As Boolean
        Public Property Button As Button
        Public Property IsSelected As Boolean

        Public Overrides Function ToString() As String
            If IsJoker Then Return "Joker"
            Return $"{Rank} of {Suit}"
        End Function

        Public Function GetImageName() As String
            If IsJoker Then Return "Joker"
            Return $"{Suit.Substring(0, 1)}{Rank}"
        End Function
    End Class

    Private Class Player
        Public Property Name As String
        Public Property Hand As New List(Of Card)
        Public Property Score As Integer
        Public Property Panel As Panel
    End Class

    Public Sub New()
        InitializeForm()
        CreateControls()
        InitializeDeck()
    End Sub

    Private Sub InitializeForm()
        Me.Text = "Jokeren - Dutch Card Game"
        Me.Size = New Size(1200, 800)
        Me.StartPosition = FormStartPosition.CenterScreen
        Me.BackColor = Color.DarkGreen
    End Sub

    Private Sub CreateControls()
        ' Create control panel at top
        Dim controlPanel As New Panel With {
            .Size = New Size(1180, 50),
            .Location = New Point(10, 10),
            .BackColor = Color.ForestGreen,
            .BorderStyle = BorderStyle.FixedSingle
        }

        ' Create buttons
        startButton = CreateButton("Start Game", 10, 10, 100)
        dealButton = CreateButton("Deal Cards", 120, 10, 100)
        playButton = CreateButton("Play Cards", 230, 10, 100)
        scoreButton = CreateButton("Score Round", 340, 10, 100)
        resetButton = CreateButton("Reset Game", 450, 10, 100)

        dealButton.Enabled = False
        playButton.Enabled = False
        scoreButton.Enabled = False

        ' Add buttons to control panel
        controlPanel.Controls.AddRange({startButton, dealButton, playButton, scoreButton, resetButton})

        ' Create score label
        scoreLabel = New Label With {
            .Text = "Scores: ",
            .Location = New Point(560, 15),
            .Size = New Size(300, 25),
            .ForeColor = Color.White,
            .Font = New Font("Arial", 10, FontStyle.Bold)
        }
        controlPanel.Controls.Add(scoreLabel)

        ' Create status label
        statusLabel = New Label With {
            .Text = "Game not started",
            .Location = New Point(10, 70),
            .Size = New Size(1180, 25),
            .ForeColor = Color.White,
            .Font = New Font("Arial", 12, FontStyle.Bold),
            .TextAlign = ContentAlignment.MiddleCenter
        }

        ' Create current player label
        currentPlayerLabel = New Label With {
            .Text = "Current player: None",
            .Location = New Point(10, 100),
            .Size = New Size(1180, 25),
            .ForeColor = Color.Yellow,
            .Font = New Font("Arial", 11, FontStyle.Bold),
            .TextAlign = ContentAlignment.MiddleCenter
        }

        ' Create main card panel
        cardPanel = New Panel With {
            .Size = New Size(1180, 300),
            .Location = New Point(10, 130),
            .BackColor = Color.ForestGreen,
            .BorderStyle = BorderStyle.FixedSingle,
            .AutoScroll = True
        }

        ' Create player panel
        playerPanel = New Panel With {
            .Size = New Size(1180, 300),
            .Location = New Point(10, 440),
            .BackColor = Color.DarkOliveGreen,
            .BorderStyle = BorderStyle.FixedSingle
        }

        ' Add all controls to form
        Me.Controls.AddRange({controlPanel, statusLabel, currentPlayerLabel, cardPanel, playerPanel})
    End Sub

    Private Function CreateButton(text As String, x As Integer, y As Integer, width As Integer) As Button
        Return New Button With {
            .Text = text,
            .Location = New Point(x, y),
            .Size = New Size(width, 30),
            .BackColor = Color.Gold,
            .ForeColor = Color.Black,
            .Font = New Font("Arial", 9, FontStyle.Bold)
        }
    End Function

    Private Sub InitializeDeck()
        deck.Clear()

        ' Standard suits and ranks for Jokeren
        Dim suits() As String = {"Hearts", "Diamonds", "Clubs", "Spades"}
        Dim ranks() As String = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"}

        ' Add standard cards
        For Each suit In suits
            For i As Integer = 0 To ranks.Length - 1
                Dim card As New Card With {
                    .Suit = suit,
                    .Rank = ranks(i),
                    .Value = i + 2, ' 2 = 2, Ace = 14
                    .IsJoker = False
                }
                deck.Add(card)
            Next
        Next

        ' Add Jokers (typically 2 in Jokeren)
        For i As Integer = 1 To 2
            deck.Add(New Card With {
                .Suit = "Joker",
                .Rank = "Joker",
                .Value = 15, ' Joker is highest
                .IsJoker = True
            })
        Next

        ' Shuffle deck
        ShuffleDeck()
    End Sub

    Private Sub ShuffleDeck()
        Dim rng As New Random()
        Dim n As Integer = deck.Count
        While n > 1
            n -= 1
            Dim k As Integer = rng.Next(n + 1)
            Dim value As Card = deck(k)
            deck(k) = deck(n)
            deck(n) = value
        End While
    End Sub

    Private Sub StartButton_Click(sender As Object, e As EventArgs) Handles startButton.Click
        If Not gameStarted Then
            InitializePlayers()
            gameStarted = True
            gamePhase2 = GamePhase.Dealing

            startButton.Enabled = False
            dealButton.Enabled = True
            statusLabel.Text = "Game started! Click 'Deal Cards' to begin."
            UpdateScoreDisplay()
            UpdateCurrentPlayerDisplay()
        End If
    End Sub

    Private Sub InitializePlayers()
        players.Clear()

        ' Create 4 players (standard for Jokeren)
        For i As Integer = 1 To 4
            Dim player As New Player With {
                .Name = $"Player {i}",
                .Score = 0
            }
            players.Add(player)
        Next

        ' Create player panels
        CreatePlayerPanels()
    End Sub

    Private Sub CreatePlayerPanels()
        playerPanel.Controls.Clear()
        Dim panelWidth As Integer = playerPanel.Width \ players.Count - 20

        For i As Integer = 0 To players.Count - 1
            Dim playerPanelItem As New Panel With {
                .Size = New Size(panelWidth, 280),
                .Location = New Point(10 + i * (panelWidth + 10), 10),
                .BackColor = Color.SeaGreen,
                .BorderStyle = BorderStyle.FixedSingle
            }

            Dim nameLabel As New Label With {
                .Text = players(i).Name,
                .Location = New Point(10, 10),
                .Size = New Size(panelWidth - 20, 25),
                .ForeColor = Color.White,
                .Font = New Font("Arial", 10, FontStyle.Bold),
                .TextAlign = ContentAlignment.MiddleCenter
            }

            Dim scoreLabel As New Label With {
                .Text = $"Score: {players(i).Score}",
                .Location = New Point(10, 40),
                .Size = New Size(panelWidth - 20, 25),
                .ForeColor = Color.Yellow,
                .Font = New Font("Arial", 9),
                .TextAlign = ContentAlignment.MiddleCenter
            }

            Dim handLabel As New Label With {
                .Text = $"Cards: 0",
                .Location = New Point(10, 70),
                .Size = New Size(panelWidth - 20, 25),
                .ForeColor = Color.White,
                .Font = New Font("Arial", 9),
                .TextAlign = ContentAlignment.MiddleCenter
            }

            playerPanelItem.Controls.AddRange({nameLabel, scoreLabel, handLabel})
            players(i).Panel = playerPanelItem
            playerPanel.Controls.Add(playerPanelItem)
        Next
    End Sub

    Private Sub DealButton_Click(sender As Object, e As EventArgs) Handles dealButton.Click
        If gamePhase2 = GamePhase.Dealing Then
            ' Clear previous hands
            For Each player In players
                player.Hand.Clear()
            Next

            ' Deal 13 cards to each player
            Dim cardIndex As Integer = 0
            For i As Integer = 0 To 12
                For Each player In players
                    If cardIndex < deck.Count Then
                        player.Hand.Add(deck(cardIndex))
                        cardIndex += 1
                    End If
                Next
            Next

            ' Sort each player's hand
            For Each player In players
                player.Hand = player.Hand.OrderBy(Function(c) c.Value).ThenBy(Function(c) c.Suit).ToList()
            Next

            gamePhase2 = GamePhase.Playing
            currentPlayerIndex = 0
            selectedCards.Clear()

            dealButton.Enabled = False
            playButton.Enabled = True

            UpdatePlayerDisplays()
            DisplayCurrentPlayerHand()
            statusLabel.Text = $"Cards dealt! {players(currentPlayerIndex).Name}'s turn."
            UpdateCurrentPlayerDisplay()
        End If
    End Sub

    Private Sub DisplayCurrentPlayerHand()
        cardPanel.Controls.Clear()

        Dim player As Player = players(currentPlayerIndex)
        Dim cardWidth As Integer = 80
        Dim cardHeight As Integer = 120
        Dim spacing As Integer = 10

        For i As Integer = 0 To player.Hand.Count - 1
            Dim card As Card = player.Hand(i)

            Dim cardButton As New Button With {
                .Text = GetCardDisplayText(card),
                .Tag = card,
                .Size = New Size(cardWidth, cardHeight),
                .Location = New Point(spacing + i * (cardWidth + spacing), 10),
                .BackColor = If(card.IsSelected, Color.LightBlue, Color.White),
                .ForeColor = If(card.Suit = "Hearts" OrElse card.Suit = "Diamonds", Color.Red, Color.Black),
                .Font = New Font("Arial", 8),
                .FlatStyle = FlatStyle.Flat
            }

            AddHandler cardButton.Click, AddressOf CardButton_Click
            card.Button = cardButton
            cardPanel.Controls.Add(cardButton)
        Next
    End Sub

    Private Function GetCardDisplayText(card As Card) As String
        If card.IsJoker Then
            Return "JOKER"
        End If

        Dim rankSymbol As String = card.Rank
        If rankSymbol = "Jack" Then rankSymbol = "J"
        If rankSymbol = "Queen" Then rankSymbol = "Q"
        If rankSymbol = "King" Then rankSymbol = "K"
        If rankSymbol = "Ace" Then rankSymbol = "A"

        Dim suitSymbol As String = ""
        Select Case card.Suit
            Case "Hearts" : suitSymbol = "♥"
            Case "Diamonds" : suitSymbol = "♦"
            Case "Clubs" : suitSymbol = "♣"
            Case "Spades" : suitSymbol = "♠"
        End Select

        Return $"{rankSymbol}{vbCrLf}{suitSymbol}"
    End Function

    Private Sub CardButton_Click(sender As Object, e As EventArgs)
        Dim button As Button = DirectCast(sender, Button)
        Dim card As Card = DirectCast(button.Tag, Card)

        card.IsSelected = Not card.IsSelected

        If card.IsSelected Then
            selectedCards.Add(card)
            button.BackColor = Color.LightBlue
        Else
            selectedCards.Remove(card)
            button.BackColor = Color.White
        End If

        statusLabel.Text = $"Selected {selectedCards.Count} card(s)"
    End Sub

    Private Sub PlayButton_Click(sender As Object, e As EventArgs) Handles playButton.Click
        If selectedCards.Count > 0 Then
            ' Remove selected cards from current player's hand
            Dim player As Player = players(currentPlayerIndex)
            player.Hand = player.Hand.Where(Function(c) Not c.IsSelected).ToList()

            ' Clear selection
            For Each card In selectedCards
                card.IsSelected = False
            Next
            selectedCards.Clear()

            ' Move to next player
            currentPlayerIndex = (currentPlayerIndex + 1) Mod players.Count

            ' Check if round is over
            If players.All(Function(p) p.Hand.Count = 0) Then
                gamePhase2 = GamePhase.Scoring
                playButton.Enabled = False
                scoreButton.Enabled = True
                statusLabel.Text = "Round complete! Click 'Score Round' to calculate scores."
            Else
                DisplayCurrentPlayerHand()
                statusLabel.Text = $"{players(currentPlayerIndex).Name}'s turn. Select cards to play."
            End If

            UpdatePlayerDisplays()
            UpdateCurrentPlayerDisplay()
        Else
            MessageBox.Show("Please select at least one card to play.", "No Cards Selected", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        End If
    End Sub

    Private Sub ScoreButton_Click(sender As Object, e As EventArgs) Handles scoreButton.Click
        ' Simple scoring system for Jokeren
        ' In actual Jokeren, scoring is more complex based on card combinations

        For Each player In players
            ' Calculate score based on remaining cards (negative points)
            Dim roundScore As Integer = 0
            For Each card In player.Hand
                ' Negative points for cards left in hand
                roundScore -= card.Value
            Next

            player.Score += roundScore
            player.Hand.Clear()
        Next

        ' Prepare for next round
        InitializeDeck()
        gamePhase2 = GamePhase.Dealing

        scoreButton.Enabled = False
        dealButton.Enabled = True

        UpdateScoreDisplay()
        UpdatePlayerDisplays()
        statusLabel.Text = "Scores updated! Click 'Deal Cards' for next round."
    End Sub

    Private Sub ResetButton_Click(sender As Object, e As EventArgs) Handles resetButton.Click
        ' Reset game
        gameStarted = False
        gamePhase2 = GamePhase.NotStarted
        currentPlayerIndex = 0
        selectedCards.Clear()

        startButton.Enabled = True
        dealButton.Enabled = False
        playButton.Enabled = False
        scoreButton.Enabled = False

        InitializeDeck()
        InitializePlayers()

        cardPanel.Controls.Clear()
        statusLabel.Text = "Game reset. Click 'Start Game' to begin."
        UpdateScoreDisplay()
        UpdateCurrentPlayerDisplay()
    End Sub

    Private Sub UpdatePlayerDisplays()
        For i As Integer = 0 To players.Count - 1
            Dim player As Player = players(i)
            If player.Panel IsNot Nothing AndAlso player.Panel.Controls.Count >= 3 Then
                ' Update score label
                Dim scoreCtrl As Label = DirectCast(player.Panel.Controls(1), Label)
                scoreCtrl.Text = $"Score: {player.Score}"

                ' Update hand count label
                Dim handCtrl As Label = DirectCast(player.Panel.Controls(2), Label)
                handCtrl.Text = $"Cards: {player.Hand.Count}"

                ' Highlight current player
                player.Panel.BackColor = If(i = currentPlayerIndex, Color.Goldenrod, Color.SeaGreen)
            End If
        Next
    End Sub

    Private Sub UpdateScoreDisplay()
        Dim scoreText As String = "Scores: "
        For Each player In players
            scoreText &= $"{player.Name}: {player.Score} | "
        Next
        scoreLabel.Text = scoreText.TrimEnd(" | ".ToCharArray())
    End Sub

    Private Sub UpdateCurrentPlayerDisplay()
        If gameStarted Then
            currentPlayerLabel.Text = $"Current player: {players(currentPlayerIndex).Name}"
        Else
            currentPlayerLabel.Text = "Current player: None"
        End If
    End Sub

    ' Form closing event
    Private Sub JokerenGame_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        If MessageBox.Show("Are you sure you want to quit?", "Quit Game",
                          MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.No Then
            e.Cancel = True
        End If
    End Sub
End Class

' Main entry point
Module Program
    Sub Main()
        Application.EnableVisualStyles()
        Application.SetCompatibleTextRenderingDefault(False)
        Application.Run(New Form1())
    End Sub
End Module
