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

import random
import time

from Code.Traducir import tr

import Code.Util as Util
import Code.Configuracion as Configuracion
import Code.ControlPosicion as ControlPosicion
import Code.Jugada as Jugada
import Code.Analisis as Analisis

import QTUtil2
import Colocacion
import Iconos
import Controles
import QTVarios
import Columnas
import Grid

import FormLayout

import Tablero

# liFens = []

#==========================================================================================================================================
class WNivelBase( QTVarios.WDialogo ):

    def __init__( self, procesador ) :

        QTVarios.WDialogo.__init__(self,procesador.pantalla, tr("NIVEL_AJEDREZ"), Iconos.Nivel(), "nivelBase" )

        self.procesador = procesador
        self.configuracion = procesador.configuracion

        self.historico = Util.DicDiskCache(self.configuracion.ficheroNivel)
        self.calcListaHistorico()

        self.motor, self.segundos, self.pruebas = self.leeParametros( )

        # liFens.extend( self.historico["20110901"]["LIFENS"])

        # Historico
        oColumnas = Columnas.ListaColumnas()
        oColumnas.nueva( "FECHA", tr("FECHA"), 120, siCentrado = True )
        oColumnas.nueva( "MPUNTOS", tr("PUNTOS_PERDIDOS"), 100, siCentrado = True )
        oColumnas.nueva( "MTIEMPOS", tr("ETI_TIEMPO"), 80, siCentrado = True )
        oColumnas.nueva( "MOTOR", tr("MOTOR"), 120, siCentrado = True )
        oColumnas.nueva( "SEGUNDOS", tr( "SEGUNDOS" ), 80, siCentrado = True )
        oColumnas.nueva( "PRUEBAS", tr( "PRUEBAS" ), 80, siCentrado = True )
        self.ghistorico = Grid.Grid( self, oColumnas )
        self.ghistorico.setMinimumWidth( self.ghistorico.anchoColumnas() + 20 )

        # Tool bar
        liAcciones = (
                        (  tr( "TB_TERMINAR" ), Iconos.TB_FinPartida(), "terminar" ),
                        ( tr( "CONFIGURACION" ), Iconos.TB_Opciones(), "configurar" ),
                        ( tr( "EMPEZAR" ), Iconos.TB_Empezar(), "empezar" ),
                    )
        self.tb = Controles.TB( self, liAcciones )
        self.ponToolBar( [ "terminar", "empezar", "configurar" ] )

        # Colocamos
        ly = Colocacion.V().control(self.tb).control(self.ghistorico).margen(3)

        self.setLayout( ly )

        self.recuperarVideo()

    #--------------------------------------------------------------------------------------------------------------------------------
    def leeParametros( self ) :
        param = Util.DicDiskCache(self.configuracion.ficheroNivel, tabla="parametros" )
        motor = param.get( "MOTOR", "stockfish" )
        segundos = param.get( "SEGUNDOS", 7 )
        pruebas = param.get( "PRUEBAS", 5 )
        param.close()

        return motor, segundos, pruebas

    #--------------------------------------------------------------------------------------------------------------------------------
    def gridNumDatos( self, grid ) :
        return len(self.liHistorico)
    #--------------------------------------------------------------------------------------------------------------------------------
    def gridDato( self, grid, fila, oColumna ) :
        col = oColumna.clave
        key = self.liHistorico[fila]
        reg = self.historico[key]
        if col == "FECHA" :
            fecha = reg[col]
            return "%d/%d/%d"%(fecha.day,fecha.month,fecha.year)
        elif col == "MPUNTOS" :
            mpuntos = reg["MPUNTOS"]
            return "%0.2f"%mpuntos
        elif col == "MTIEMPOS" :
            mtiempos = reg["MTIEMPOS"]
            return "%0.2f"%mtiempos
        elif col == "MOTOR" :
            return reg["MOTOR"]
        elif col == "SEGUNDOS" :
            tiempo = int(reg["TIEMPOJUGADA"]/1000)
            return "%d"%tiempo
        elif col == "PRUEBAS" :
            nfens = len( reg["LIFENS"] )
            return "%d"%nfens

    #--------------------------------------------------------------------------------------------------------------------------------
    def calcListaHistorico( self ) :
        self.liHistorico = self.historico.keys( siOrdenados = True, siReverse = True )

    #--------------------------------------------------------------------------------------------------------------------------------
    def procesarTB( self ) :
        accion = self.sender().clave
        if accion == "terminar" :
            self.guardarVideo()
            self.historico.close()
            self.reject()

        elif accion == "empezar" :
            self.empezar()

        elif accion == "configurar" :
            self.configurar()

    #--------------------------------------------------------------------------------------------------------------------------------
    def configurar( self ) :
        # Datos
        liGen = [(None,None)]

        ## Motor
        mt = self.configuracion.tutorInicial if self.motor is None else self.motor

        liCombo = [mt]
        for nombre, clave in self.configuracion.comboMotoresMultiPV20(minimo = 16) :
            liCombo.append( (clave,nombre) )

        liGen.append( ( tr( "MOTOR" ) + " :", liCombo ) )

        ## Segundos a pensar el tutor
        config = FormLayout.Spinbox( tr( "SEGUNDOS_ANALISIS" ), 1, 99, 50 )
        liGen.append( ( config, self.segundos ) )

        ## Pruebas
        config = FormLayout.Spinbox( tr( "PRUEBAS" ), 1, 40, 40 )
        liGen.append( ( config, self.pruebas ) )

        # Editamos
        resultado = FormLayout.fedit( liGen, title= tr( "CONFIGURACION" ), parent = self, icon = Iconos.TB_Opciones(), siDefecto = False )
        if resultado :
            accion, liResp = resultado
            self.motor = liResp[0]
            self.segundos = liResp[1]
            self.pruebas = liResp[2]

            param = Util.DicDiskCache(self.configuracion.ficheroNivel, tabla="parametros" )
            param["MOTOR"] = self.motor
            param["SEGUNDOS"] = self.segundos
            param["PRUEBAS"] = self.pruebas
            param.close()

    #--------------------------------------------------------------------------------------------------------------------------------
    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 ) :
        li = Util.recuperaVar( "lista60.dkv" )
        liR = []
        dif = int(40/self.pruebas)
        ini = 10
        for x in range(self.pruebas) :
            t0 = random.randint(ini,ini+dif-1)
            ini += dif
            t1 = random.randint(0,len(li[t0]))
            liR.append( li[t0][t1] + " 0 1")
        # liR = liFens
        w = WNivel( self, liR, self.motor, self.segundos)
        w.exec_()
        self.calcListaHistorico()
        self.ghistorico.refresh()

#==========================================================================================================================================
class WNivel( QTVarios.WDialogo ):

    def __init__( self, owner, liFens, motor, segundos ) :

        super(WNivel, self).__init__(owner, tr("NIVEL_AJEDREZ"), Iconos.Nivel(), "nivel" )

        self.procesador = owner.procesador
        self.configuracion = self.procesador.configuracion

        if motor.startswith( "*" ) :
            motor = motor[1:]
        confMotor = self.configuracion.buscaTutor( motor, "stockfish" )
        self.xtutor = self.procesador.creaTutor( confMotor, segundos*1000, None )

        self.historico = owner.historico

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

        self.liFens = liFens
        self.nFens = len(self.liFens)
        self.juego = 0
        self.liPuntos = []
        self.liPV = []
        self.liTiempos = []

        self.tablero = Tablero.Tablero(self, confTablero)
        self.tablero.crea()
        self.tablero.ponMensajero( self.mueveHumano )

        # Rotulos información
        self.lbColor = Controles.LB( "" ).ponWrap().anchoMinimo( 200 )
        self.lbJuego = Controles.LB( "" ).alinCentrado()

        # Tool bar
        liAcciones = (
                        # ( tr( "EMPEZAR" ), Iconos.TB_Empezar(), "empezar" ),
                        ( tr( "ANALISIS" ), Iconos.Tutor(), "analizar" ),
                        ( tr( "CANCELAR" ), Iconos.TB_Cancelar(), "cancelar" ),
                        ( tr( "SEGUIR" ), Iconos.Pelicula_Seguir(), "seguir" ),
                        ( tr( "TB_ABANDONAR" ), Iconos.TB_Abandonar(), "abandonar" ),
                    )
        self.tb = Controles.TB( self, liAcciones )
        # self.ponToolBar( [ "empezar", "cancelar" ] )

        # Colocamos
        lyV = Colocacion.V().control(self.tb).relleno(2).control(self.lbJuego).relleno(1).control(self.lbColor).relleno(2)
        ly = Colocacion.H().control(self.tablero).otro(lyV)

        self.setLayout( ly )

        self.posicion = ControlPosicion.ControlPosicion()
        self.recuperarVideo()

        self.siguienteJugada()

    #--------------------------------------------------------------------------------------------------------------------------------
    def procesarTB( self ) :
        accion = self.sender().clave
        if accion in [ "abandonar", "terminar", "cancelar" ] :
            self.guardarVideo()
            self.reject()
        elif accion == "empezar" :
            self.siguienteJugada()
        elif accion == "seguir" :
            self.siguienteJugada()
        elif accion == "analizar" :
            self.analizar()

    #--------------------------------------------------------------------------------------------------------------------------------
    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 siguienteJugada( self ) :
        self.ponToolBar( [ "abandonar" ] )

        if self.juego == self.nFens :
            self.terminarTest()
            return

        fen = self.liFens[self.juego]
        self.juego += 1

        self.lbJuego.ponTexto( "<h2>%d/%d<h2>"%(self.juego,self.nFens))

        cp = self.posicion

        cp.leeFen( fen )

        siW = cp.siBlancas
        color, colorR = tr( "PGN_WHITE" ), tr( "PGN_BLACK" )
        cK, cQ, cKR, cQR = "K", "Q", "k", "q"
        if not siW :
            color, colorR = colorR, color
            cK, cQ, cKR, cQR = cKR, cQR, cK, cQ

        mens = "<h1><center>%s</center></h1><br>"%color

        if cp.enroques :
            def menr( ck, cq ) :
                enr = ""
                if ck in cp.enroques :
                    enr += "O-O"
                if cq in cp.enroques :
                    if enr :
                        enr += "  +  "
                    enr += "O-O-O"
                return enr
            enr = menr( cK, cQ )
            if enr :
                mens += "<br>%s : %s"%( color, enr )
            enr = menr( cKR, cQR )
            if enr :
                mens += "<br>%s : %s"%( colorR, enr )
        if cp.alPaso != "-" :
            mens += "<br>     %s : %s"%( tr( "PEON_AL_PASO" ), cp.alPaso )

        self.lbColor.ponTexto( mens )

        self.sigueHumano()
        self.iniTiempo = time.clock()

    #--------------------------------------------------------------------------------------------------------------------------------
    def terminarTest( self ) :
        self.paraHumano()
        self.xtutor.terminar()

        t = 0
        for x in self.liPuntos :
            t += x
        mpuntos = t*1.0/self.nFens

        t = 0.0
        for x in self.liTiempos :
            t += x
        mtiempos = t*1.0/self.nFens

        hoy = Util.hoy()
        fecha = "%d%02d%02d"%( hoy.year, hoy.month, hoy.day )
        datos = {}
        datos["FECHA"] = hoy
        datos["MOTOR"] = self.xtutor.clave
        datos["TIEMPOJUGADA"] = self.xtutor.motorTiempoJugada
        datos["LIFENS"] = self.liFens
        datos["LIPV"] = self.liPV
        datos["MPUNTOS"] = mpuntos
        datos["MTIEMPOS"] = mtiempos

        self.historico[fecha] = datos

        self.lbColor.ponTexto("")
        self.lbJuego.ponTexto( "" )

        mens = "<h3>%s : %0.2f</h3><h3>%s : %0.2f</h3>"%(tr( "PUNTOS_PERDIDOS"), mpuntos, tr("TIEMPO_SEGUNDOS"), mtiempos )
        QTUtil2.mensaje( self, mens, tr( "GM_RESULTADO" ), siResalta = False )

        self.accept()

    #--------------------------------------------------------------------------------------------------------------------------------
    def paraHumano( self ) :
        self.tablero.desactivaTodas()
    #--------------------------------------------------------------------------------------------------------------------------------
    def sigueHumano( self ) :
        siW = self.posicion.siBlancas
        self.tablero.ponPosicion( self.posicion )
        self.tablero.ponerPiezasAbajo( siW )
        self.tablero.ponIndicador( siW )
        self.tablero.activaColor( siW )

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

        self.paraHumano()

        movimiento = desde + hasta

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

        siBien, mens, self.jg = Jugada.dameJugada( self.posicion, desde, hasta, coronacion )
        if siBien :
            self.tablero.ponPosicion( self.jg.posicion )
            self.tablero.ponFlechaSC( desde, hasta )
            self.calculaTiempoPuntos( )
        else :
            self.sigueHumano()

    #--------------------------------------------------------------------------------------------------------------------------------
    def calculaTiempoPuntos( self ) :

        tiempo = time.clock()-self.iniTiempo

        um = QTUtil2.mensEspera.inicio( self, tr( "ANALIZANDO" ), posicion = "ad" )
        self.rmr, pos = self.xtutor.analizaJugada(self.jg,self.xtutor.motorTiempoJugada)
        self.jg.analisis = self.rmr, pos
        um.final()
        pv = self.jg.movimiento()
        li = []
        pv = pv.lower()

        minimo = self.rmr.liMultiPV[0].puntosABS()
        actual = None
        mens = "<h2>%d/%d</h2><center><table>"%(self.juego,self.nFens)
        li = []
        for rm in self.rmr.liMultiPV :
            pts = rm.puntosABS()
            ptsc = minimo-pts
            mv = rm.movimiento().lower()
            if mv == pv :
                actual = ptsc
            pgn = self.posicion.pgnSP( mv[:2],mv[2:4],mv[4:])
            li.append( (mv==pv,pgn,pts, ptsc) )

        if actual is None :
            actual = ptsc

        for siPV, pgn, pts, ptsc in li :
            dosp = "&nbsp;:&nbsp;"
            dosi = "&nbsp;=&nbsp;"
            cpts = "%d"%pts
            cptsc = "%d"%ptsc
            if siPV :
                ini = "<b>"
                fin = "</b>"
                pgn = ini + pgn + fin
                dosp = ini + dosp + fin
                dosi = ini + dosi + fin
                cpts = ini + cpts + fin
                cptsc = ini + cptsc + fin

            mens += "<tr><td>%s</td><td>%s</td><td align=\"right\">%s</td><td>%s</td><td align=\"right\">%s</td></tr>"%(pgn,dosp,cpts,dosi,cptsc )
        mens += "</table></center>"

        self.liPV.append( pv )
        self.liPuntos.append( actual )
        self.liTiempos.append( tiempo )

        self.lbJuego.ponTexto(mens)
        self.lbColor.ponTexto("")
        self.ponToolBar( [ "seguir", "cancelar", "analizar" ] )

    #-----------------------------------------------------------------------------------
    def analizar( self ) :

        Analisis.MuestraAnalisis( self.procesador, self.xtutor, self.jg, self.posicion.siBlancas, 9999999, 1, pantalla = self, siGrabar = False )

#==========================================================================================================================================
def pantallaNivel( procesador ) :

    w = WNivelBase(procesador)
    w.exec_()
