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

#==========================================================================================================================================
import os
import time

from Code.Constantes import *
from Code.Traducir import tr

import Util
import ControlPosicion
import Jugada

import Gestor

import QT.QTUtil2 as QTUtil2
import QT.Iconos as Iconos
import QT.Controles as Controles

import QT.PantallaAperturas as PantallaAperturas
import QT.PantallaPGN as PantallaPGN
import QT.EntMaquina as EntMaquina
import QT.PantallaSolo as PantallaSolo

#==========================================================================================================================================
class GestorSolo( Gestor.Gestor ) :

    #--------------------------------------------------------------------------------------------------------------------------------
    def inicio( self, dic={} ) :

        me = self.procesador.unMomento()

        self.tipoJuego = kJugSolo
        self.reinicio = dic

        self.siJuegaHumano = True

        self.ultimoFichero = dic.get("ULTIMOFICHERO", "")
        self.siCambios = dic.get("SICAMBIOS", False)

        self.siVolteoAutomatico = dic.get("VOLTEO", False)

        if "liPGN" not in dic :
            hoy = Util.hoy()
            self.liPGN = []
            self.liPGN.append( ["Event",tr("El ajedrez de Lucas")] )
            self.liPGN.append( ["Date","%d.%02d.%02d"%(hoy.year, hoy.month, hoy.day)] )
            jugador = self.configuracion.jugador
            if len(jugador) == 0 :
                jugador = "Unknown"
            self.liPGN.append( ["White", jugador] )
            self.liPGN.append( ["Black", jugador] )
        else :
            self.liPGN = dic["liPGN"]

        self.fen = dic.get( "FEN", None )

        cp = ControlPosicion.ControlPosicion()
        if self.fen :
            cp.leeFen( self.fen )
        else :
            cp.posInicial()

        self.partida.reset( cp )

        self.estado = dic.get("ESTADO", kJugando)

        self.bloqueApertura = dic.get("BLOQUEAPERTURA", None )
        self.posicApertura = dic.get("POSICAPERTURA", None ) # Utilizada para reeditar

        if self.bloqueApertura :
            self.partida.reset()
            self.partida.leerPV( self.bloqueApertura.a1h8 )
            self.listaAperturasStd.asignaApertura( self.partida )

        if "PARTIDA" in dic :
            self.partida.reset()
            self.partida.recuperaDeTexto( dic["PARTIDA"] )
            self.listaAperturasStd.asignaApertura( self.partida )

        self.ponToolBar( False )

        self.pantalla.activaJuego(True, False)
        self.quitaAyudas(True, False)
        self.pantalla.ponRotulo1( None )
        self.pantalla.ponRotulo2( None )
        self.ponMensajero( self.mueveHumano )
        self.ponPosicion( self.partida.ultPosicion )
        self.mostrarIndicador( True )
        self.ponPiezasAbajo( dic.get( "SIBLANCASABAJO", True ) )
        self.pgnRefresh( True )
        self.ponCapturasPorDefecto()

        self.refresh()

        if self.partida.numJugadas() > 0 :
            self.mueveJugada( "f" )
            jg = self.partida.liJugadas[-1]
            self.ponFlechaSC( jg.desde, jg.hasta )

        me.final()

        self.ponPosicionDGT()

        self.siguienteJugada()

    #--------------------------------------------------------------------------------------------------------------------------------
    def procesarAccion( self, clave ) :

        if clave == k_finpartida :
            self.finPartida()

        elif clave == k_atras :
            self.atras()

        elif clave == k_reiniciar :
            self.reiniciar()

        elif clave == k_otros :
            self.opciones()

        elif clave == k_pgnInformacion :
            self.informacion()

        elif clave == k_grabar :
            self.grabar()

        elif clave == k_grabarComo :
            self.grabarComo()

        elif clave == k_recuperar :
            self.recuperar()

        else :
            Gestor.Gestor.rutinaAccionDef( self, clave )

    #--------------------------------------------------------------------------------------------------------------------------------
    def ponToolBar( self, siGrabarComo ) :
        li = [ k_finpartida,k_grabar,k_grabarComo,k_recuperar,k_pgnInformacion,k_atras,k_reiniciar,k_otros ]
        if not siGrabarComo :
            del li[2]
        self.pantalla.ponToolBar( li )

    #--------------------------------------------------------------------------------------------------------------------------------
    def finPartida( self ) :
        # Comprobamos que no haya habido cambios desde el último grabado
        if self.siCambios and self.partida.numJugadas() :
            resp = QTUtil2.preguntaCancelar( self.pantalla, tr( "SOLO_GRABAR" ), tr("SI"), tr("NO") )
            if resp is None :
                return
            elif resp :
                self.grabarComo()

        self.procesador.inicio()

    #--------------------------------------------------------------------------------------------------------------------------------
    def finalX( self ) :
        self.finPartida()
        return False

    #--------------------------------------------------------------------------------------------------------------------------------
    def atras( self ) :
        if self.partida.numJugadas() :
            self.partida.anulaSoloUltimoMovimiento( )
            if not self.fen :
                self.listaAperturasStd.asignaApertura( self.partida )
            self.ponteAlFinal()
            self.siguienteJugada()

    #--------------------------------------------------------------------------------------------------------------------------------
    def siguienteJugada( self ) :

        if self.estado == kFinJuego :
            return

        self.estado = kJugando

        self.ponVista()

        siBlancas = self.partida.ultPosicion.siBlancas
        self.siJugamosConBlancas = siBlancas # Compatibilidad, sino no funciona el cambio en pgn
        if self.siVolteoAutomatico :
            time.sleep( 1 )
            if siBlancas != self.tablero.siBlancasAbajo :
                self.tablero.rotaTablero()

        if self.partida.numJugadas() > 0 :
            jgUltima = self.partida.liJugadas[-1]
            if jgUltima :
                if jgUltima.siJaqueMate :
                    self.ponResultado( kGanaRival, jgUltima.posicion.siBlancas )
                    return
                if jgUltima.siAhogado :
                    self.ponResultado( kTablas )
                    return
                if jgUltima.siTablasRepeticion :
                    self.ponResultado( kTablasRepeticion )
                    return
                if jgUltima.siTablas50 :
                    self.ponResultado( kTablas50 )
                    return
                if jgUltima.siTablasFaltaMaterial :
                    self.ponResultado( kTablasFaltaMaterial )
                    return

        self.ponIndicador( siBlancas )
        self.refresh()

        self.activaColor( siBlancas )

    #--------------------------------------------------------------------------------------------------------------------------------
    def mueveHumano( self, desde, hasta, coronacion = None ) : # se incluye coronacion para poder llamarlo desde libros

        movimiento = desde + hasta

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

        siBien, mens, jg = Jugada.dameJugada( self.partida.ultPosicion, desde, hasta, coronacion )

        if siBien :

            self.movimientosPiezas( jg.liMovs )

            self.partida.ultPosicion = jg.posicion
            self.masJugada( jg )
            self.error = ""
            self.siguienteJugada()
            return True
        else :
            self.error = mens
            return False

    #--------------------------------------------------------------------------------------------------------------------------------
    def masJugada( self, jg ) :

        self.siCambios = True

        # Preguntamos al mono si hay movimiento
        if self.siTerminada() :
            jg.siJaqueMate = jg.siJaque
            jg.siAhogado = not jg.siJaque

        self.partida.liJugadas.append( jg )
        if self.partida.pendienteApertura :
            self.listaAperturasStd.asignaApertura( self.partida )

        resp = self.partida.si3repetidas()
        if resp :
            jg.siTablasRepeticion = True
            rotulo = ""
            for j in resp :
                rotulo += "%d,"%(j/2+1,)
            rotulo = rotulo.strip(",")
            self.rotuloTablasRepeticion = rotulo

        if self.partida.ultPosicion.movPeonCap >= 50 :
            jg.siTablas50 = True

        if self.partida.ultPosicion.siFaltaMaterial() :
            jg.siTablasFaltaMaterial = True

        self.ponFlechaSC( jg.desde, jg.hasta )

        self.pgnRefresh(self.partida.ultPosicion.siBlancas)
        self.refresh()

        self.ponPosicionDGT()

    #--------------------------------------------------------------------------------------------------------------------------------
    def ponResultado( self, quien, siBlancas = None ) :
        self.desactivaTodas( )

        self.resultadoQuien = quien
        self.resultadoSiBlancas = siBlancas

        self.resultado = quien

        if quien == kTablasRepeticion :
            self.resultado = kTablas

        elif quien == kTablas50 :
            self.resultado = kTablas

        elif quien == kTablasFaltaMaterial :
            self.resultado = kTablas

    #-----------------------------------------------------------------------------------
    def actualPGN( self ) :
        """
        Llamado para grabar el pgn
        """
        resp = ""
        st = set()
        for eti, valor in self.liPGN :
            resp += '[%s "%s"]\n'%(eti,valor)
            st.add( eti )

        if "Result" not in st :
            if self.resultado == kDesconocido :
                result = "*"

            elif self.resultado == kTablas :
                result = "1/2-1/2"

            else :
                result = '1-0' if self.resultadoSiBlancas else '0-1'

            resp += '[Result "%s"]\n'%result
        else :
            result = st["Result"]

        if self.fen :
            resp += '[FEN "%s"]\n'%self.fen

        ap = self.partida.apertura
        if ap :
            if "ECO" not in st :
                resp += '[ECO "%s"]\n'%ap.eco
            if "Opening" not in st :
                resp += '[Opening "%s"]\n'%tr(ap.nombre)

        resp += self.partida.pgnBase() + " " + result

        return resp

    #-----------------------------------------------------------------------------------
    def opciones( self ) :
        liMasOpciones = (
                ( "libros", tr( "LIBRO_CONSULTA" ), Iconos.TB_Libros() ),
                ( None, None, None ),
                ( "apertura", tr("PGN_OPENING" ), Iconos.Apertura() ),
                ( None, None, None ),
                ( "posicion", tr("POSICION_INICIAL" ), Iconos.Datos() ),
                ( None, None, None ),
                ( "leerpgn", tr("TB_PGNFICHERO" ), Iconos.PGN_Importar() ),
                ( None, None, None ),
                ( "rotacion", tr("JS_ROTACION" ), Iconos.JS_Rotacion() ),
                )
        resp = self.otros(liMasOpciones)

        if resp :
            if resp == "libros" :
                resp1 = self.libros( "S" ) # gestor
                if resp1 :
                    self.mueveHumano( resp1[:2], resp1[2:4], resp1[4:])

            elif resp == "rotacion" :
                self.siVolteoAutomatico = not self.siVolteoAutomatico
                siBlancas = self.partida.ultPosicion.siBlancas
                if self.siVolteoAutomatico :
                    if siBlancas != self.tablero.siBlancasAbajo :
                        self.tablero.rotaTablero()

            elif resp == "posicion" :
                resp = EntMaquina.editarPosicion( self.pantalla, self.configuracion, self.fen )
                if resp is not None :
                    self.fen = resp
                    self.bloqueApertura = None
                    self.posicApertura = None
                    self.reiniciar(  )

            elif resp == "apertura" :
                bl, ps = PantallaAperturas.dameApertura( self.pantalla, self.configuracion, self.bloqueApertura, self.posicApertura )
                if bl :
                    self.bloqueApertura = bl
                    self.posicApertura = ps
                    self.fen = None
                    self.reiniciar(  )

            elif resp == "leerpgn" :
                resp = PantallaPGN.eligePartida( self.pantalla, self )
                if resp :
                    self.bloqueApertura = None
                    self.posicApertura = None
                    self.fen = None
                    dic = self.creaDic()
                    dic["PARTIDA"] = resp.guardaEnTexto()
                    self.reiniciar( dic )

    #-----------------------------------------------------------------------------------
    def creaDic( self ) :
        dic = {}
        dic["VOLTEO"] = self.siVolteoAutomatico
        dic["liPGN"] = self.liPGN
        dic["FEN"] = self.fen
        dic["ESTADO"] = self.estado
        dic["BLOQUEAPERTURA"] = self.bloqueApertura
        dic["POSICAPERTURA"] = self.posicApertura
        return dic

    #-----------------------------------------------------------------------------------
    def reiniciar( self, dic = None ) :
        if dic is None :
            dic = self.creaDic()
        self.inicio( dic )

    #-----------------------------------------------------------------------------------
    def editarEtiquetasPGN( self ) :

        resp = PantallaSolo.editarEtiquetasPGN( self.procesador, self.liPGN )
        if resp :
            self.liPGN = resp

    #-----------------------------------------------------------------------------------
    def guardaDir( self, resp ) :
        direc = os.path.dirname( resp )
        if direc != self.configuracion.dirJS :
            self.configuracion.dirJS = direc
            self.configuracion.graba()

    #-----------------------------------------------------------------------------------
    def grabarFichero( self, fichero ) :

        try :
            dic = self.creaDic()
            dic["PARTIDA"] = self.partida.guardaEnTexto()
            dic["ULTIMOFICHERO"] = fichero
            dic["SIBLANCASABAJO"] = self.tablero.siBlancasAbajo
            f = open( fichero, "wb" )
            f.write( Util.dic2txt( dic ) )
            f.close()
            self.guardaDir( fichero )
            self.siCambios = False
            nombre = os.path.basename(fichero)
            me = QTUtil2.mensEspera.inicio( self.pantalla, tr("GRABADO",nombre) )
            time.sleep( 0.8 )
            me.final()

        except :
            QTUtil2.mensError( self.pantalla, "%s : %s"%( tr("IMPOSIBLE_GRABAR"),fichero ) )
    #-----------------------------------------------------------------------------------
    def grabarComo( self ) :
        extension = "pks"
        siConfirmar = True
        if self.ultimoFichero :
            fichero = self.ultimoFichero
        else :
            fichero = self.configuracion.dirJS
        while True :
            resp = QTUtil2.salvaFichero( self.pantalla, tr( "INDICA_FICHERO" ), fichero, tr("FICHERO")+" %s (*.%s)"%(extension,extension), siConfirmarSobreescritura=siConfirmar  )
            if resp :
                resp = str(resp)
                if not siConfirmar :
                    if os.path.abspath(resp) != os.path.abspath(self.ultimoFichero) and os.path.isfile(resp):
                        yn = QTUtil2.preguntaCancelar( self.pantalla, tr( "FICHERO_EXISTE", resp ), si=tr("SOBREESCRIBIR"), no=tr("ELEGIR_OTRO") )
                        if yn is None :
                            break
                        if not yn :
                            continue
                self.grabarFichero( resp )
                return resp
            break
        return None
    #-----------------------------------------------------------------------------------
    def grabar( self ) :
        if self.ultimoFichero :
            self.grabarFichero( self.ultimoFichero )
        else :
            resp = self.grabarComo()
            if resp :
                self.ultimoFichero = resp
                self.ponToolBar( True )

    #-----------------------------------------------------------------------------------
    def recuperar( self ) :
        resp = QTUtil2.leeFichero( self.pantalla, self.configuracion.dirJS, "pks" )
        if resp :
            f = open( resp, "rb" )
            txt = f.read()
            f.close()
            self.guardaDir( resp )
            dic = Util.txt2dic( txt )
            dic["ULTIMOFICHERO"] = resp
            self.reiniciar( dic )
            self.ponToolBar( True )

    #--------------------------------------------------------------------------------------------------------------------------------
    def informacion( self ) :

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

        for clave, valor in self.liPGN :
            siFecha = clave.upper().endswith("DATE")
            ctra = "PGN_" + clave.upper()
            trad = tr( ctra )
            if trad != ctra :
                clave = trad
            else :
                clave = clave[0].upper()+clave[1:].lower()
            if siFecha :
                valor = valor.replace( ".??", "" )
            menu.opcion( clave, "%s : %s"%(clave,valor), Iconos.PuntoAzul() )

        apertura = self.partida.apertura
        if apertura :
            menu.separador()
            nom = tr( apertura.nombre )
            ape = tr("PGN_OPENING")
            rotulo = nom if ape.upper() in nom.upper() else ("%s : %s"%(ape,nom))
            menu.opcion( clave, rotulo, Iconos.PuntoNaranja() )

        menu.separador()
        menu.opcion( "pgn", tr("JS_EDITARPGN" ), Iconos.PGN() )

        resp = menu.lanza()
        if resp == "pgn" :
            self.editarEtiquetasPGN()
