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

import XMotor
import XMotorRespuesta

# ---------------------------------------------------------------------------------------------
class GestorMotor :

    # -----------------------------------------------------------------------------------------
    def __init__( self, procesador, confMotor ) :
        self.procesador = procesador

        self.siIniMotor = False
        self.confMotor = confMotor
        self.nombre = confMotor.nombre
        self.clave = confMotor.clave
        self.siMultiPV = False
        self.siMaximizaMultiPV = False

        self.dispatch = None

    # -----------------------------------------------------------------------------------------
    def opciones( self, tiempoJugada, profundidad, siMultiPV ) :
        self.motorTiempoJugada = tiempoJugada
        self.motorProfundidad = profundidad
        self.siMultiPV = siMultiPV

        self.siInfinito = (self.clave == "tarrasch") and not tiempoJugada

        if self.clave == "daydreamer" and profundidad and profundidad == 1 :
            self.motorProfundidad = 2

    # -----------------------------------------------------------------------------------------
    def maximizaMultiPV( self ) :
        self.siMaximizaMultiPV = True

    # -----------------------------------------------------------------------------------------
    def iniciarMotor( self ) :
        self.siIniMotor = True

        nMultiPV = 0
        if self.siMultiPV :
            nMultiPV = self.confMotor.multiPV
        exe = self.confMotor.ejecutable()
        liUCI = self.confMotor.liUCI
        self.motor = XMotor.XMotor( self.nombre, exe, liUCI, nMultiPV, siMaximizaMultiPV = self.siMaximizaMultiPV )
        if self.confMotor.siDebug :
            self.motor.siDebug = True
            self.motor.nomDebug = self.confMotor.nomDebug

    # -----------------------------------------------------------------------------------------
    def juega( self, nAjustado=0 ) :
        if not self.siIniMotor :
            self.iniciarMotor()
        fen = self.procesador.gestor.partida.fenActual()

        if self.siInfinito : # problema tarrasch
            rmr = self.motor.mejorMovInfinito(fen, self.motorProfundidad )

        else :
            rmr = self.motor.mejorMov(fen, self.motorTiempoJugada, self.motorProfundidad )

        if nAjustado :
            rmr.partida = self.procesador.gestor.partida
            if nAjustado >= 1000 :
                rmr.liPersonalidades = self.procesador.configuracion.liPersonalidades
                rmr.fenBase = fen
            return rmr.mejorMovAjustado(nAjustado)
        else :
            return rmr.mejorMov()

    # -----------------------------------------------------------------------------------------
    def juegaTiempo( self, tiempoBlancas, tiempoNegras, tiempoJugada, nAjustado=0 ) :
        if self.motorTiempoJugada or self.motorProfundidad :
            return self.juega(nAjustado)
        if not self.siIniMotor :
            self.iniciarMotor()
        tiempoBlancas = int(tiempoBlancas*1000)
        tiempoNegras = int(tiempoNegras*1000)
        tiempoJugada = int(tiempoJugada*1000)
        fen = self.procesador.gestor.partida.fenActual()
        rmr = self.motor.mejorMovTiempo( fen, tiempoBlancas, tiempoNegras, tiempoJugada )
        if nAjustado :
            rmr.partida = self.procesador.gestor.partida
            if nAjustado >= 1000 :
                rmr.liPersonalidades = self.procesador.configuracion.liPersonalidades
                rmr.fenBase = fen
            return rmr.mejorMovAjustado(nAjustado)
        else :
            return rmr.mejorMov()

    # -----------------------------------------------------------------------------------------
    def analiza( self, fen ) :
        if not self.siIniMotor :
            self.iniciarMotor()
        return self.motor.mejorMov(fen, self.motorTiempoJugada,  self.motorProfundidad )

    # -----------------------------------------------------------------------------------------
    def valora( self, posicion, desde, hasta, coronacion ) :
        if not self.siIniMotor :
            self.iniciarMotor()
        if not hasattr( self, "ml" ) :
            self.ml = self.procesador.gestor.ml

        posicionNueva = posicion.copia()
        posicionNueva.mover( desde, hasta, coronacion )

        fen = posicionNueva.fen()
        self.ml.ponFen( fen )

        if self.ml.siTerminada() :
            return None

        mrm = self.motor.mejorMov(fen, self.motorTiempoJugada,  None )
        rm = mrm.mejorMov()
        rm.cambiaColor(posicion)
        return rm

    # -----------------------------------------------------------------------------------------
    def control( self, fen, profundidad ) :
        if not self.siIniMotor :
            self.iniciarMotor()

        return self.motor.mejorMov(fen, 0,  profundidad )

    # -----------------------------------------------------------------------------------------
    def terminar( self ) :
        if self.siIniMotor :
            self.motor.apagar()
            self.siIniMotor = False # necesario si se quiere reusar

    # -----------------------------------------------------------------------------------------
    def analizaJugada( self, jg, tiempo ) :
        if not self.siIniMotor :
            self.iniciarMotor()

        mrm =  self.motor.mejorMov( jg.posicionBase.fen(), tiempo, None )
        rm, n = mrm.buscaRM(jg.movimiento())
        if rm :
            return mrm, n

        # No está considerado, obliga a hacer el análisis de nuevo desde posicion
        if jg.siJaqueMate or jg.siTablas() :
            rm = XMotorRespuesta.RespuestaMotor( self.nombre )
        else :
            posicion = jg.posicion

            mrm1 =  self.motor.mejorMov( posicion.fen(), tiempo, None )
            mov = jg.movimiento()
            if mrm1.liMultiPV :
                rm = mrm1.liMultiPV[0]
                rm.cambiaColor(posicion)
                rm.pv = mov + " " + rm.pv
            else :
                rm = XMotorRespuesta.RespuestaMotor( self.nombre )
                rm.pv = mov
            rm.desde = mov[:2]
            rm.hasta = mov[2:4]
            rm.coronacion = mov[4] if len(mov) == 5 else ""
        mrm.liMultiPV.append( rm )
        return mrm, len(mrm.liMultiPV)-1

    # -----------------------------------------------------------------------------------------
    def analizaVariante( self, jg, tiempo, siBlancas ) :
        if not self.siIniMotor :
            self.iniciarMotor()

        mrm =  self.motor.mejorMov( jg.posicion.fen(), tiempo, None )
        if mrm.liMultiPV :
            rm = mrm.liMultiPV[0]
            if siBlancas != jg.posicion.siBlancas :
                rm.cambiaColor(jg.posicion)
        else :
            rm = XMotorRespuesta.RespuestaMotor()
        return rm

# ---------------------------------------------------------------------------------------------

