from settings import *
from pygame.time import get_ticks
import pygame as pg
from pytmx.util_pygame import load_pygame
from pygame.math import Vector2 as vector
import os


CHAR_ROWS = 4
CHAR_COLS = 4
NOMEKOP_ROWS = 2
NOMEKOP_COLS = 4



def distance(s1, s2):
	return (((s1.rect.centerx - s2.rect.centerx)**2 + (s1.rect.centery - s2.rect.centery)**2)**0.5)


def player_is_blocked_by_object(player, collidable_sprites):
	r1_right = player.x + player.width
	r1_left = player.x
	r1_top = player.y
	r1_bot = player.y + player.height
	r1_centery = player.y + player.height/2
	r1_centerx = player.x + player.width/2
	
	i = 0
	while i < len(collidable_sprites):
		sprite = collidable_sprites[i]
		r2_right = sprite.x + sprite.width
		r2_left = sprite.x 
		r2_top = sprite.y
		r2_bot = sprite.y + sprite.height
		i += 1
		if player.direction == "right" and (r1_right - 50 > r2_left and r1_left < r2_left) and (r2_top <= r1_centery <= r2_bot):
			return True
		elif player.direction == "left" and (r1_left + 50 < r2_right and r1_right > r2_right) and (r2_top <= r1_centery<= r2_bot):
			return True
		elif player.direction == "down" and (r1_bot - 50 > r2_top and r1_top < r2_top) and (r2_left <= r1_centerx <= r2_right):
			return True
		elif player.direction == "up" and (r1_top + 50 < r2_bot and r1_bot > r2_bot) and (r2_left <= r1_centerx <= r2_right):
			return True
	
	return False
	
def return_y(s):
	if s.kind == "monster_patch":
		return s.rect.centery - 40
	else:
		return s.rect.centery


def import_maps(map_names):

    maps = {}

    for name in map_names:
        path = os.path.join("..", "data", "maps", name)
        maps[name] = load_pygame(path)

    return maps

def load_all_images(full_path, rows, cols):
	
	all_imgs = pg.image.load(full_path).convert_alpha()
	cell_width, cell_height = all_imgs.get_width() / cols, all_imgs.get_height() / rows

	frames = []
	for row in range(rows):
		for col in range(cols):
			img = all_imgs.subsurface((col * cell_width, row * cell_height, cell_width, cell_height))
			frames.append(img)
		
	return frames

def load_image(image_name):
    # loads a nomekop image icon given the name of the image, e.g., "Draem.png"
    path = os.path.join("..", "graphics", "icons", image_name)
    return pg.image.load(path).convert_alpha()

def flip_image(image):
    # flips an image horizontally
    return pg.transform.flip(image, True, False)

def load_char(image_name, flip=False):
    path = os.path.join("..", "graphics", "characters", image_name)
    images = load_all_images(path, 4, 4)
    image = images[4]
    if flip:
        image = flip_image(image)
    return image

def load_frames(nomekop, flip):
    # loads all frames relevant to a nomekop
	frames = []
	image_name = nomekop + ".png"
	path = os.path.join("..", "graphics", "nomekop", image_name)
	frames = load_all_images(path, 2, 4)
	if nomekop in LEGENDARY:
		path = os.path.join("..", "graphics", "attacks", "ice.png")
		frames = frames + load_all_images(path, 12, 4)
	elif nomekop in FIRE:
		path = os.path.join("..", "graphics", "attacks", "fire.png")
		frames = frames + load_all_images(path, 1, 4)

	elif nomekop in PLANT:
		path = os.path.join("..", "graphics", "attacks", "plant.png")
		frames = frames + load_all_images(path, 1, 4)

	elif nomekop in WATER:
		path = os.path.join("..", "graphics", "attacks", "water.png")
		frames = frames + load_all_images(path, 1, 4)

	if flip:
		frames = [flip_image(image) for image in frames]
	return frames


def load_icons(nomekop_list, flip):
    icons = []
    i = 0
    while i < len(nomekop_list):
        image_name = nomekop_list[i] + ".png"
        image = load_image(image_name)
        if flip:
            image = flip_image(image)
        icons = icons + [image]
        i = i + 1
    return icons

class Timer:
	def __init__(self, duration, repeat = False, autostart = False, func = None):
		self.duration = duration
		self.start_time = 0
		self.active = False
		self.repeat = repeat
		self.func = func
		if autostart:
			self.activate()

	def activate(self):
		self.active = True
		self.start_time = get_ticks()

	def deactivate(self):
		self.active = False
		self.start_time = 0
		if self.repeat:
			self.activate()

	def update(self):
		if self.active:
			current_time = get_ticks()
			if current_time - self.start_time >= self.duration:
				if self.func:
					self.func()
				self.deactivate()


class Evolution:
	def __init__(self, start_nomekop, end_nomekop, font, end_evolution):
		self.display_surface = pg.display.get_surface()
		path = os.path.join("..", "graphics", "nomekop", start_nomekop + ".png")
		self.start_monster_surf = pg.transform.scale2x(load_all_images(path, 2, 4)[0])
		path = os.path.join("..", "graphics", "nomekop", end_nomekop + ".png")
		self.end_monster_surf = pg.transform.scale2x(load_all_images(path, 2, 4)[0])
		self.timers = {
			'start': Timer(800, autostart = True),
			'end': Timer(1800, func = end_evolution)
		}

		# star animation
		star_frames = []
		path = os.path.join("..", "graphics", "stars")
		files = os.listdir(path)
		for file in files:
			path = os.path.join("..", "graphics", "stars", file)
			star_frames += load_all_images(path, 1, 1)

		self.star_frames = [pg.transform.scale2x(frame) for frame in star_frames]
		self.frame_index = 0

		# screen tint
		self.tint_surf = pg.Surface(self.display_surface.get_size())
		self.tint_surf.set_alpha(200)

		# white tint 
		self.start_monster_surf_white = pg.mask.from_surface(self.start_monster_surf).to_surface()
		self.start_monster_surf_white.set_colorkey('black')
		self.tint_amount, self.tint_speed = 0, 80
		self.start_monster_surf_white.set_alpha(self.tint_amount)

		# text 
		self.start_text_surf = font.render(f'{start_nomekop} is evolving', False, COLORS['black'])
		self.end_text_surf = font.render(f'{start_nomekop} evolved into {end_nomekop}', False, COLORS['black'])

	def display_stars(self, dt):
		self.frame_index += 20 * dt
		if self.frame_index < len(self.star_frames):
			frame = self.star_frames[int(self.frame_index)]
			rect = frame.get_frect(center = (WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2))
			self.display_surface.blit(frame, rect)

	def update(self, dt):
		for timer in self.timers.values():
			timer.update()

		if not self.timers['start'].active:
			self.display_surface.blit(self.tint_surf, (0,0))
			if self.tint_amount < 255:
				rect = self.start_monster_surf.get_frect(center = (WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2))
				self.display_surface.blit(self.start_monster_surf, rect)

				self.tint_amount += self.tint_speed * dt
				self.start_monster_surf_white.set_alpha(self.tint_amount)
				self.display_surface.blit(self.start_monster_surf_white, rect)

				text_rect = self.start_text_surf.get_frect(midtop = rect.midbottom + vector(0,20))
				pg.draw.rect(self.display_surface, COLORS['white'], text_rect.inflate(20,20), 0, 5)
				self.display_surface.blit(self.start_text_surf, text_rect)

			else:
				rect = self.end_monster_surf.get_frect(center = (WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2))
				self.display_surface.blit(self.end_monster_surf, rect)
				
				text_rect = self.end_text_surf.get_frect(midtop = rect.midbottom + vector(0,20))
				pg.draw.rect(self.display_surface, COLORS['white'], text_rect.inflate(20,20), 0, 5)
				self.display_surface.blit(self.end_text_surf, text_rect)
				self.display_stars(dt)

				if not self.timers['end'].active:
					self.timers['end'].activate()