import psp2d
import time
from random import randint

images = 'blank.png','ud.png','lr.png','bl.png','tl.png','tr.png','br.png','rock.png','spout.png','end.png'
images = [psp2d.Image(x) for x in images]
cornice = psp2d.Image('cornice.png'), psp2d.Image('cornice1.png')
menuimg = [psp2d.Image('start.png'),psp2d.Image('quit.png')]
pauseimg = psp2d.Image('pause.png')
punt = [0,0]
bg = psp2d.Image('bg.png')
font = psp2d.Font('font.png')
blu = psp2d.Color(0,0,128)

screen = psp2d.Screen()

nuovepos = [0,0]

prossima_direzione = 'giu'

oldpad = psp2d.Controller()
pad = psp2d.Controller()            

class Blocco(object):
    def __init__(self, n, x, y):
        self.n = n
        self.x = x
        self.y = y
        self.nvolte = 0
        self.progress = 0
        self.direzione = prossima_direzione 
        self.indietro = 0
        self.vittoria = 0
        self.timer = 0
        direzione = prossima_direzione
    def draw(self):
        screen.blit(images[self.n], 0, 0, images[self.n].width, images[self.n].height, self.x, self.y, True)
    def showProgress(self):
        global prossima_direzione
        self.timer += 1
        if self.timer % 2 == 0:
            if self.direzione == 'destra' and self.nvolte <= 31: ## Fatto
                for a in range(10):
                    bg.putPixel(self.x+self.nvolte, 11+self.y+a, blu)
                if self.nvolte == 31:
                    self.pixel1 = screen.getPixel(self.x+32+1,self.y+15)
                    self.pixel2 = screen.getPixel(self.x+32+1,self.y+5)
                    if self.pixel1.red == 255 and self.pixel1.blue == 255 and self.pixel1.green == 255 and\
                       self.pixel2.red == 166 and self.pixel2.blue == 166 and self.pixel2.green == 166:
                        nuovepos[0] = self.x + 32
                        nuovepos[1] = self.y
                        self.pixel3a = screen.getPixel(self.x+32+15, self.y+30) #bl
                        if self.pixel3a.red == 255:
                            prossima_direzione = 'sinistra/giu'
                        self.pixel3b = screen.getPixel(self.x+32+15,self.y+1) # tl
                        if self.pixel3b.red == 255 and self.pixel3a.red != 255:
                            prossima_direzione = 'sinistra/su'
                    else:
                        if self.vittoria != 1:
                            self.vittoria = 2
                    
            elif self.direzione == 'sinistra' and self.nvolte <= 32: ## Fatto
                for a in range(10):
                    bg.putPixel(self.x+32-self.nvolte, 11+self.y+a, blu)
                if self.nvolte == 32:
                    self.pixel1 = screen.getPixel(self.x-1,self.y+16)
                    self.pixel2 = screen.getPixel(self.x-1,self.y+5)
                    if self.pixel1.red == 255 and self.pixel1.blue == 255 and self.pixel1.green == 255 and\
                       self.pixel2.red == 166 and self.pixel2.blue == 166 and self.pixel2.green == 166:
                        nuovepos[0] = self.x - 32
                        nuovepos[1] = self.y
                        self.pixel3 = screen.getPixel(self.x-15, self.y+30) #br
                        if self.pixel3.red == 255:
                            prossima_direzione = 'destra/giu'
                        self.pixel3 = screen.getPixel(self.x-15,self.y+1) # tr
                        if self.pixel3.red == 255:
                            prossima_direzione = 'destra/su'
                    else:
                        if self.vittoria != 1:
                            self.vittoria = 2

            elif self.direzione == 'giu' and self.nvolte <= 31: ## Fatto
                for a in range(10):
                    bg.putPixel(self.x+11+a, self.y+self.nvolte, blu)
                if self.nvolte == 31:
                    self.pixel1 = screen.getPixel(self.x+15,self.y+32+1)
                    self.pixel2 = screen.getPixel(self.x+1,self.y+32+1)
                    if self.pixel1.red == 255 and self.pixel1.blue == 255 and self.pixel1.green == 255 and\
                       self.pixel2.red == 166 and self.pixel2.blue == 166 and self.pixel2.green == 166:
                        nuovepos[0] = self.x
                        nuovepos[1] = self.y + 32
                        self.pixel3 = screen.getPixel(self.x+30,self.y+32+15)
                        if self.pixel3.red == 255:
                            prossima_direzione = 'su/destra'
                        self.pixel3 = screen.getPixel(self.x+1,self.y+32+15)
                        if self.pixel3.red == 255:
                            prossima_direzione = 'su/sinistra'
                    else:
                        if self.vittoria != 1:
                            self.vittoria = 2
                    
            elif self.direzione == 'su' and self.nvolte <= 32: ## Fatto
                for a in range(10):
                    bg.putPixel(self.x+11+a, self.y+32-self.nvolte, blu)
                if self.nvolte == 32:
                    self.pixel1 = screen.getPixel(self.x+15,self.y-1)
                    self.pixel2 = screen.getPixel(self.x+1,self.y-1)
                    if self.n == 9:
                            self.vittoria = 1
                    if self.pixel1.red == 255 and self.pixel1.blue == 255 and self.pixel1.green == 255 and\
                       self.pixel2.red == 166 and self.pixel2.blue == 166 and self.pixel2.green == 166:
                        nuovepos[0] = self.x
                        nuovepos[1] = self.y - 32
                        self.pixel3 = screen.getPixel(self.x+30,self.y-15)
                        if self.pixel3.red == 255:
                            prossima_direzione = 'giu/destra'
                        self.pixel3 = screen.getPixel(self.x+1,self.y-15)
                        if self.pixel3.red == 255:
                            prossima_direzione = 'giu/sinistra'
                    else:
                        if self.vittoria != 1:
                            self.vittoria = 2

            #tl 4
            elif self.direzione == 'su/sinistra' and self.nvolte <= 31: # da su a sinistra Fatto
                for a in range(10):
                    bg.putPixel(self.x+11+a, self.y+self.nvolte, blu)
                for a in range(10):
                    bg.putPixel(self.x+31-self.nvolte, 11+self.y+a, blu)
                if self.nvolte == 31:
                    self.pixel1 = screen.getPixel(self.x-1,self.y+15)
                    self.pixel2 = screen.getPixel(self.x-1,self.y+1)
                    if self.pixel1.red == 255 and self.pixel1.blue == 255 and self.pixel1.green == 255 and\
                       self.pixel2.red == 166 and self.pixel2.blue == 166 and self.pixel2.green == 166:
                        nuovepos[0] = self.x - 32
                        nuovepos[1] = self.y
                        self.pixel3 = screen.getPixel(self.x-1,self.y+16) #lr
                        if self.pixel3.red == 255:
                            prossima_direzione = 'sinistra'
                        self.pixel3 = screen.getPixel(self.x-15,self.y+30) #br
                        if self.pixel3.red == 255:
                            prossima_direzione = 'destra/giu'
                        self.pixel3 = screen.getPixel(self.x-16,self.y+1) #tr
                        if self.pixel3.red == 255:
                            prossima_direzione = 'destra/su'
                    else:
                        if self.vittoria != 1:
                            self.vittoria = 2
            elif self.direzione == 'sinistra/su' and self.nvolte <= 31: # da sinistra a su Fatto
                for a in range(10):
                    bg.putPixel(self.x+self.nvolte, 11+self.y+a, blu)
                for a in range(10):
                    bg.putPixel(self.x+11+a, self.y+31-self.nvolte, blu)
                if self.nvolte == 31:
                    self.pixel1 = screen.getPixel(self.x+15,self.y-1)
                    self.pixel2 = screen.getPixel(self.x+1,self.y-1)
                    if self.pixel1.red == 255 and self.pixel1.blue == 255 and self.pixel1.green == 255 and\
                       self.pixel2.red == 166 and self.pixel2.blue == 166 and self.pixel2.green == 166:
                        nuovepos[0] = self.x
                        nuovepos[1] = self.y - 32
                        self.pixel3 = screen.getPixel(self.x+15,self.y-1) #ud
                        if self.pixel3.red == 255:
                            prossima_direzione = 'su'
                        self.pixel3 = screen.getPixel(self.x+1,self.y-15) #bl
                        if self.pixel3.red == 255:
                            prossima_direzione = 'giu/sinistra'
                        self.pixel3 = screen.getPixel(self.x+30,self.y-15) #br
                        if self.pixel3.red == 255:
                            prossima_direzione = 'giu/destra'
                    else:
                        if self.vittoria != 1:
                            self.vittoria = 2
                        
            #tr 5 
            elif self.direzione == 'su/destra' and self.nvolte <= 31: # da su a destra Fatto
                for a in range(10):
                    bg.putPixel(self.x+11+a, self.y+self.nvolte, blu)
                for a in range(10):
                    bg.putPixel(self.x+self.nvolte, 11+self.y+a, blu)
                if self.nvolte == 31:
                    self.pixel1 = screen.getPixel(self.x+31+1,self.y+16)
                    self.pixel2 = screen.getPixel(self.x+31+1,self.y+1)
                    if self.pixel1.red == 255 and self.pixel1.blue == 255 and self.pixel1.green == 255 and\
                       self.pixel2.red == 166 and self.pixel2.blue == 166 and self.pixel2.green == 166:
                        nuovepos[0] = self.x + 32
                        nuovepos[1] = self.y 
                        self.pixel3 = screen.getPixel(self.x+32+1,self.y+15) #lr
                        if self.pixel3.red == 255:
                            prossima_direzione = 'destra'
                        self.pixel3 = screen.getPixel(self.x+32+16,self.y+1) #tl
                        if self.pixel3.red == 255:
                            prossima_direzione = 'sinistra/su'
                        self.pixel3 = screen.getPixel(self.x+32+16,self.y+30) #bl
                        if self.pixel3.red == 255:
                            prossima_direzione = 'sinistra/giu'
                    else:
                        if self.vittoria != 1:
                            self.vittoria = 2
            elif self.direzione == 'destra/su' and self.nvolte <= 31: # da destra a su Fatto
                for a in range(10):
                    bg.putPixel(self.x+31-self.nvolte, 11+self.y+a, blu)
                for a in range(10):
                    bg.putPixel(self.x+11+a, self.y+31-self.nvolte, blu)
                if self.nvolte == 31:
                    self.pixel1 = screen.getPixel(self.x+16,self.y-1)
                    self.pixel2 = screen.getPixel(self.x+1,self.y-1)
                    if self.pixel1.red == 255 and self.pixel1.blue == 255 and self.pixel1.green == 255 and\
                       self.pixel2.red == 166 and self.pixel2.blue == 166 and self.pixel2.green == 166:
                        nuovepos[0] = self.x 
                        nuovepos[1] = self.y - 32
                        self.pixel3 = screen.getPixel(self.x+16,self.y-1) #ud
                        if self.pixel3.red == 255:
                            prossima_direzione = 'su'
                        self.pixel3 = screen.getPixel(self.x+30,self.y-15) #br
                        if self.pixel3.red == 255:
                            prossima_direzione = 'giu/destra'
                        self.pixel3 = screen.getPixel(self.x+1,self.y-15) #bl
                        if self.pixel3.red == 255:
                            prossima_direzione = 'giu/sinistra'
                    else:
                        if self.vittoria != 1:
                            self.vittoria = 2
            #br 6
            elif self.direzione == 'giu/destra' and self.nvolte <= 31: # da giu a destra Fatto
                for a in range(10):
                    bg.putPixel(self.x+11+a, self.y+31-self.nvolte, blu)
                for a in range(10):
                    bg.putPixel(self.x+self.nvolte, 11+self.y+a, blu)
                if self.nvolte == 31:
                    self.pixel1 = screen.getPixel(self.x+32+1,self.y+16)
                    self.pixel2 = screen.getPixel(self.x+32+1,self.y+1)
                    if self.pixel1.red == 255 and self.pixel1.blue == 255 and self.pixel1.green == 255 and\
                       self.pixel2.red == 166 and self.pixel2.blue == 166 and self.pixel2.green == 166:
                        nuovepos[0] = self.x + 32
                        nuovepos[1] = self.y
                        self.pixel3 = screen.getPixel(self.x+32+1,self.y+16) #lr
                        if self.pixel3.red == 255:
                            prossima_direzione = 'destra'
                        self.pixel3 = screen.getPixel(self.x+32+16,self.y+1) #tl
                        if self.pixel3.red == 255:
                            prossima_direzione = 'sinistra/su'
                        self.pixel3 = screen.getPixel(self.x+32+16,self.y+30) #bl
                        if self.pixel3.red == 255:
                            prossima_direzione = 'sinistra/giu'
                    else:
                        if self.vittoria != 1:
                            self.vittoria = 2
            elif self.direzione == 'destra/giu' and self.nvolte <= 31: # da destra a giu Fatto
                for a in range(10):
                    bg.putPixel(self.x+31-self.nvolte, 11+self.y+a, blu)
                for a in range(10):
                    bg.putPixel(self.x+11+a, self.y+self.nvolte, blu)
                if self.nvolte == 31:
                    self.pixel1 = screen.getPixel(self.x+16,self.y+32+1)
                    self.pixel2 = screen.getPixel(self.x+1,self.y+32+1)
                    if self.pixel1.red == 255 and self.pixel1.blue == 255 and self.pixel1.green == 255 and\
                       self.pixel2.red == 166 and self.pixel2.blue == 166 and self.pixel2.green == 166:
                        nuovepos[0] = self.x 
                        nuovepos[1] = self.y + 32
                        self.pixel3 = screen.getPixel(self.x+16,self.y+32+1) #ud
                        if self.pixel3.red == 255:
                            prossima_direzione = 'giu'
                        self.pixel3 = screen.getPixel(self.x+30,self.y+32+16) #tr
                        if self.pixel3.red == 255:
                            prossima_direzione = 'su/destra'
                        self.pixel3 = screen.getPixel(self.x+1,self.y+32+16) #tl
                        if self.pixel3.red == 255:
                            prossima_direzione = 'su/sinistra'
                    else:
                        if self.vittoria != 1:
                            self.vittoria = 2

            #bl 3 
            elif self.direzione == 'giu/sinistra' and self.nvolte <= 31: # da giu a sinistra Fatto
                for a in range(10):
                    bg.putPixel(self.x+11+a, self.y+31-self.nvolte, blu)
                for a in range(10):
                    bg.putPixel(self.x+31-self.nvolte, 11+self.y+a, blu)
                if self.nvolte == 31:
                    self.pixel1 = screen.getPixel(self.x-1,self.y+16)
                    self.pixel2 = screen.getPixel(self.x-1,self.y+1)
                    if self.pixel1.red == 255 and self.pixel1.blue == 255 and self.pixel1.green == 255 and\
                       self.pixel2.red == 166 and self.pixel2.blue == 166 and self.pixel2.green == 166:
                        nuovepos[0] = self.x - 32
                        nuovepos[1] = self.y 
                        self.pixel3 = screen.getPixel(self.x-1,self.y+16) #lr
                        if self.pixel3.red == 255:
                            prossima_direzione = 'sinistra'
                        self.pixel3 = screen.getPixel(self.x-16,self.y+30) #br
                        if self.pixel3.red == 255:
                            prossima_direzione = 'destra/giu'
                        self.pixel3 = screen.getPixel(self.x-16,self.y+1) #tr
                        if self.pixel3.red == 255:
                            prossima_direzione = 'destra/su'
                    else:
                        if self.vittoria != 1:
                            self.vittoria = 2
            elif self.direzione == 'sinistra/giu' and self.nvolte <= 31: # da sinistra a giu
                for a in range(10):
                    bg.putPixel(self.x+self.nvolte, 11+self.y+a, blu)
                for a in range(10):
                    bg.putPixel(self.x+11+a, self.y+self.nvolte, blu)
                if self.nvolte == 31:
                    self.pixel1 = screen.getPixel(self.x+16,self.y+32+1)
                    self.pixel2 = screen.getPixel(self.x+1,self.y+32+1)
                    if self.pixel1.red == 255 and self.pixel1.blue == 255 and self.pixel1.green == 255 and\
                       self.pixel2.red == 166 and self.pixel2.blue == 166 and self.pixel2.green == 166:
                        nuovepos[0] = self.x 
                        nuovepos[1] = self.y + 32
                        self.pixel3 = screen.getPixel(self.x+16,self.y+32+1) #ud
                        if self.pixel3.red == 255:
                            prossima_direzione = 'giu'
                        self.pixel3 = screen.getPixel(self.x+30,self.y+32+16) #tr
                        if self.pixel3.red == 255:
                            prossima_direzione = 'su/destra'
                        self.pixel3 = screen.getPixel(self.x+1,self.y+32+16) #tl
                        if self.pixel3.red == 255:
                            prossima_direzione = 'su/sinistra'
                    else:
                        if self.vittoria != 1:
                            self.vittoria = 2
            self.nvolte += 1
            
class Control(Blocco):
    ''' Classe adibita al controllo dei blocchi. '''
    def __init__(self, list_blocks):
        self.b = list_blocks
        self.pos = [32,0]
        self.pausa = False
    def Update(self):
        if self.pausa == False:
            if pad.down and not oldpad.down and self.pos[1] != 256-32: self.pos[1] += 32
            elif pad.up and not oldpad.up and self.pos[1] != 0: self.pos[1] -= 32
            elif pad.left and not oldpad.left and self.pos[0] != 32: self.pos[0] -= 32
            elif pad.right and not oldpad.right and self.pos[0] != 256: self.pos[0] += 32
        if pad.start and not oldpad.start and self.pausa == True: self.pausa = False
        elif pad.start and not oldpad.start and self.pausa == False: self.pausa = True
        
        for elemento in self.b:
            if elemento.n != 8 and elemento.n != 9 and elemento.x == self.pos[0] and elemento.y == self.pos[1] and screen.getPixel(self.pos[0]+16,self.pos[1]+16).red == 255:
                if pad.square and self.pos[0] != 32 and not oldpad.square and self.pos[0] != 0 and screen.getPixel(elemento.x-5,elemento.y+5).red == 255: 
                    elemento.x -= 32; self.pos[0] -= 32
                elif pad.circle and self.pos[0] != 256 and not oldpad.circle and self.pos[0] != 256+32 and screen.getPixel(elemento.x+32+5,elemento.y+5).red == 255: 
                    elemento.x += 32; self.pos[0] += 32
                elif pad.triangle and self.pos[1] != 0 and not oldpad.triangle and self.pos[1] != 0 and screen.getPixel(elemento.x+5,elemento.y-5).red == 255:
                    elemento.y -= 32; self.pos[1] -= 32
                elif pad.cross and self.pos[1] != 256-32 and not oldpad.cross and self.pos[1] != 256+32 and screen.getPixel(elemento.x+5,elemento.y+32+5).red == 255:
                    elemento.y += 32; self.pos[1] += 32

class Rand(object):
    ''' Randomizza la posizione dei blocchi '''
    def __init__(self):
        self.b = []
        self.xd = []; self.yd = []
        self.iniziox = 32+randint(0,7)*32
        self.inizioy = randint(0,6)*32
        self.b.append(Blocco(8, self.iniziox, self.inizioy))
        self.finex = 32+randint(0,7)*32
        self.finey = randint(0,6)*32
        while self.finey == self.inizioy + 32:
            self.finey = randint(0,6)*32
        self.b.append(Blocco(9, self.finex, self.finey))
        self.a = 0
        self.bg_prova = psp2d.Image('bg.png')
        self.bg_prova.blit(images[8], 0, 0, images[8].width, images[8].height, self.iniziox, self.inizioy, True)
        self.bg_prova.blit(images[9], 0, 0, images[9].width, images[9].height, self.finex, self.finey, True)
        while self.a < 36:
            self.x = 32+randint(0,7)*32
            self.y = randint(0,7)*32
            if self.bg_prova.getPixel(self.x+1,self.y+1).red != 166:
                self.tipo = randint(1,6)
                self.bg_prova.blit(images[self.tipo], 0, 0, images[self.tipo].width, images[self.tipo].height, self.x, self.y, True)
                self.b.append(Blocco(self.tipo,self.x,self.y))
                self.a += 1
        
objrand = Rand()
b = objrand.b

control = Control(b)

menu = 0
scelta = 0

timer = 200
partenza = 0
vittoria = 0

oldpad = psp2d.Controller()
while True:
    pad = psp2d.Controller()
    if menu == 1:
        screen.blit(bg, 0, 0, bg.width, bg.height, 0, 0, True)

        for i in range(len(b)):
            b[i].draw()

        if timer == 20:
            partenza = 1
        if partenza == 1 and vittoria != 1 and vittoria != 2:
            b[0].showProgress()

            if control.pausa == False:
                for elemento in b:
                    if elemento.x == nuovepos[0] and elemento.y == nuovepos[1]:
                        elemento.direzione = prossima_direzione
                        elemento.showProgress()
                        if elemento.vittoria == 1:
                            vittoria = 1
                        elif elemento.vittoria == 2:
                            vittoria = 2
            
        for i in range(8):
            for ii in range(8):
                screen.blit(cornice[1], 0, 0, cornice[1].width, cornice[1].height, 32+ii*32, i*32, True)
                    
        screen.blit(cornice[0], 0, 0, cornice[0].width, cornice[0].height, control.pos[0], control.pos[1], True)

        control.Update()

        if partenza != 1 and vittoria == 0:
            if control.pausa == False:
                timer -= 1
            font.drawText(screen, 450, 10, str(timer/20))
        if partenza == 1 and vittoria != 1:
            font.drawText(screen, 410, 10, 'GO!')
        if vittoria == 1:
            font.drawText(screen, 150, 272/2-20, 'YOU WON!')
            if pad.start and not oldpad.start:
                bg = psp2d.Image('bg.png')
                prossima_direzione = 'giu'
                timer = 200
                partenza = 0
                objrand = Rand()
                b = objrand.b
                control = Control(b)
                game = 0
                vittoria = 0
                menu = 0
                nuovepos = [0,0]
                time.sleep(2)
        if vittoria == 2:
            font.drawText(screen, 150, 272/2-20, 'YOU LOSE!')
            if pad.start and not oldpad.start:
                bg = psp2d.Image('bg.png')
                prossima_direzione = 'giu'
                timer = 200
                partenza = 0
                objrand = Rand()
                b = objrand.b
                control = Control(b)
                game = 0
                vittoria = 0
                menu = 0
                nuovepos = [0,0]
                time.sleep(2)

        if control.pausa == True:
            screen.blit(pauseimg,0,0,480,272,0,0,True)
        
    elif menu == 0:
        screen.blit(menuimg[scelta], 0, 0, menuimg[scelta].width, menuimg[scelta].height, 0, 0, True)
        if pad.up: scelta = 0
        elif pad.down: scelta = 1
        elif pad.cross and scelta == 0:
            menu = 1
            time.sleep(0.5)
        elif pad.cross and scelta == 1:
            break
        
    oldpad = pad
    screen.swap()
