#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Module pygame pour le projet02
par gforhan
"""

import pygame
from pygame.locals import *

# temps (en ms) d'affichage de la fenêtre pygame
TIMER = 5000
# dictionnaire de couleurs codées en RGB
COLORS = {'black':(0,0,0),\
			 'red':(255,0,0),\
			 'green':(0,255,0),\
			 'blue':(0,0,255),\
			 'white':(255,255,255)\
			}

def setTimer(t : int) -> None :
	"""
	entrée : t un entier représentant un nombre de secondes
	sortie : -
	démarche : affecte la valeur t à la variable TIMER du module
	"""
	assert isinstance(t, int) and t > 0, "setTimer: t doit être un entier strictement positif"
	global TIMER
	TIMER = t
	print( f"TIMER = {TIMER} ms" )

def _repere(fond : 'pygame.Surface', fenetre : dict) -> None :
	"""
	entrée : fond une surface pygame, fenetre précise les extrema (x,y) du repérage
	sortie : -
	démarche : dessiner les lignes+graduation du répère avec l'origine (0,0) centrée dans la surface fond
	"""
	global COLORS
	sxmin, symin = 0, 0
	sxmax, symax = fond.get_size()
	x0 = ( sxmax - sxmin ) // 2
	y0 = ( symax - symin ) // 2
	
	pygame.draw.line(fond, COLORS['white'], (sxmin,y0), (sxmax,y0) , 1)
	dx = (sxmax - sxmin) / ( fenetre['xmax'] - fenetre['xmin'] )
	for i in range( fenetre['xmax'] - fenetre['xmin'] + 1 ) :
		l = pygame.draw.line(fond, COLORS['white'], (i*dx, y0-3), (i*dx, y0+3) , 1)

	pygame.draw.line(fond, COLORS['white'], (x0, symin), (x0,symax) , 1)
	dy = (symax - symin) / ( fenetre['ymax'] - fenetre['ymin'] )
	for i in range( fenetre['ymax'] - fenetre['ymin'] + 1 ) :
		l = pygame.draw.line(fond, COLORS['white'], (x0-3,i*dy), (x0+3,i*dy) , 1)

	police=pygame.font.SysFont("monospace",15)# on definit la police et la taille
	if fenetre['xmax'] <= 5 :
		imageTxt=police.render("1",True,COLORS['white'])# imageTxt contient le msg
		fond.blit(imageTxt,(x0+dx,y0+dy/2))# on positionne l'image
	else :
		imageTxt=police.render("5",True,COLORS['white'])
		fond.blit(imageTxt,(x0+5*dx,y0+dy/2))
	if fenetre['ymax'] <= 5 :
		imageTxt=police.render("1",True,COLORS['white'])
		fond.blit(imageTxt,(x0-dx/2,y0-dy))
	else :
		imageTxt=police.render("5",True,COLORS['white'])
		fond.blit(imageTxt,(x0-dx/2,y0-5*dy))

	pygame.display.flip()

def _afficheP(fond : 'pygame.Surface', fenetre : dict, z : 'NbComplexe', bcoord : bool = False) -> None :
	"""
	entrée : fond une surface pygame, 
				fenetre précise les extrema (x,y) du repérage
				z une instance NbComplexe, 
				bcoord un booléen qui précise si on affiche les coordonnées de z
	sortie : -
	démarche : placement du point Z (et des coordonnées) dans la surface fond
	"""
	global COLORS
	sxmin, symin = 0, 0
	sxmax, symax = fond.get_size()
	x0 = ( sxmax - sxmin ) // 2
	y0 = ( symax - symin ) // 2
	dx = (sxmax - sxmin) / ( fenetre['xmax'] - fenetre['xmin'] )
	dy = (symax - symin) / ( fenetre['ymax'] - fenetre['ymin'] )

	xz, yz = x0 + z.get_re() * dx, y0 - z.get_im() * dy # coordonnées du point Z
	tcx = 2 # taille de la croix
	pygame.draw.line(fond, COLORS['red'], (xz-tcx,yz-tcx), (xz+tcx,yz+tcx))
	pygame.draw.line(fond, COLORS['red'], (xz-tcx,yz+tcx), (xz+tcx,yz-tcx))

	if bcoord : # si affichage des coordonnées
		police=pygame.font.SysFont("monospace",15)# on definit la police et la taille
		imageTxt=police.render(str(z), True, COLORS['red'])
		fond.blit(imageTxt,(xz-tcx,yz+tcx))

def affichage(*args : list) -> None :
	"""
	entrée : liste d'instances NbComplexe
	sortie : -
	démarche : 
		parcours la liste pour déterminer les extrema des parties réelles et imaginaires des NbComplexe
		affiche un repère (O,i,j) incluant les extrema déterminés
		re-parcours la liste pour afficher chaque nombre complexe dans le plan durant TIMER secondes
	expl : affichage( z1, z2, z3, True )
	expl2 : affichage( listeZ, False )
	"""
	import time
	global TIMER
	pygame.init()
	
	bcoord = False
	if isinstance( args[-1], bool) :
		bcoord = args[-1]
		args = args[:-1]
	if isinstance( args[0], list ) :
		args = [ e for e in args[0] ]

	fenetre = {'xmin':-5, 'xmax':5, 'ymin':-5, 'ymax':5} # dimension du repère

	rfenetre = Rect(0,0,800,600)
	screen = pygame.display.set_mode(rfenetre.size, 0)
	screen.fill( COLORS['black'] )

	_repere( screen, fenetre )
	
	for z in args :
		_afficheP( screen, fenetre, z, bcoord )

	pygame.display.flip()
	pygame.time.wait( TIMER )	
	pygame.quit()

# fin du fichier projet02_pygame.py
