import random
import os,fnmatch
from datetime import timedelta
from pygame._sdl2.video import Window
from pgzhelper import *

WIDTH = 800
HEIGHT = 800
debug = False

pics = ['puzzle1']
doneimg = Actor('welldone',pos=(WIDTH//2,HEIGHT+500))
startimg = Actor('start',pos=(WIDTH//2,-500))

class Game():
    tiles=[]
    tiles_max=0
    path = None
    picture = None
    drag= None
    last= None
    show = False
    timer = 0
    run = False

    def __init__(self,no):
        self.no=no
        self.img = Actor(Game.path+'/'+str(no))
        Game.tiles.append(self)
        self.xo,self.yo = self.get_pos()
        x = random.randint(1,16)
        y = random.randint(1, 6)
        self.img.pos = (x*40,400+y*50)
        self.img.angle = 90*random.randint(0,3)
        self.inplace = False

    def get_pos(self):
        pos = (None,None)
        if Game.tiles_max>0:
            xp = WIDTH // 2 - Game.picture.width // 2
            yp = HEIGHT // 2 - Game.picture.height // 2
            sx = Game.tiles[0].img.width  + 1
            sy = Game.tiles[0].img.height + 1
            cols = round(Game.picture.width/sx)
            rows = round(Game.picture.height/sy)
            lp = 1
            for m in range(rows):
                for n in range(cols):
                    x = xp + n * sx + sx // 2
                    y = yp + m * sy + sy // 2
                    if lp==self.no:
                        pos = (x,y)
                    lp+=1
        return pos

    def set_inplace(self):
        self.img.pos = (self.xo,self.yo)
        self.img.angle = 0
        self.inplace = True

    def near_inplace(self,dist=30):
        if abs(self.img.x - self.xo)<dist and \
               abs(self.img.y - self.yo)<dist and self.img.angle==0:
                if not self.inplace:
                    animate(self.img, tween='bounce_end', duration=0.25, pos=(self.xo,self.yo))
                    self.inplace = True

    @classmethod
    def load(cls,path):
        cls.tiles_max=len(fnmatch.filter(os.listdir(path), '*.png'))-1
        cls.path = path
        cls.picture = Actor(path+'/0')
        cls.picture.pos = (WIDTH // 2,HEIGHT // 2)
        for no in range(1,cls.tiles_max+1):
            cls(no)

    @classmethod
    def start(cls,name):
        window = Window.from_display_module()
        window.position = (0,32)
        Game.load(os.getcwd()+'/images/'+name)
        cls.tiles[0].set_inplace()

    @classmethod
    def check_finish(cls):
        tiles_inplace = sum([ 1 for tile in cls.tiles if tile.inplace ])
        if debug: print(f"{tiles_inplace}/{cls.tiles_max}")
        return tiles_inplace == cls.tiles_max

    @classmethod
    def select_tile(cls,pos):
        i = len(cls.tiles)
        found=None
        for tile in cls.tiles[::-1]:
           i-=1
           if tile.img.collidepoint(pos):
                found = tile
                cls.last = tile
                cls.tiles.pop(i)
                cls.tiles.append(tile)
                break
        return found

def draw():
    screen.clear()
    screen.blit(Game.path + '\..\puzzle-bg', (0, 0))

    td = timedelta(seconds=Game.timer)
    screen.draw.text(f'Time: {td}', (WIDTH//2-110,10), color=(255,255,255), fontsize=48, shadow=(1.0,1.0))

def update():
    pass

def on_mouse_down(pos,button):
    pass

def on_mouse_up(pos):
    pass

def on_mouse_move(pos, rel, buttons):
    pass

Game.start(random.choice(pics))
