#!/usr/bin/env python3
import pygame
import time
import sys
import os
import numpy as np
import math
import random

PADDLE_LEN = 6

Ny = int(sys.argv[1])
Nx = int(sys.argv[2])
param = sys.argv[3]

speed = 1.0
try:
    speed = float(param)
except:
    pass

pygame.init()
pygame.joystick.init()
j1 = pygame.joystick.Joystick(0)
j2 = pygame.joystick.Joystick(1)
j1.init()
j2.init()

numbers = [
    int("0b111101101101111", 2),
    int("0b010010010010010", 2),
    int("0b111001111100111", 2),
    int("0b111001111001111", 2),
    int("0b100100100111010", 2),
    int("0b111100111001111", 2),
    int("0b111100111101111", 2),
    int("0b111001011010010", 2),
    int("0b111101111101111", 2),
    int("0b111101111001111", 2)
]



def Reset(sign=1):
    global x, y, dx, dy
    x = Nx//2
    y = Ny//2  
    dy = 1*sign
    dx = random.uniform(-0.4, 0.4)
    l = math.sqrt(dx*dx+dy*dy)/speed
    dx /= l
    dy /= l

Reset()

player1 = (Nx-PADDLE_LEN)//2
player2 = (Nx-PADDLE_LEN)//2
score1 = 0
score2 = 0

def clamp(a, x, b):
    if x < a:
        return a
    if x > b:
        return b
    return x

while True:
    for event in pygame.event.get():
        pass
    
    time.sleep(0.016)

    if j1.get_axis(0) > 0.2 and player1+PADDLE_LEN < Nx:
        player1 += 1
    if j1.get_axis(0) < -0.2 and player1 > 0 :
        player1 -= 1

    if j2.get_axis(0) > 0.2 and player2+PADDLE_LEN < Nx:
        player2 += 1
    if j2.get_axis(0) < -0.2 and player2 > 0 :
        player2 -= 1

    x += dx
    y += dy


    if x < 0 or x >= Nx:
        dx = -dx

    if y >= Ny-2 and y <= Ny-1:
        xi = int(x)
        if xi >= player1 and xi <= player1+PADDLE_LEN:
            dy = -1
            dx = x-(player1+PADDLE_LEN/2)
            l = math.sqrt(dx*dx+dy*dy)/speed
            dx /= l
            dy /= l

    if y >= Ny-1:
        score2+=1
        Reset() 

    if y <= 1 and y > 0:
        xi = int(x)
        if xi >= player2 and xi <= player2+PADDLE_LEN:
            dy = 1
            dx = x-(player2+PADDLE_LEN/2)
            l = math.sqrt(dx*dx+dy*dy)/speed
            dx /= l
            dy /= l

    if y <= 0:
        score1+=1
        Reset(-1.0)

    buffer = bytearray(b"\x00"*(3*Nx*Ny))
    def SetPixel(x, y, r, g, b):
        idx = 3*(y+Ny*x)
        buffer[idx+0] = r
        buffer[idx+1] = g
        buffer[idx+2] = b
    #SetPixel(x, y, 0xff, 0xff, 0xff)
    def showdigit(num, xs, ys, r, g, b):
        for y in range(ys+4, ys-1, -1):
            for x in range(xs+2, xs-1, -1):
                if num&1 == 1:
                    SetPixel(x, y, r, g, b)
                num >>= 1

    def shownum(num, x, y, r, g, b):
        # i am sorry
        if num == 0:
            showdigit(numbers[0], x, y, r, g, b)
            return
        digits = int(math.ceil(math.log(num)/math.log(10)+0.0001))
        xoff = (digits-1)*4
        for _ in range(digits, 0, -1):
            showdigit(numbers[num%10], x+xoff, y, r, g, b)
            num //= 10
            xoff-=4
    shownum(score2, 0, Ny//2-6, 0x00, 0x00, 0xff)
    shownum(score1, 0, Ny//2+2, 0xff, 0x00, 0x00)
    for i in range(Nx):
        if i %2 == 0:
            SetPixel(i, Ny//2, 0x00, 0xff, 0x00)
    xi = clamp(0, int(x), Nx-1)
    yi = clamp(0, int(y), Ny-1)

    SetPixel(xi, yi, 0xff, 0xff, 0xff)

    for i in range(PADDLE_LEN):
        SetPixel(player1+i, Ny-2, 0xff, 0x00, 0x00)
    for i in range(PADDLE_LEN):
        SetPixel(player2+i, 1, 0x00, 0x00, 0xff)
    
    os.write(1, buffer)