import tkinter as tk
import random
import math

WINDOW_WIDTH = 400
WINDOW_HEIGHT = 600
WAX_COLOR = "#f84d6a"
BACKGROUND_COLOR = "#101030"

NUM_SIDES = 12        # number of vertices per blob
WIGGLE_AMOUNT = 4     # how much each point can change per frame

class WaxBlob:
    def __init__(self, canvas):
        self.radius = random.randint(30, 60)
        self.x = random.randint(self.radius, WINDOW_WIDTH - self.radius)
        self.y = random.randint(self.radius, WINDOW_HEIGHT - self.radius)

        self.vy = random.uniform(-0.8, 0.8)
        self.canvas = canvas

        # generate random radial offsets so shape isn't a perfect circle
        self.offsets = [random.uniform(0.8, 1.2) for _ in range(NUM_SIDES)]
        self.id = canvas.create_polygon(self._get_points(),
                                        fill=WAX_COLOR, outline="")

    def _get_points(self):
        points = []
        for i in range(NUM_SIDES):
            angle = (2 * math.pi / NUM_SIDES) * i
            r = self.radius * self.offsets[i]
            px = self.x + r * math.cos(angle)
            py = self.y + r * math.sin(angle)
            points.extend([px, py])
        return points

    def move(self):
        self.y += self.vy
        if self.y - self.radius < 0 or self.y + self.radius > WINDOW_HEIGHT:
            self.vy = -self.vy

        # gently wiggle each radial offset so that the blob keeps changing shape
        self.offsets = [
            max(0.4, min(1.6, off + random.uniform(-0.02, 0.02)))
            for off in self.offsets
        ]

        self.canvas.coords(self.id, *self._get_points())

    def distance_to(self, other):
        return math.hypot(self.x - other.x, self.y - other.y)

    def merge_with(self, other):
        area1 = math.pi * (self.radius ** 2)
        area2 = math.pi * (other.radius ** 2)
        total = area1 + area2

        self.radius = math.sqrt(total / math.pi)
        self.offsets = [
            (a + b) / 2 for a, b in zip(self.offsets, other.offsets)
        ]
        self.x = (self.x + other.x) / 2
        self.y = (self.y + other.y) / 2

def simulate():
    for blob in blobs:
        blob.move()

    for i in range(len(blobs)):
        for j in range(i + 1, len(blobs)):
            b1 = blobs[i]
            b2 = blobs[j]
            if b1.distance_to(b2) < (b1.radius + b2.radius) * 0.65:
                b1.merge_with(b2)
                canvas.delete(b2.id)
                blobs.remove(b2)
                break

    if random.random() < 0.01 and len(blobs) < 8:
        new_blob = WaxBlob(canvas)
        new_blob.radius = 15
        blobs.append(new_blob)

    root.after(30, simulate)

root = tk.Tk()
root.title("Lava Lamp Simulator")
canvas = tk.Canvas(root, width=WINDOW_WIDTH, height=WINDOW_HEIGHT,
                   bg=BACKGROUND_COLOR, highlightthickness=0)
canvas.pack()

blobs = [WaxBlob(canvas) for _ in range(4)]
root.after(30, simulate)
root.mainloop()
