import pygame
from pygame.locals import *
from random import *

class Video(object): 
    def __init__(self,width,height,gameTitle,version,credit,credit2,fullscreen=False): 
        self.width = int(width)
        self.height = int(height)
        self.gameTitle = gameTitle
        self.version = version
        self.credit = credit
        self.credit2 = credit2
        self.fullscreen = fullscreen
        self.lmap = None
        self.tile = []
        self.unit = []
        self.houses = []
        self.statuses = []
        self.wave_a = []
        self.wave_b = []
        self.wave_c = []
        self.wave_d = []
        self.wave_e = []
        self.bulles = []
        self.gameIcon = pygame.image.load('Icon.png')
        pygame.display.set_icon(self.gameIcon)
        self.window = None
        if(self.fullscreen): self.window = pygame.display.set_mode((width, height),FULLSCREEN)
        else: self.window = pygame.display.set_mode((width, height))

        pygame.display.set_caption(self.gameTitle+" - "+self.version)

        self.littleText = pygame.font.Font('atwriter.ttf',18)
        self.mediumText = pygame.font.Font('atwriter.ttf',26)
        self.largeText = pygame.font.Font('atwriter.ttf',48)
        self.menubar = pygame.image.load("menubar.png").convert()
        self.red = pygame.image.load("Red.png").convert_alpha()
        
        #fond = pygame.image.load("background.jpg").convert()
        #self.window.blit(fond, (0,0))
        
        print("Video OK")

    def refresh(self,year=-1):
        pygame.display.flip()
        if(year>-1):
            pygame.display.set_caption(self.gameTitle+" - "+self.version+" - Year "+str(self.lmap.year))

    def setMap(self,lmap):
        self.lmap = lmap
        #Load all resources
        for x in self.lmap.tilesIndex :
            self.tile.append(pygame.image.load(x+".png").convert())
        for x in self.lmap.unitsIndex :
            self.unit.append(pygame.image.load(x+".png").convert_alpha())
        for x in range(1,self.lmap.civ.stadeMax+1):
            self.houses.append(pygame.image.load("House"+str(x)+".png").convert_alpha())
        for x in range(1,self.lmap.civ.statusMax+1):
            self.statuses.append(pygame.image.load("Status"+str(x)+".png").convert_alpha())
        for x in range(1,9):
            self.wave_a.append(pygame.image.load("Wave_a_"+str(x)+".png").convert_alpha())
            self.wave_b.append(pygame.image.load("Wave_b_"+str(x)+".png").convert_alpha())
            self.wave_c.append(pygame.image.load("Wave_c_"+str(x)+".png").convert_alpha())
            self.wave_d.append(pygame.image.load("Wave_d_"+str(x)+".png").convert_alpha())
            self.wave_e.append(pygame.image.load("Wave_e_"+str(x)+".png").convert_alpha())

        self.tree_top = pygame.image.load("Trees_top.png").convert_alpha()
        self.tree_bottom = pygame.image.load("Trees_bottom.png").convert_alpha()
        self.tree_right = pygame.image.load("Trees_right.png").convert_alpha()
        self.tree_left = pygame.image.load("Trees_left.png").convert_alpha()

        self.grass_top = pygame.image.load("Grass_top.png").convert_alpha()
        self.grass_bottom = pygame.image.load("Grass_bottom.png").convert_alpha()
        self.grass_right = pygame.image.load("Grass_right.png").convert_alpha()
        self.grass_left = pygame.image.load("Grass_left.png").convert_alpha()

        self.rock_top = pygame.image.load("Rock_top.png").convert_alpha()
        self.rock_bottom = pygame.image.load("Rock_bottom.png").convert_alpha()
        self.rock_right = pygame.image.load("Rock_right.png").convert_alpha()
        self.rock_left = pygame.image.load("Rock_left.png").convert_alpha()

        self.pop = pygame.image.load("Pop.png").convert_alpha()

        for x in range(0,2):
            self.bulles.append(pygame.image.load("Bulle"+str(x)+".png").convert_alpha())

    def drawMenubar(self):
        self.window.blit(self.menubar, (0,0))
        if(self.lmap.force>0):
            for x in range(0,int(self.lmap.width*self.lmap.force/100)+1):
                self.window.blit(self.red,(x*32,0))
        
        self.window.blit(self.pop, (8,0))
        self.message_display(str(self.lmap.getPop()),64,16,2,"white")
        self.message_display(self.lmap.civ.getAge(),-1,16,2,"white")

    def blackScreen(self):
        self.window.fill((0,0,0))

    def drawTuto(self):
        self.window.fill((0,0,0))
        self.message_display("How to play",-1,64,3,"white")
        self.message_display("You must defend human expansion against monsters... And humanity itself",-1,120,2,"white")
        self.message_display("As a GOD, generate earthquakes by pressing SPACE, shorter or longer.",-1,150,2,"white")
        self.message_display("Weak waves will destroy weak threats like insects",-1,280,2,"white")
        self.message_display("Strong waves will destroy any monsters but can damage your civilization too !",-1,310,2,"white")
        self.message_display("If your civilization is not happy, it can't evolve. So SHAKE THEM !",-1,350,2,"red")
        self.message_display("To win, your civilization MUST be happy and evolved at the end of the century !",-1,400,2,"white")
        self.message_display("In any case, PRESS SPACE :D",-1,500,2,"white")

    def drawTitle(self):
        self.blackScreen()
        self.window.blit(pygame.image.load("Title.png").convert(), (int(abs(self.width-1024)/2),int(abs(self.height-768)/2) ))
        self.message_display(self.gameTitle+" - "+self.version,-1,64,3,"white")
        self.message_display(self.credit,-1,120,1,"white")
        self.message_display(self.credit2,-1,140,1,"white")

    def drawGameOver(self):
        self.blackScreen()
        self.window.blit(pygame.image.load("GameOver.png").convert(), (int(abs(self.width-1024)/2),int(abs(self.height-768)/2) ))
        self.message_display("Game Over",-1,64,3,"white")
        self.message_display("Your civilization has fallen in chaotic ages...",-1,120,2,"white")


    def drawVictory(self):
        self.blackScreen()
        self.window.blit(pygame.image.load("Victory.png").convert(), (int(abs(self.width-1024)/2),int(abs(self.height-768)/2) ))
        self.message_display("Victory !",-1,64,3,"black")
        self.message_display("Your civilization has reached heaven on earth :)",-1,120,2,"black")
        self.message_display("SCORE : "+str(self.lmap.getPop()),-1,150,2,"black")

    def tile_top(self,z):
        if(z<self.lmap.width): return -1
        return self.lmap.tiles[z-self.lmap.width]

    def tile_bottom(self,z):
        if(int(z/self.lmap.width)>=self.lmap.height-1): return -1
        return self.lmap.tiles[z+self.lmap.width]

    def tile_left(self,z):
        if(z%self.lmap.width==0): return -1
        return self.lmap.tiles[z-1]

    def tile_right(self,z):
        if(z%self.lmap.width==self.lmap.width-1): return -1
        return self.lmap.tiles[z+1]


    def drawTiles(self):
        for h in range(0,self.lmap.height):
            for w in range(0,self.lmap.width):
                z = h*self.lmap.width+w
                t = self.lmap.tiles[z]
                self.window.blit(self.tile[t],(w*32,(h+1)*32))

                if(t==1): #Eau par rapport à la Roche
                    if(self.tile_top(z)==3): self.window.blit(self.rock_top,(w*32,(h+1)*32))
                    if(self.tile_bottom(z)==3): self.window.blit(self.rock_bottom,(w*32,(h+1)*32))
                    if(self.tile_left(z)==3): self.window.blit(self.rock_left,(w*32,(h+1)*32))
                    if(self.tile_right(z)==3): self.window.blit(self.rock_right,(w*32,(h+1)*32))
                
                if(t==3 or t==1): #Roche et Eau par rapport à l'herbe
                    if(self.tile_top(z)==0): self.window.blit(self.grass_top,(w*32,(h+1)*32))
                    if(self.tile_bottom(z)==0): self.window.blit(self.grass_bottom,(w*32,(h+1)*32))
                    if(self.tile_left(z)==0): self.window.blit(self.grass_left,(w*32,(h+1)*32))
                    if(self.tile_right(z)==0): self.window.blit(self.grass_right,(w*32,(h+1)*32))
                
                if(t!=2): #Végétation
                    if(self.tile_top(z)==2): self.window.blit(self.tree_top,(w*32,(h+1)*32))
                    if(self.tile_bottom(z)==2): self.window.blit(self.tree_bottom,(w*32,(h+1)*32))
                    if(self.tile_left(z)==2): self.window.blit(self.tree_left,(w*32,(h+1)*32))
                    if(self.tile_right(z)==2): self.window.blit(self.tree_right,(w*32,(h+1)*32))
                    
    def drawUnits(self):
        for h in range(0,self.lmap.height):
            for w in range(0,self.lmap.width):
                if(self.lmap.tiles[h*self.lmap.width+w]>=0):
                    if(self.lmap.units[h*self.lmap.width+w]==1):#Si on doit dessiner une maison
                        self.window.blit(self.houses[self.lmap.civ.stade-1],(w*32,(h+1)*32))
                        for ss in range(self.lmap.civ.status):
                            self.window.blit(self.statuses[ss],(w*32,(h+1)*32))
                    else:
                        self.window.blit(self.unit[self.lmap.units[h*self.lmap.width+w]],(w*32,(h+1)*32))

    def drawWavePart(self,x,y,xc,yc,r):
        force = self.lmap.wave.force

        top = (yc-y>=r)
        right = (x-xc>=r)
        bottom = (y-yc>=r)
        left = (xc-x>=r)

        topright = (y<yc) and (x>xc)
        rightbottom = (x>xc) and (y>yc)
        leftbottom = (x<xc) and (y>yc)
        topleft = (y<yc) and (x<xc)
        
        if(force<20): wavesource = self.wave_a
        if(force>=20 and force<40): wavesource = self.wave_b
        if(force>=40 and force<60): wavesource = self.wave_c
        if(force>=60 and force<80): wavesource = self.wave_d
        if(force>=80): wavesource = self.wave_e

        
        if(top and right==False and left==False): self.window.blit(wavesource[0],(x*32,(y+1)*32)) #Up
        if(topright and top==False and right==False): self.window.blit(wavesource[1],(x*32,(y+1)*32)) #Up-Right
        if(right and top==False and bottom==False): self.window.blit(wavesource[2],(x*32,(y+1)*32)) #Right
        if(rightbottom and right==False and bottom==False): self.window.blit(wavesource[3],(x*32,(y+1)*32)) #Down-Right
        if(bottom and right==False and left==False): self.window.blit(wavesource[4],(x*32,(y+1)*32)) #Down
        if(leftbottom and left==False and bottom==False): self.window.blit(wavesource[5],(x*32,(y+1)*32)) #Down-Left
        if(left and bottom==False and top==False): self.window.blit(wavesource[6],(x*32,(y+1)*32)) #Left
        if(topleft and top==False and left==False): self.window.blit(wavesource[7],(x*32,(y+1)*32)) #Up-Left
        
        self.lmap.waveEffect(x,y)
    
    def waveCircle(self,x_centre,y_centre,r):
        x=0
        y=r
        d=r-1
        while y>=x :
            self.drawWavePart(x_centre + x , y_centre + y,x_centre,y_centre,r)
            self.drawWavePart(x_centre + y , y_centre + x,x_centre,y_centre,r)
            self.drawWavePart(x_centre - x , y_centre + y,x_centre,y_centre,r)
            self.drawWavePart(x_centre - y , y_centre + x,x_centre,y_centre,r)
            self.drawWavePart(x_centre + x , y_centre - y,x_centre,y_centre,r)
            self.drawWavePart(x_centre + y , y_centre - x,x_centre,y_centre,r)
            self.drawWavePart(x_centre - x , y_centre - y,x_centre,y_centre,r)
            self.drawWavePart(x_centre - y , y_centre - x,x_centre,y_centre,r)
            if(d>=2*x):
                d = d-2*x-1
                x = x+1
            elif(d< 2*(r-y)):
                d = d+2*y-1
                y = y-1     
            else:
                d = d+2*(y-x-1)
                y = y-1
                x = x+1

    def drawWave(self):
        self.waveCircle(int(self.lmap.width/2),int(self.lmap.height/2),self.lmap.wave.r)

    def drawBulle(self,x,y,expr):
        self.window.blit(self.bulles[expr],(x,y))

    def drawBulles(self):
        if(self.lmap.bulles!=None):
            for bulle in self.lmap.bulles :
                self.drawBulle(bulle.x*32+16,(bulle.y+1)*32-16-32,bulle.expr-1)
                bulle.timer()
        i = 0
        while i<len(self.lmap.bulles):
            if(self.lmap.bulles[i].expired()):
                self.lmap.bulles.pop(i)
                i -=1
            i += 1

    def drawMap(self):
        self.blackScreen()
        self.drawTiles()
        self.drawUnits()
        if(self.lmap.wave!=None): self.drawWave()
        self.drawMenubar()
        self.drawBulles()

    def text_objects(self,text, font, color="black"):
        if(color=="black"): rgbcolor = (0,0,0)
        if(color=="white"): rgbcolor = (255,255,255)
        if(color=="red"): rgbcolor = (255,0,0)
        textSurface = font.render(text, True, rgbcolor)
        return textSurface, textSurface.get_rect()

    def message_display(self,text,x=-1,y=-1,size=1,color="black"):
        if(size==1): TextSurf, TextRect = self.text_objects(text, self.littleText,color)
        if(size==2): TextSurf, TextRect = self.text_objects(text, self.mediumText,color)
        if(size==3): TextSurf, TextRect = self.text_objects(text, self.largeText,color)
        if(x==-1): x = (self.width/2)
        if(y==-1): y = (self.height/2)
        TextRect.center = (x,y)
        self.window.blit(TextSurf, TextRect)

    def playEffect(self,so,power=1):
        effect = None
        if(so=="earthquake"): effect = pygame.mixer.Sound('earthquake.wav')
        if(so=="dino"): effect = pygame.mixer.Sound('dino.wav')
        if(so=="dead"): effect = pygame.mixer.Sound('dead.wav')
        if(so=="dead1"): effect = pygame.mixer.Sound('dead1.wav')
        if(so=="dead2"): effect = pygame.mixer.Sound('dead2.wav')
        if(so=="dead3"): effect = pygame.mixer.Sound('dead3.wav')
        if(so=="deads"): effect = pygame.mixer.Sound('deads.wav')
        if(so=="water"): effect = pygame.mixer.Sound('water.wav')
        if(so=="victory"): effect = pygame.mixer.Sound('victory.wav')
        if(so=="gameover"): effect = pygame.mixer.Sound('gameover.wav')
        if(effect!=None): effect.play()
