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

from Code.Traducir import tr

import Partida
import Jugada
import MotorInterno

import QT.QTUtil as QTUtil
import QT.QTUtil2 as QTUtil2
import QT.PantallaAnalisis as PantallaAnalisis

#==========================================================================================================================================
class UnaMuestra():
    def __init__( self, owner, wowner, jg, xmotor, tiempo, fila, columna, numero ) :

        self.jg = jg
        self.fila = fila
        self.columna = columna

        siBase = (fila+columna)== 0
        if siBase and jg.analisis :
            mrm, pos = jg.analisis
        else :
            me = QTUtil2.mensEspera.inicio( wowner, tr("ANALIZANDO"), posicion = "ad" )
            mrm, pos = xmotor.analizaJugada(jg, tiempo)
            me.final()

        self.mrm = mrm
        self.posElegida = pos

        if siBase :
            jg.analisis = self.mrm, self.posElegida

        # Creamos la lista de movimientos analizados por el tutor
        self.listaRM = self.hazListaRM( ) # rm,nombre

        self.siMoviendoTiempo = False

        self.wmu = owner.w.creaMuestra( self, fila, columna, "%d_"%numero, self.listaRM, 0 )
        self.tablero = self.wmu.tablero

        self.tablero.exePulsadoNum = self.exePulsadoNum
        self.ml = MotorInterno.MotorInterno()

        self.owner = owner
        self.xmotor = xmotor

        self.cambiadoRM( self.posElegida )
        # self.wmu.setFocus()
        self.wmu.wrm.setFocus()
        QTUtil.xrefreshGUI()

    #-----------------------------------------------------------------------------------
    def cambiadoRM( self, pos ) :
        if not hasattr( self, "wmu" ) : # Puede llegar aquí desde gridCambiadoposicion
            return
        self.posRM = pos
        rm1 = self.listaRM[pos][0]

        self.partida = Partida.Partida(self.jg.posicionBase).leerPV(rm1.pv)

        puntuacion = rm1.texto()

        self.wmu.ponDatosRM( puntuacion, self.mrm.nombre, self.etiquetaTiempo(), self.pgnActual() )

        self.pos = 0
        self.max = len(self.partida.liJugadas)

        self.mueve(siInicio=True)

    #--------------------------------------------------------------------------------------------
    def etiquetaTiempo( self ) :
        if self.mrm.maxTiempo :
            t = "%0.2f"%(float(self.mrm.maxTiempo) /1000.0,)
            while True :
                if t[-1] == "0" :
                    t = t[:-1]
                else :
                    if t[-1] == "." :
                        t = t[:-1]
                    break

            etiT = "%s : %s"%( tr( "SEGUNDOS" ), t )
            if self.mrm.depth :
                etiT += "  -  %s : %d"%( tr( "PROFUNDIDAD" ), self.mrm.depth )
        else :
            etiT = ""
        return etiT

    #--------------------------------------------------------------------------------------------
    def hazListaRM( self ) :
        li = []
        pb = self.jg.posicionBase
        siElegido = True
        for rm in self.mrm.liMultiPV :
            pv1 = rm.pv.split(" ")[0]
            desde = pv1[:2]
            hasta = pv1[2:4]
            coronacion = pv1[4] if len(pv1)==5 else None

            nombre = pb.pgnSP( desde, hasta, coronacion )
            mate = rm.mate
            if mate :
                nombre += " (M%d)"%mate
            else :
                nombre += " (%d %s)"%(rm.puntos, tr( "ABREV_PUNTOS") )
            li.append( (rm, nombre, rm.puntosABS(), siElegido) )
            siElegido = False

        return li

    #-----------------------------------------------------------------------------------
    def grabarBase(self, partida, rm ):
        puntuacion = rm.texto()
        jugada = partida.pgnBase(self.owner.posJugada/2+1)
        nombre = self.mrm.nombre
        comentario = " {%s %s %s} "%( puntuacion, nombre, self.etiquetaTiempo() )
        li = jugada.split( " " )
        n = 1 if self.jg.posicionBase.siBlancas else 2
        variante = (" ".join(li[:n]) + comentario + " ".join(li[n:])).replace( "\n", "" ).strip()
        variantes = self.jg.variantes
        if variantes :
            if variante in variantes : # Sin repetidos
                return
            variantes = variantes.strip() + "\n\n" + variante
        else :
            variantes = variante
        self.jg.variantes = variantes

    #-----------------------------------------------------------------------------------
    def grabar(self):
        self.grabarBase( self.partida, self.listaRM[self.posRM][0] )
        self.owner.procesador.gestor.ponVista()

    #-----------------------------------------------------------------------------------
    def grabarTodos(self):
        for pos,tp in enumerate(self.listaRM) :
            rm = tp[0]
            partida = Partida.Partida(self.jg.posicionBase).leerPV(rm.pv)
            self.grabarBase(partida,rm)
        self.owner.procesador.gestor.ponVista()

    #-----------------------------------------------------------------------------------
    def pgnActual(self):
        return self.partida.pgnSP(self.owner.posJugada/2+1)

    #-----------------------------------------------------------------------------------
    def saltaPGN(self, jugada ):
        self.pos = jugada
        jg = self.partida.liJugadas[self.pos]
        self.tablero.ponPosicion(jg.posicion)
        self.tablero.ponFlechaSC(jg.desde, jg.hasta)

    #-----------------------------------------------------------------------------------
    def mueve(self, siInicio = False, nSaltar=0, siFinal = False, siBase = False):
        if nSaltar:
            pos = self.pos + nSaltar
            if pos >= 0 and pos < self.max:
                self.pos = pos
            else:
                return
        elif siInicio :
            self.pos = 0
        elif siBase:
            self.pos = -1
        elif siFinal:
            self.pos = self.max - 1
        if len(self.partida.liJugadas) :
            jg = self.partida.liJugadas[self.pos if self.pos > -1 else 0 ]
            if siBase :
                self.tablero.ponPosicion(jg.posicionBase)
            else:
                self.tablero.ponPosicion(jg.posicion)
                self.tablero.ponFlechaSC(jg.desde, jg.hasta)

    #-----------------------------------------------------------------------------------
    def mueveTiempo(self):
        if self.siMoviendoTiempo :
            self.siMoviendoTiempo = False
            self.tiempoOtrosTB( True )
            self.owner.w.paraReloj()
            return

        def otrosTB( siHabilitar ) :
            for accion in self.wmu.tb.liAcciones :
                if not accion.clave.endswith("MoverTiempo") :
                    accion.setEnabled( siHabilitar )

        self.tiempoFuncion = self.mueve
        self.tiempoPosMax = self.max
        self.tiempoPos = -1
        self.tiempoOtrosTB = otrosTB
        self.siMoviendoTiempo = True
        otrosTB( False )
        self.mueve( siBase = True )
        self.owner.w.iniciaReloj( self.mueveTiempo1 )

    #-----------------------------------------------------------------------------------
    def mueveTiempo1( self ) :
        self.tiempoPos += 1
        if self.tiempoPos == self.tiempoPosMax :
            self.siMoviendoTiempo = False
            self.tiempoOtrosTB( True )
            self.owner.w.paraReloj()
            return
        if self.tiempoPos == 0 :
            self.tiempoFuncion( siInicio = True )
        else :
            self.tiempoFuncion( nSaltar = 1 )

    #-----------------------------------------------------------------------------------
    def analizaExterior(self):
        jg = self.partida.liJugadas[self.pos]
        rm = self.listaRM[self.posRM][0]
        pts = rm.texto()
        AnalisisVariantes(self.owner.w, self.xmotor, self.owner.confTablero, jg, self.owner.siBlancas, pts, maxRecursion = self.owner.maxRecursion)

    #--------------------------------------------------------------------------------------------------------------------------------
    def ponFlechas( self, fen, siMB, siMovimientos ) :
        self.ml.ponFen( fen )
        self.ml.calculaEstado()
        if siMovimientos :
            li = self.ml.listaMovimientos() if siMB else self.ml.listaMovimientosOB()
        else :
            li = self.ml.listaCapturas( siMB )

        self.tablero.quitaFlechas()
        if self.tablero.flechaSC :
            self.tablero.flechaSC.hide()
        for m in li :
            pv = m.pv()
            d = pv[:2]
            h = pv[2:4]
            self.tablero.creaFlechaMov( d, h, "m" if siMovimientos else "c" )

    #--------------------------------------------------------------------------------------------------------------------------------
    def exePulsadoNum( self, siIzq, siActivar, numero  ) :
        if numero in [1,8] :
            if siActivar :
                # Que jugada está en el tablero
                jg = self.partida.liJugadas[self.pos if self.pos > -1 else 0 ]
                if self.pos == -1 :
                    fen = jg.posicionBase.fen()
                else:
                    fen = jg.posicion.fen()
                siBlancas = " w " in fen
                if siBlancas :
                    siMB = numero == 1
                else :
                    siMB = numero == 8
                self.ponFlechas( fen, siMB, siIzq )
            else :
                self.tablero.quitaFlechas()
                if self.tablero.flechaSC :
                    self.tablero.flechaSC.show()

#==========================================================================================================================================
class MuestraAnalisis():
    def __init__(self, procesador, xtutor, jg, siBlancas, maxRecursion, posJugada, pantalla = None, siGrabar = True):

        self.xtutor = xtutor
        self.procesador = procesador
        self.configuracion = procesador.configuracion
        self.confTablero = self.configuracion.cTableroT
        self.jg = jg
        self.siBlancas = siBlancas
        self.posJugada = posJugada # Para mostrar el pgn con los números correctos

        self.siMoviendoTiempo = False

        siLibre = maxRecursion > 0
        self.maxRecursion = maxRecursion

        pantalla = procesador.pantalla if pantalla is None else pantalla

        self.w = PantallaAnalisis.WAnalisis(self, pantalla, self.confTablero, self.siBlancas, siLibre, siGrabar)

        mu = UnaMuestra( self, pantalla, jg, self.xtutor, self.xtutor.motorTiempoJugada, 0, 0, 0 )

        mu.fila = 0
        mu.columna = 0

        self.liMuestras = [mu,]

        self.w.exec_()
        for uno in self.liMuestras :
            xmotor = uno.xmotor
            if xmotor.clave != xtutor.clave :
                xmotor.terminar()

    #-----------------------------------------------------------------------------------
    def procesarTB(self, accion):
        li = accion.split("_")
        accion = li[1]
        numero = int(li[0])
        mu = self.liMuestras[numero]
        if accion == "MoverAdelante":
            mu.mueve(nSaltar = 1)
        elif accion == "MoverAtras":
            mu.mueve(nSaltar = -1)
        elif accion == "MoverInicio":
            mu.mueve(siBase = True)
        elif accion == "MoverFinal":
            mu.mueve(siFinal = True)
        elif accion == "MoverLibre":
            mu.analizaExterior()
        elif accion == "MoverTiempo":
            mu.mueveTiempo()
        elif accion == "MoverMas":
            self.mueveMas(numero)
        elif accion == "MoverGrabar":
            mu.grabar()
        elif accion == "MoverGrabarTodos":
            mu.grabarTodos()

    #-----------------------------------------------------------------------------------
    def saltaPGN(self, numero, jugada ):
        mu = self.liMuestras[numero]
        mu.saltaPGN( jugada )
    #-----------------------------------------------------------------------------------
    def mueveMas(self, numero):
        mu = self.liMuestras[numero]
        fila = mu.fila
        columna = mu.columna
        # Hay alguien a la derecha
        f = fila
        c = columna+1
        siD = False
        for una in self.liMuestras :
            if una.fila == f and una.columna == c :
                siD = True
                break
        if siD :
            # Hay alguien abajo
            f = fila +1
            c = columna
            siA = False
            for una in self.liMuestras :
                if una.fila == f and una.columna == c :
                    siA = True
                    break
            if siA :
                for accion in mu.wmu.tb.liAcciones :
                    if accion.clave.endswith("MoverMas") :
                        accion.setEnabled( False )
                return

        resp = PantallaAnalisis.paramAnalisis( self.w, self.configuracion, False  )
        if resp is None:
            return

        if siD :
            for accion in mu.wmu.tb.liAcciones :
                if accion.clave.endswith("MoverMas") :
                    accion.setEnabled( False )

        claveMotor, tiempo = resp
        xmotor = None
        for mu in self.liMuestras :
            if mu.xmotor.clave == claveMotor :
                xmotor = mu.xmotor
                break
        if xmotor is None :
            confMotor = self.configuracion.buscaMotor( claveMotor )
            xmotor = self.procesador.creaGestorMotor( None, confMotor, tiempo, None, siMultiPV = True )

        mu = UnaMuestra( self, self.w, self.jg, xmotor, tiempo, f, c, len(self.liMuestras) )

        self.liMuestras.append( mu )

        QTUtil.xrefreshGUI()

#==========================================================================================================================================
class AnalisisVariantes():
    def __init__(self, owner, xtutor, confTablero, jg, siBlancas, cPuntosBase, maxRecursion = 100000):

        self.owner = owner
        self.xtutor = xtutor
        self.confTablero = confTablero
        self.jg = jg
        self.siBlancas = siBlancas
        self.posicionBase = jg.posicionBase
        self.siMoviendoTiempo = False

        self.rm = None

        if self.xtutor.motorTiempoJugada :
            segundosPensando = self.xtutor.motorTiempoJugada/1000  # está en milésimas
            if self.xtutor.motorTiempoJugada%1000 > 0:
                segundosPensando += 1
        else :
            segundosPensando = 3

        self.w = PantallaAnalisis.WAnalisisVariantes(self, self.owner, segundosPensando, self.confTablero, self.siBlancas, cPuntosBase, maxRecursion)
        self.reset()
        self.w.exec_()

    #-----------------------------------------------------------------------------------
    def reset(self):
        self.tableroTutor = self.w.tableroT
        self.w.tablero.ponPosicion(self.posicionBase)
        self.w.tablero.ponFlechaSC(self.jg.desde, self.jg.hasta)
        self.w.tablero.ponMensajero(self.mueveHumano)
        self.w.tablero.activaColor(not self.jg.posicion.siBlancas)

    #-----------------------------------------------------------------------------------
    def mueveHumano(self, desde, hasta, coronacion = None ):
        movimiento = desde + hasta

        # Peón coronando
        if not coronacion and self.posicionBase.siPeonCoronando(desde, hasta) :
            coronacion = self.w.tablero.peonCoronando(not self.jg.posicion.siBlancas)
            if coronacion is None:
                return False
        if coronacion :
            movimiento += coronacion

        siBien, mens, jgNueva = Jugada.dameJugada(self.posicionBase, desde, hasta, coronacion)

        if siBien:

            self.movimientosPiezas(jgNueva.liMovs)
            self.w.tablero.ponFlechaSC(jgNueva.desde, jgNueva.hasta)
            self.analizaJugada(jgNueva)
            return True
        else:
            return False

    #-----------------------------------------------------------------------------------
    def analizaJugada(self, jgNueva):
        me = QTUtil2.mensEspera.inicio(self.w, tr("ANALIZANDO"))

        secs = self.w.dameSegundos()
        self.rm = self.xtutor.analizaVariante( jgNueva, secs*1000, self.siBlancas )
        me.final()

        self.partidaTutor = Partida.Partida(jgNueva.posicion).leerPV(self.rm.pv)

        if len(self.partidaTutor.liJugadas) :
            self.w.tableroT.ponPosicion(self.partidaTutor.liJugadas[0].posicion)

        self.w.ponPuntuacion(self.rm.texto())

        self.posTutor = 0
        self.maxTutor = len(self.partidaTutor.liJugadas)

        self.mueveTutor(siInicio = True)

    #-----------------------------------------------------------------------------------
    def movimientosPiezas(self, liMovs):
        """
        Hace los movimientos de piezas en el tablero
        """
        for movim in liMovs:
            if movim[0] == "b":
                self.w.tablero.borraPieza(movim[1])
            elif movim[0] == "m":
                self.w.tablero.muevePieza(movim[1], movim[2])
            elif movim[0] == "c":
                self.w.tablero.cambiaPieza(movim[1], movim[2])

        self.w.tablero.desactivaTodas()

        self.w.tablero.escena.update()
        self.w.update()
        QTUtil.xrefreshGUI()

    #-----------------------------------------------------------------------------------
    def procesarTB(self, accion, maxRecursion):
        if self.rm:
            if accion == "MoverAdelante":
                self.mueveTutor(nSaltar=1)
            elif accion == "MoverAtras":
                self.mueveTutor(nSaltar=-1)
            elif accion == "MoverInicio":
                self.mueveTutor(siInicio = True)
            elif accion == "MoverFinal":
                self.mueveTutor(siFinal = True)
            elif accion == "MoverTiempo":
                self.mueveTiempo()
            elif accion.endswith("MoverLibre"):
                self.analizaExterior(maxRecursion)

    #-----------------------------------------------------------------------------------
    def mueveTutor(self, siInicio = False, nSaltar=0, siFinal = False, siBase = False):
        if nSaltar:
            pos = self.posTutor + nSaltar
            if pos >= 0 and pos < self.maxTutor:
                self.posTutor = pos
            else:
                return
        elif siInicio or siBase:
            self.posTutor = 0
        elif siFinal:
            self.posTutor = self.maxTutor-1
        if self.partidaTutor.numJugadas() :
            jg = self.partidaTutor.liJugadas[self.posTutor]
            if siBase:
                self.tableroTutor.ponPosicion(jg.posicionBase)
            else:
                self.tableroTutor.ponPosicion(jg.posicion)
                self.tableroTutor.ponFlechaSC(jg.desde, jg.hasta)
        self.tableroTutor.escena.update()
        self.w.update()
        QTUtil.xrefreshGUI()

    #-----------------------------------------------------------------------------------
    def mueveTiempo(self):
        if self.siMoviendoTiempo :
            self.siMoviendoTiempo = False
            self.tiempoOtrosTB( True )
            self.w.paraReloj()
            return

        def otrosTB( siHabilitar ) :
            for accion in self.w.tb.liAcciones :
                if not accion.clave.endswith("MoverTiempo") :
                    accion.setEnabled( siHabilitar )

        self.tiempoFuncion = self.mueveTutor
        self.tiempoPosMax = self.maxTutor
        self.tiempoPos = -1
        self.tiempoOtrosTB = otrosTB
        self.siMoviendoTiempo = True
        otrosTB( False )
        self.mueveTutor( siBase = True )
        self.w.iniciaReloj( self.mueveTiempo1 )

    #-----------------------------------------------------------------------------------
    def mueveTiempo1( self ) :
        self.tiempoPos += 1
        if self.tiempoPos == self.tiempoPosMax :
            self.siMoviendoTiempo = False
            self.tiempoOtrosTB( True )
            self.w.paraReloj()
            return
        if self.tiempoPos == 0 :
            self.tiempoFuncion( siInicio = True )
        else :
            self.tiempoFuncion( nSaltar = 1 )

    #-----------------------------------------------------------------------------------
    def analizaExterior(self, maxRecursion):
        jg = self.partidaTutor.liJugadas[self.posTutor]
        pts = self.rm.texto()
        AnalisisVariantes(self.w, self.xtutor, self.confTablero, jg, self.siBlancas, pts, maxRecursion)
