# -*- coding: latin-1 -*-

import random
import time

from PySide import QtCore, QtGui

from Code.Traducir import tr

import Code.Configuracion as Configuracion
import Code.ControlPosicion as ControlPosicion

import QTUtil2
import Colocacion
import Iconos
import Controles

import Tablero

#==========================================================================================================================================
class WDatos( QtGui.QDialog ):

    #--------------------------------------------------------------------------------------------------------------------------------
    def __init__(self, wParent, txtcategoria, maxNivel )  :
        super(WDatos, self).__init__(wParent)

        self.setWindowTitle( tr( "MEMORIA" ) )
        self.setWindowIcon( Iconos.Memoria() )
        self.setWindowFlags( QtCore.Qt.Dialog | QtCore.Qt.WindowTitleHint )

        tb = QTUtil2.creaTBAceptarCancelar( self )

        f = Controles.TipoLetra( puntos=12, peso = 75 )

        self.ed, lb = QTUtil2.spinBoxLB( maxNivel, 1, maxNivel, etiqueta = txtcategoria + " " + tr( "NIVEL" ), maxTam=40 )
        lb.ponFuente( f )

        ly = Colocacion.H().control( lb ).control( self.ed ).margen( 20 )

        layout = Colocacion.V().control( tb ).otro( ly ).margen(3)

        self.setLayout( layout )

    #--------------------------------------------------------------------------------------------------------------------------------
    def procesarTB( self ) :
        accion = self.sender().clave
        if accion == "aceptar" :
            self.nivel = self.ed.value()
            self.accept()
        elif accion == "cancelar" :
            self.reject()

# --------------------------------------------------------------------------------------------------------
def paramMemoria( parent, txtCategoria, maxNivel  ) :
    if maxNivel == 1 :
        return 1

    # Datos
    w = WDatos( parent, txtCategoria, maxNivel )
    if w.exec_() :
        return w.nivel
    else :
        return None

#==========================================================================================================================================

#==========================================================================================================================================
class WMemoria( QtGui.QDialog ):

    def __init__( self, procesador, txtcategoria, nivel, segundos, listaFen, record ) :

        super(WMemoria, self).__init__(procesador.pantalla)

        self.setWindowFlags( QtCore.Qt.Dialog | QtCore.Qt.WindowTitleHint )

        f = Controles.TipoLetra( puntos=10, peso = 75 )

        self.configuracion = procesador.configuracion
        self.nivel = nivel
        self.segundos = segundos
        self.record = record

        self.setWindowTitle( tr( "MEMORIA" ) )
        self.setWindowIcon( Iconos.Memoria() )

        # Tablero
        confTablero = Configuracion.ConfigTablero()
        confTablero.lee( self.configuracion.cTableroN.graba() )
        confTablero.anchoPieza = 48

        self.listaFen = listaFen

        self.posicion = ControlPosicion.ControlPosicion()

        self.tablero = Tablero.PosTablero(self, confTablero)
        self.tablero.crea()
        self.ultimaPieza = "P"

        # Ayuda
        lbAyuda = Controles.LB( tr( "AYUDA_POSICION" ) )
        ly = Colocacion.H().control( lbAyuda )
        self.gbAyuda = Controles.GB( self, tr( "TIT_AYUDA" ), ly )

        self.gbAyuda.hide()

        # Rotulos información
        lbCategoria = Controles.LB( txtcategoria ).ponFuente( f )
        lbNivel = Controles.LB( tr( "MEMORIA_NIVEL", str(nivel+1), "25" ) ).ponFuente( f )
        if record :
            lbRecord = Controles.LB( tr( "MEMORIA_RECORD", str(record) ) ).ponFuente( f )

        # Rotulo de tiempo
        self.rotuloDispone = Controles.LB( tr( "MEMORIA_DISPONE", str(self.segundos), str(self.nivel+3) ) ).ponWrap().ponFuente( f ).alinCentrado()
        self.rotuloDispone1 = Controles.LB( tr( "MEMORIA_DISPONE1" ) ).ponWrap().ponFuente( f ).alinCentrado()
        ly = Colocacion.V().control( self.rotuloDispone ).control( self.rotuloDispone1 )
        self.gbTiempo = Controles.GB( self, "", ly )

        self.rotuloDispone1.hide()

        # Tool bar
        liAcciones = (
                        ( tr( "EMPEZAR" ), Iconos.TB_Empezar(), "empezar" ),
                        ( tr( "MEMORIA_SEGUIR" ), Iconos.Pelicula_Seguir(), "seguir" ),
                        ( tr( "MEMORIA_COMPROBAR" ), Iconos.TB_Tablas(), "comprobar" ),
                        ( tr( "MEMORIA_OBJETIVO" ), Iconos.Verde32(), "objetivo" ),
                        ( tr( "MEMORIA_NUESTRO" ), Iconos.Rojo32(), "nuestro" ),
                        ( tr( "MEMORIA_REPETIR" ), Iconos.Pelicula_Repetir(), "repetir" ),
                        ( tr( "TB_ABANDONAR" ), Iconos.TB_Abandonar(), "abandonar" ),
                    )
        self.tb = tb = Controles.TB( self, liAcciones )
        self.ponToolBar( [ "empezar" ] )

        # Colocamos
        ly = Colocacion.G()
        ly.control( self.tablero, 0, 0, 6, 1 )
        ly.control( tb, 0, 1, 1, 2 )
        ly.controlc( lbCategoria, 1, 1 )
        ly.controlc( lbNivel, 2, 1 )
        if record :
            ly.controlc( lbRecord, 3, 1 )
        ly.controlc( self.gbTiempo, 4, 1 )

        ly.control( self.gbAyuda, 5, 1 )

        self.setLayout( ly )

        self.timer = None

    #--------------------------------------------------------------------------------------------------------------------------------
    def mueve( self, desde, hasta ) :
        if desde == hasta :
            return
        if self.casillas[hasta] :
            self.tablero.borraPieza( hasta )
        self.casillas[hasta] = self.casillas[desde]
        self.casillas[desde] = None
        self.tablero.muevePieza( desde, hasta )

    #--------------------------------------------------------------------------------------------------------------------------------
    def borraCasilla( self, desde ) :
        self.casillas[desde] = None
        self.tablero.borraPieza( desde )

    #--------------------------------------------------------------------------------------------------------------------------------
    def creaCasilla( self, desde ) :
        menu = QtGui.QMenu(self)

        siK = False
        sik = False
        for p in self.casillas.itervalues() :
            if p == "K" :
                siK = True
            elif p == "k" :
                sik = True

        liOpciones = []
        if not siK :
            liOpciones.append( ( tr( "REY" ), "K") )
        liOpciones.extend( [ ( tr( "DAMA" ), "Q"), (tr( "TORRE" ), "R"), (tr( "ALFIL" ), "B"), (tr( "CABALLO" ), "N"), (tr( "PEON" ), "P")  ] )
        if not sik :
            liOpciones.append( ( tr( "REY" ), "k") )
        liOpciones.extend( [ ( tr( "DAMA" ), "q"), (tr( "TORRE" ), "r"), (tr( "ALFIL" ), "b"), (tr( "CABALLO" ), "n"), (tr( "PEON" ), "p") ] )

        for txt, pieza in liOpciones :

            icono = eval( "Iconos.%s_16c()"%pieza )

            accion = QtGui.QAction( icono, txt, menu )
            accion.clave = pieza
            menu.addAction( accion )

        resp = menu.exec_(QtGui.QCursor.pos())
        if resp :
            pieza = resp.clave
            antultimo = self.ultimaPieza
            self.ultimaPieza = pieza
            self.repitePieza( desde )
            if pieza == "K" :
                self.ultimaPieza = antultimo
            if pieza == "k" :
                self.ultimaPieza = antultimo
    #--------------------------------------------------------------------------------------------------------------------------------
    def repitePieza( self, desde ) :
        self.casillas[desde] = self.ultimaPieza
        pieza = self.tablero.creaPieza( self.ultimaPieza, desde )
        pieza.activa( True )

    #--------------------------------------------------------------------------------------------------------------------------------
    def procesarTB( self ) :
        accion = self.sender().clave
        if accion == "abandonar" :
            self.reject()
        elif accion == "empezar" :
            self.empezar()
        elif accion == "seguir" :
            self.seguir()
        elif accion == "comprobar" :
            self.comprobar()
        elif accion == "objetivo" :
            self.objetivo()
        elif accion == "nuestro" :
            self.nuestro()
        elif accion == "repetir" :
            self.repetir()

    #--------------------------------------------------------------------------------------------------------------------------------
    def ponToolBar( self, liAcciones ) :

        self.tb.clear()
        for k in liAcciones :
            self.tb.dicTB[k].setVisible( True )
            self.tb.dicTB[k].setEnabled( True )
            self.tb.addAction( self.tb.dicTB[k] )

        self.tb.liAcciones = liAcciones
        self.tb.update()

    #--------------------------------------------------------------------------------------------------------------------------------
    def empezar( self ) :
        # Ha pulsado empezar

        # Elegimos el fen de la lista
        nPos = random.randint( 0, len(self.listaFen )-1 )
        self.fenObjetivo = self.listaFen[nPos]
        del self.listaFen[nPos]
        self.posicion.leeFen( self.fenObjetivo )
        self.tablero.ponPosicion( self.posicion )
        self.tablero.desactivaTodas()
        self.casillas = self.posicion.casillas
        self.tablero.casillas = self.casillas

        # Quitamos empezar y ponemos seguir
        self.ponToolBar( [ "seguir" ] )

        self.rotuloDispone.ponTexto( tr( "MEMORIA_DISPONE", str(self.segundos), str(self.nivel+3) ) )
        self.rotuloDispone1.ponTexto( tr( "MEMORIA_DISPONE1" ) )
        self.rotuloDispone1.show()
        self.rotuloDispone1.show()
        self.gbTiempo.show()

        self.tiempoPendiente = self.segundos
        self.iniciaReloj()

    #--------------------------------------------------------------------------------------------------------------------------------
    def seguir( self ) :
        self.paraReloj()

        self.tablero.ponMensajero( self.mueve )
        self.tablero.mensBorrar = self.borraCasilla
        self.tablero.mensCrear = self.creaCasilla
        self.tablero.mensRepetir = self.repitePieza

        # Quitamos seguir y ponemos comprobar
        self.ponToolBar( [ "comprobar" ] )

        self.rotuloDispone1.ponTexto( tr( "MEMORIA_DISPONE2", str(self.nivel+3) ) )
        self.rotuloDispone.setVisible( False )

        self.iniTiempo = time.clock()

        for k in self.casillas :
            self.casillas[k] = None
        self.tablero.ponPosicion( self.posicion )

        self.gbAyuda.setVisible( True )

    #--------------------------------------------------------------------------------------------------------------------------------
    def comprobar( self ) :

        self.tiempo = int(time.clock() - self.iniTiempo)

        fenNuevo = self.posicion.fen()
        fenNuevo = fenNuevo[:fenNuevo.index(" ")]
        fenComprobar = self.fenObjetivo
        fenComprobar = fenComprobar[:fenComprobar.index(" ")]

        if fenComprobar == fenNuevo :
            mens = tr( "MEMORIA_CORRECTO", str(self.tiempo) )
            if self.tiempo < self.record or self.record == 0 :
                mens += "<br>" + tr( "MEMORIA_NUEVORECORD" )
            QTUtil2.mensaje( self, mens )
            self.accept()
            return

        QTUtil2.mensaje( self, tr( "MEMORIA_ERROR" ) )

        self.fenNuestro = self.posicion.fen()

        self.tablero.ponMensajero( None )
        self.tablero.mensBorrar = None
        self.tablero.mensCrear = None
        self.tablero.mensRepetir = None
        self.tablero.desactivaTodas()

        self.gbTiempo.hide()
        self.gbAyuda.hide()

        # Quitamos comprobar y ponemos el resto
        li = [ "objetivo", "nuestro" ]
        if len(self.listaFen ) :
            li.append( "repetir" )

        self.ponToolBar( li )

    #--------------------------------------------------------------------------------------------------------------------------------
    def objetivo( self ) :
        self.posicion.leeFen( self.fenObjetivo )
        self.tablero.ponPosicion( self.posicion )
        self.tablero.desactivaTodas()

    #--------------------------------------------------------------------------------------------------------------------------------
    def nuestro( self ) :
        self.posicion.leeFen( self.fenNuestro )
        self.tablero.ponPosicion( self.posicion )
        self.tablero.desactivaTodas()

    #--------------------------------------------------------------------------------------------------------------------------------
    def repetir( self ) :
        self.rotuloDispone.ponTexto( tr( "MEMORIA_DISPONE", str(self.segundos), str(self.nivel+3) ) )
        self.rotuloDispone.show()
        self.rotuloDispone1.hide()
        self.gbTiempo.show()

        self.empezar()
        #~ self.ponToolBar( [ "empezar" ] )

    #--------------------------------------------------------------------------------------------------------------------------------
    def reloj( self ) :
        self.tiempoPendiente -= 1

        self.rotuloDispone.ponTexto( tr( "MEMORIA_DISPONE", str(self.tiempoPendiente), str(self.nivel+3) ) )
        if self.tiempoPendiente == 0 :
            self.seguir()

    #--------------------------------------------------------------------------------------------------------------------------------
    def iniciaReloj( self ) :
        if self.timer is not None :
            self.timer.stop()
            del self.timer

        self.timer = QtCore.QTimer(self)
        self.connect(self.timer, QtCore.SIGNAL("timeout()"), self.reloj )
        self.timer.start(1000)

    #--------------------------------------------------------------------------------------------------------------------------------
    def paraReloj( self ) :
        if self.timer is not None :
            self.timer.stop()
            del self.timer
            self.timer = None

#==========================================================================================================================================
def lanzaMemoria( procesador, txtcategoria, nivel, segundos, listaFen, record ) :
    w = WMemoria( procesador, txtcategoria, nivel, segundos, listaFen, record )
    if w.exec_() :
        return w.tiempo
    else :
        return None
