import socket

HOST = '127.0.0.1'
PORT = 5006

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((HOST, PORT))


offset = 0
currentSpeed = 0.0003
idleSpeed = 0.0003

# Clouds
cloud1X = 100
cloud2X = 500

# Sky
dayColor = color(100, 180, 255)
nightColor = color(20, 24, 82)
targetSkyColor = dayColor
currentSkyColor = dayColor

# Rock (unused but kept)
rockX = 150
targetRockX = 150
rockY = 250

numDrops = 100
rainX = [0]*numDrops
rainY = [0]*numDrops
isRaining = False

isRoadWet = False
roadColor = color(60)
wetRoadColor = color(35, 45, 55)

isStopped = False
savedSpeed = 0


def setup():
    size(800, 500)
    global rainX, rainY
    for i in range(numDrops):
        rainX[i] = random(width)
        rainY[i] = random(-height, 0)


def draw():
    global offset, currentSpeed, cloud1X, cloud2X
    global currentSkyColor, targetSkyColor
    global isRaining, isRoadWet, isStopped

    # Sky transition
    currentSkyColor = lerpColor(currentSkyColor, targetSkyColor, 0.05)
    background(currentSkyColor)

    # Clouds
    drawCloud(cloud1X, 120, 2.5)
    drawCloud(cloud2X, 180, 1.8)

    cloud1X -= currentSpeed * 15
    cloud2X -= currentSpeed * 25

    if cloud1X < -300:
        cloud1X = width + 300
    if cloud2X < -300:
        cloud2X = width + 300

    # Rain
    if isRaining:
        stroke(150, 150, 255, 150)
        strokeWeight(2)
        for i in range(numDrops):
            line(rainX[i], rainY[i], rainX[i], rainY[i] + 10)
            rainY[i] += 10 + (currentSpeed * 100)

            if rainY[i] > height:
                rainY[i] = random(-20, 0)
                rainX[i] = random(width)
        noStroke()

    # Grass
    fill(50, 150, 50)
    rect(0, height/2, width, height/2)

    # Road
    targetRoadColor = wetRoadColor if isRoadWet else roadColor
    fill(lerpColor(roadColor, targetRoadColor, 0.1))

    beginShape()
    vertex(width * 0.45, height/2)
    vertex(width * 0.55, height/2)
    vertex(width, height)
    vertex(0, height)
    endShape(CLOSE)

    # Wet reflections
    if isRoadWet:
        fill(180, 230, 255, 40)
        noStroke()
        beginShape()
        vertex(width * 0.47, height/2)
        vertex(width * 0.53, height/2)
        vertex(width * 0.70, height)
        vertex(width * 0.30, height)
        endShape(CLOSE)

        for i in range(3):
            yPos = map(i, 0, 3, height/2 + 50, height - 50)
            wPos = map(i, 0, 3, 40, 150)
            ellipse(width/2, yPos, wPos, 5)

    drawBigDrop(80, height - 80)

    # Speed control
    roadWidthAtMouseY = map(mouseY, height/2, height, width * 0.1, width)
    leftEdge = (width/2) - (roadWidthAtMouseY / 2)
    rightEdge = (width/2) + (roadWidthAtMouseY / 2)

    mouseInRoad = (mouseY > height/2 and mouseX > leftEdge and mouseX < rightEdge)

    if isStopped:
        targetSpeed = 0
    elif mouseInRoad:
        targetSpeed = map(mouseY, height/2, height, 0.001, 0.04)
    else:
        targetSpeed = idleSpeed

    currentSpeed = lerp(currentSpeed, targetSpeed, 0.05)

    # Lamps
    for i in range(5):
        lampPos = (offset * 10 + i * 0.2) % 1
        drawDualLamps(lampPos)

    drawStopSign(width - 80, height - 80, 0.8)

    # Road lines
    fill(255)
    i = 0
    while i < 1:
        pos = (i + offset) % 1
        y = lerp(height/2, height, pos)
        w = lerp(2, 40, pos)
        h = lerp(2, 20, pos)
        rect(width/2 - w/2, y, w, h)
        i += 0.1

    # Speed HUD
    pushMatrix()
    translate(width - 170, height / 2 - 35)

    fill(0, 0, 0, 200)
    stroke(0, 200, 255)
    strokeWeight(2)
    rect(0, 0, 150, 70, 12)

    fill(150, 200, 255)
    noStroke()
    textAlign(CENTER)
    textSize(11)
    text("CRUISE CONTROL", 75, 20)

    kmh = int(map(currentSpeed, 0.002, 0.1, 20, 240))

    if kmh > 180:
        fill(255, 50, 50)
    elif kmh > 100:
        fill(255, 200, 0)
    else:
        fill(100, 255, 100)

    textSize(26)
    text(str(kmh) + " KM/H", 75, 50)
    popMatrix()

    # Car
    pushMatrix()
    shake = random(-currentSpeed*40, currentSpeed*40)
    translate(width/2, height - 120 + shake)

    fill(160, 0, 0)
    rect(-130, 0, 260, 80, 20)

    fill(130, 0, 0)
    rect(-110, -60, 220, 70, 25)
    fill(20)
    rect(-95, -45, 190, 45, 10)

    fill(200, 0, 0)
    if currentSpeed > 0.05:
        fill(255, 50, 50)
    rect(-120, 20, 50, 25, 8)
    rect(70, 20, 50, 25, 8)

    fill(240)
    rect(-30, 35, 60, 25, 3)
    fill(0)
    textSize(20)
    textAlign(CENTER, CENTER)
    text("B4", 0, 47)

    fill(80)
    rect(-90, 75, 25, 15, 5)
    rect(65, 75, 25, 15, 5)

    popMatrix()

    offset += currentSpeed
    if offset > 0.1:
        offset = 0


def mousePressed():
    global targetSkyColor, isRaining, isRoadWet, isStopped

    if dist(mouseX, mouseY, cloud1X, 120) < 150:
        targetSkyColor = nightColor if targetSkyColor == dayColor else dayColor

    if dist(mouseX, mouseY, cloud2X, 180) < 100:
        isRaining = not isRaining

    if dist(mouseX, mouseY, 80, height - 80) < 40:
        isRoadWet = not isRoadWet

    if dist(mouseX, mouseY, width - 80, height - 80) < 40:
        isStopped = not isStopped


def drawCloud(x, y, sc):
    pushMatrix()
    translate(x, y)
    scale(sc)
    fill(255, 250)
    noStroke()
    ellipse(0, 0, 80, 50)
    ellipse(-30, 15, 60, 40)
    ellipse(30, 15, 60, 40)
    popMatrix()


def drawBigDrop(x, y):
    pushMatrix()
    translate(x, y)
    noStroke()
    fill(0, 150, 255, 200)
    if isRoadWet:
        stroke(255)
    strokeWeight(2)

    beginShape()
    vertex(0, -30)
    bezierVertex(-20, -10, -25, 10, 0, 20)
    bezierVertex(25, 10, 20, -10, 0, -30)
    endShape(CLOSE)

    fill(255, 150)
    ellipse(-5, -5, 8, 12)
    popMatrix()


def drawDualLamps(pos):
    y = lerp(height/2, height + 400, pos)
    h = lerp(10, 450, pos)
    sw = lerp(1, 10, pos)

    xLeft = lerp(width * 0.44, -300, pos)
    xRight = lerp(width * 0.56, width + 300, pos)

    stroke(30)
    strokeWeight(sw)

    line(xLeft, y, xLeft, y - h)
    line(xRight, y, xRight, y - h)

    noStroke()

    if targetSkyColor == nightColor:
        fill(255, 255, 180, 200)
        glowW = lerp(15, 120, pos)
        glowH = lerp(8, 50, pos)

        ellipse(xLeft + lerp(5, 40, pos), y - h + 5, glowW, glowH)
        ellipse(xRight - lerp(5, 40, pos), y - h + 5, glowW, glowH)

        fill(255, 255, 200, 30)
        ellipse(xLeft, y, glowW * 2, glowH)
        ellipse(xRight, y, glowW * 2, glowH)

    fill(40)
    rect(xLeft, y - h, lerp(10, 70, pos), lerp(5, 25, pos))
    rect(xRight - lerp(10, 70, pos), y - h, lerp(10, 70, pos), lerp(5, 25, pos))


def drawStopSign(x, y, sc):
    pushMatrix()
    translate(x, y)
    scale(sc)

    fill(200, 0, 0)
    if isStopped:
        stroke(255, 255, 0)
    else:
        noStroke()

    strokeWeight(4)
    beginShape()
    angle = TWO_PI / 8
    a = PI/8
    while a < TWO_PI:
        sx = cos(a) * 50
        sy = sin(a) * 50
        vertex(sx, sy)
        a += angle
    endShape(CLOSE)

    fill(255)
    textAlign(CENTER, CENTER)
    textSize(22)
    text("STOP", 0, 0)
    popMatrix()
    
def keyPressed():
    message = "1,2,3,4,5,6,7"
    
    client.send(message.encode('utf-8'))
    
    data = client.recv(1024)
    response = data.decode('utf-8')
    
    print("Response from Python:", response)    
