Imports System.Drawing
Imports System.Collections.Generic

Public Class Form1
    Inherits Form

    Private deck As New List(Of Card)()
    Private playerCards As New List(Of Card)()
    Private dealerCards As New List(Of Card)()
    Private currentPlayerScore As Integer = 0
    Private currentDealerScore As Integer = 0
    Private gameOver As Boolean = False

    ' Runtime controls
    Private WithEvents btnHit As Button
    Private WithEvents btnStand As Button
    Private WithEvents btnNewGame As Button
    Private lblPlayerScore As Label
    Private lblDealerScore As Label
    Private lblGameStatus As Label
    Private pnlPlayerCards As Panel
    Private pnlDealerCards As Panel

    Public Sub New()
        InitializeForm()
        InitializeControls()
        StartNewGame()
    End Sub

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

    Private Sub InitializeControls()
        ' Title label
        Dim lblTitle As New Label()
        lblTitle.Text = "TWENTY-ONE CARD GAME"
        lblTitle.Font = New Font("Arial", 20, FontStyle.Bold)
        lblTitle.ForeColor = Color.Gold
        lblTitle.Size = New Size(400, 40)
        lblTitle.Location = New Point(200, 10)
        lblTitle.TextAlign = ContentAlignment.MiddleCenter
        Me.Controls.Add(lblTitle)

        ' Dealer section
        Dim lblDealer As New Label()
        lblDealer.Text = "DEALER"
        lblDealer.Font = New Font("Arial", 14, FontStyle.Bold)
        lblDealer.ForeColor = Color.White
        lblDealer.Size = New Size(100, 30)
        lblDealer.Location = New Point(50, 60)
        Me.Controls.Add(lblDealer)

        pnlDealerCards = New Panel()
        pnlDealerCards.Size = New Size(700, 120)
        pnlDealerCards.Location = New Point(50, 90)
        pnlDealerCards.BackColor = Color.Transparent
        Me.Controls.Add(pnlDealerCards)

        lblDealerScore = New Label()
        lblDealerScore.Text = "Score: 0"
        lblDealerScore.Font = New Font("Arial", 12, FontStyle.Bold)
        lblDealerScore.ForeColor = Color.White
        lblDealerScore.Size = New Size(100, 25)
        lblDealerScore.Location = New Point(650, 60)
        Me.Controls.Add(lblDealerScore)

        ' Player section
        Dim lblPlayer As New Label()
        lblPlayer.Text = "PLAYER"
        lblPlayer.Font = New Font("Arial", 14, FontStyle.Bold)
        lblPlayer.ForeColor = Color.White
        lblPlayer.Size = New Size(100, 30)
        lblPlayer.Location = New Point(50, 250)
        Me.Controls.Add(lblPlayer)

        pnlPlayerCards = New Panel()
        pnlPlayerCards.Size = New Size(700, 120)
        pnlPlayerCards.Location = New Point(50, 280)
        pnlPlayerCards.BackColor = Color.Transparent
        Me.Controls.Add(pnlPlayerCards)

        lblPlayerScore = New Label()
        lblPlayerScore.Text = "Score: 0"
        lblPlayerScore.Font = New Font("Arial", 12, FontStyle.Bold)
        lblPlayerScore.ForeColor = Color.White
        lblPlayerScore.Size = New Size(100, 25)
        lblPlayerScore.Location = New Point(650, 250)
        Me.Controls.Add(lblPlayerScore)

        ' Game status
        lblGameStatus = New Label()
        lblGameStatus.Text = "Game in progress..."
        lblGameStatus.Font = New Font("Arial", 14, FontStyle.Bold)
        lblGameStatus.ForeColor = Color.Yellow
        lblGameStatus.Size = New Size(400, 30)
        lblGameStatus.Location = New Point(200, 420)
        lblGameStatus.TextAlign = ContentAlignment.MiddleCenter
        Me.Controls.Add(lblGameStatus)

        ' Control buttons
        btnHit = New Button()
        btnHit.Text = "HIT"
        btnHit.Font = New Font("Arial", 12, FontStyle.Bold)
        btnHit.Size = New Size(100, 40)
        btnHit.Location = New Point(200, 470)
        btnHit.BackColor = Color.LightBlue
        Me.Controls.Add(btnHit)

        btnStand = New Button()
        btnStand.Text = "STAND"
        btnStand.Font = New Font("Arial", 12, FontStyle.Bold)
        btnStand.Size = New Size(100, 40)
        btnStand.Location = New Point(350, 470)
        btnStand.BackColor = Color.LightCoral
        Me.Controls.Add(btnStand)

        btnNewGame = New Button()
        btnNewGame.Text = "NEW GAME"
        btnNewGame.Font = New Font("Arial", 12, FontStyle.Bold)
        btnNewGame.Size = New Size(150, 40)
        btnNewGame.Location = New Point(500, 470)
        btnNewGame.BackColor = Color.LightGreen
        Me.Controls.Add(btnNewGame)
    End Sub

    Private Sub StartNewGame()
        ' Clear previous game
        deck.Clear()
        playerCards.Clear()
        dealerCards.Clear()
        pnlPlayerCards.Controls.Clear()
        pnlDealerCards.Controls.Clear()
        currentPlayerScore = 0
        currentDealerScore = 0
        gameOver = False

        ' Create and shuffle deck
        CreateDeck()
        ShuffleDeck()

        ' Deal initial cards
        DealCardToPlayer()
        DealCardToPlayer()
        DealCardToDealer()
        DealCardToDealer()

        ' Update UI
        UpdateScores()
        UpdateGameStatus("Your turn. Hit or Stand?")
        UpdateButtonStates(True)
    End Sub

    Private Sub CreateDeck()
        Dim suits() As String = {"♥", "♦", "♣", "♠"}
        Dim values() As String = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"}

        For Each suit In suits
            For Each value In values
                deck.Add(New Card(suit, value))
            Next
        Next
    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 Card = deck(i)
            deck(i) = deck(j)
            deck(j) = temp
        Next
    End Sub

    Private Sub DealCardToPlayer()
        If deck.Count = 0 Then Return

        Dim card As Card = deck(0)
        deck.RemoveAt(0)
        playerCards.Add(card)

        DisplayCard(card, pnlPlayerCards, playerCards.Count)
        UpdatePlayerScore()
    End Sub

    Private Sub DealCardToDealer()
        If deck.Count = 0 Then Return

        Dim card As Card = deck(0)
        deck.RemoveAt(0)
        dealerCards.Add(card)

        DisplayCard(card, pnlDealerCards, dealerCards.Count)
        UpdateDealerScore()
    End Sub

    Private Sub DisplayCard(card As Card, panel As Panel, cardIndex As Integer)
        Dim cardLabel As New Label()
        cardLabel.Text = card.GetDisplayText()
        cardLabel.Font = New Font("Arial", 14, FontStyle.Bold)
        cardLabel.Size = New Size(60, 90)
        cardLabel.Location = New Point((cardIndex - 1) * 65, 0)
        cardLabel.TextAlign = ContentAlignment.MiddleCenter
        cardLabel.BackColor = Color.White
        cardLabel.BorderStyle = BorderStyle.FixedSingle

        ' Color red cards for hearts and diamonds
        If card.Suit = "♥" OrElse card.Suit = "♦" Then
            cardLabel.ForeColor = Color.Red
        Else
            cardLabel.ForeColor = Color.Black
        End If

        panel.Controls.Add(cardLabel)
    End Sub

    Private Sub UpdatePlayerScore()
        currentPlayerScore = CalculateScore(playerCards)
        lblPlayerScore.Text = $"Score: {currentPlayerScore}"
    End Sub

    Private Sub UpdateDealerScore()
        currentDealerScore = CalculateScore(dealerCards)
        lblDealerScore.Text = $"Score: {currentDealerScore}"
    End Sub

    Private Sub UpdateScores()
        UpdatePlayerScore()
        UpdateDealerScore()
    End Sub

    Private Function CalculateScore(cards As List(Of Card)) As Integer
        Dim score As Integer = 0
        Dim aceCount As Integer = 0

        For Each card In cards
            Select Case card.Value
                Case "A"
                    score += 11
                    aceCount += 1
                Case "K", "Q", "J"
                    score += 10
                Case Else
                    score += Integer.Parse(card.Value)
            End Select
        Next

        ' Handle aces (11 or 1)
        While score > 21 AndAlso aceCount > 0
            score -= 10
            aceCount -= 1
        End While

        Return score
    End Function

    Private Sub UpdateGameStatus(message As String)
        lblGameStatus.Text = message
    End Sub

    Private Sub UpdateButtonStates(enabled As Boolean)
        btnHit.Enabled = enabled AndAlso Not gameOver
        btnStand.Enabled = enabled AndAlso Not gameOver
    End Sub

    Private Sub DealerPlay()
        UpdateButtonStates(False)

        ' Dealer must hit until score >= 17
        While currentDealerScore < 17
            DealCardToDealer()
            Application.DoEvents()
            Threading.Thread.Sleep(500) ' Pause for effect
        End While

        DetermineWinner()
    End Sub

    Private Sub DetermineWinner()
        gameOver = True

        If currentPlayerScore > 21 Then
            UpdateGameStatus("BUST! You went over 21. Dealer wins!")
        ElseIf currentDealerScore > 21 Then
            UpdateGameStatus("Dealer busts! You win!")
        ElseIf currentPlayerScore > currentDealerScore Then
            UpdateGameStatus("You win! Your score is higher.")
        ElseIf currentDealerScore > currentPlayerScore Then
            UpdateGameStatus("Dealer wins! Dealer score is higher.")
        Else
            UpdateGameStatus("Push! It's a tie.")
        End If

        UpdateButtonStates(False)
    End Sub

    ' Event Handlers
    Private Sub BtnHit_Click(sender As Object, e As EventArgs) Handles btnHit.Click
        If gameOver Then Return

        DealCardToPlayer()

        If currentPlayerScore > 21 Then
            DetermineWinner()
        End If
    End Sub

    Private Sub BtnStand_Click(sender As Object, e As EventArgs) Handles btnStand.Click
        If gameOver Then Return

        DealerPlay()
    End Sub

    Private Sub BtnNewGame_Click(sender As Object, e As EventArgs) Handles btnNewGame.Click
        StartNewGame()
    End Sub
End Class

Public Class Card
    Public Property Suit As String
    Public Property Value As String

    Public Sub New(suit As String, value As String)
        Me.Suit = suit
        Me.Value = value
    End Sub

    Public Function GetDisplayText() As String
        Return $"{Value}{vbCrLf}{Suit}"
    End Function
End Class

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