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

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

from PySide import QtCore, QtGui

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

import Code.Util as Util
import Code.Configuracion as Configuracion
import Code.ControlPosicion as ControlPosicion
import Code.Books as Books
import Code.Personalidades as Personalidades
import Code.DGT as DGT

import QTUtil2
import Colocacion
import Iconos
import Controles
import PantallaAperturas
import PantallaMotores

import FormLayout

import Tablero

#==========================================================================================================================================
class LBPieza(Controles.LB) :
    def __init__( self, owner, pieza, anchoPieza, tipoPieza ) :
        self.pieza = pieza
        self.owner = owner
        pixmap = eval( "Iconos.pm%s_%d%s()"%(pieza,anchoPieza,tipoPieza) )
        self.dragpixmap = pixmap
        Controles.LB.__init__( self )
        self.anchoFijo(anchoPieza).altoFijo(anchoPieza).ponImagen(pixmap)
    def mousePressEvent(self, event) :
        if event.button() == QtCore.Qt.LeftButton :
            self.owner.startDrag( self )
            self.owner.owner.ultimaPieza = self.pieza

#-------------------------------------------------------------------------------------------------------------------------------------------
class ListaPiezas(QtGui.QWidget):
    def __init__(self, owner, lista):
        QtGui.QWidget.__init__(self)

        self.owner = owner
        self.tablero = tablero = owner.tablero
        anchoPieza = tablero.anchoPieza
        tipoPieza = tablero.tipoPieza

        liLB = []
        for fila,valor in enumerate(lista.split(";")) :
            for columna,pieza in enumerate(valor.split(",")) :
                lb = LBPieza( self, pieza, anchoPieza, tipoPieza )
                liLB.append( (lb, fila, columna) )

        layout = Colocacion.G()
        for lb, fila, columna in liLB :
            layout.control(lb,fila,columna)

        l1 = Colocacion.H().relleno(1).otro(layout).relleno(1)
        l2 = Colocacion.V().relleno(1).otro(l1).relleno(1)

        self.setLayout( l2 )

    def startDrag(self, lb):

        pixmap = lb.dragpixmap
        pieza = lb.pieza
        itemData = QtCore.QByteArray(str(pieza))

        mimeData = QtCore.QMimeData()
        mimeData.setData('image/x-lc-pieza', itemData)

        drag = QtGui.QDrag(self)
        drag.setMimeData(mimeData)
        drag.setHotSpot(QtCore.QPoint(pixmap.width()/2, pixmap.height()/2))
        drag.setPixmap(pixmap)

        drag.exec_(QtCore.Qt.MoveAction)

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

    def __init__( self, wParent, configuracion, fen ) :

        super(WPosicion, self).__init__(wParent)

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

        self.configuracion = configuracion

        self.setWindowTitle( tr( "POSICION" ) )
        self.setWindowIcon( Iconos.Datos() )

        # Quien mueve
        self.rbBlancas = Controles.RB( self, tr( "PGN_WHITE" ) )
        self.rbNegras = Controles.RB( self, tr( "PGN_BLACK" ) )

        # Enroques permitidos
        self.cbBoo = Controles.CHB( tr( "PGN_WHITE" ) + " O-O", True )
        self.cbBooo = Controles.CHB( tr( "PGN_WHITE" ) + " O-O-O", True )
        self.cbNoo = Controles.CHB( tr( "PGN_BLACK" ) + " O-O", True )
        self.cbNooo = Controles.CHB( tr( "PGN_BLACK" ) + " O-O-O", True )

        # Peón al paso
        lbAlPaso = Controles.LB( tr( "PEON_AL_PASO" ) + " :" )
        self.edAlPaso = Controles.ED( self ).controlrx( "(-|[a-h][36])" ).anchoFijo( 30 )

        # Medias jugadas desde último mov. peón
        self.edMedias, lbMedias = QTUtil2.spinBoxLB( 0, 0, 999, etiqueta = tr( "JUGADAS_SIN_50" ), maxTam=50 )

        # Jugadas
        self.edJugadas, lbJugadas = QTUtil2.spinBoxLB( 1, 1, 999, etiqueta = tr( "JUGADAS" ), maxTam=50 )

        # Botones adicionales
        btPosInicial = Controles.PB( self, tr( "POSICION_INICIAL" ), self.posInicial ).ponPlano(False)
        btLimpiaTablero = Controles.PB( self, tr( "LIMPIA_TABLERO" ), self.limpiaTablero ).ponPlano(False)
        btPegar = Controles.PB( self, tr( "PEGAR_POSICION" ), self.pegarPosicion ).ponPlano(False)
        btCopiar = Controles.PB( self, tr( "COPIAR_POSICION" ), self.copiarPosicion ).ponPlano(False)

        # Tablero
        confTablero = Configuracion.ConfigTablero()
        confTablero.lee( configuracion.cTableroN.graba() )
        confTablero.anchoPieza = 32
        self.posicion = ControlPosicion.ControlPosicion()
        if fen :
            self.posicion.leeFen( fen )
        else :
            self.posicion.posInicial()
        self.tablero = Tablero.PosTablero(self, confTablero)
        self.tablero.crea()
        self.tablero.ponMensajero( self.mueve )
        self.tablero.mensBorrar = self.borraCasilla
        self.tablero.mensCrear = self.creaCasilla
        self.tablero.mensRepetir = self.repitePieza
        self.ultimaPieza = "P"

        self.resetPosicion()

        # Piezas drag-drop
        self.dragDropWI = ListaPiezas( self, "P;N;B;R;Q;K" )
        self.dragDropWB = ListaPiezas( self, "P,N,B,R,Q,K" )
        self.dragDropBD = ListaPiezas( self, "k;q;r;b;n;p" )
        self.dragDropBA = ListaPiezas( self, "k,q,r,b,n,p" )
        self.tablero.ponDispatchDrop( self.dispatchDrop )
        self.tablero.baseCasillasSC.setAcceptDrops(True)

        # Ayuda
        lbAyuda = Controles.LB( tr( "AYUDA_POSICION" ) )

        # Tool bar
        tb = QTUtil2.creaTBAceptarCancelar( self )

        # Layout

        ## Quien mueve
        hbox = Colocacion.H().relleno(1).control(self.rbBlancas).espacio(30).control(self.rbNegras).relleno(1)
        gbColor = Controles.GB( self, tr( "QUIEN_MUEVE" ), hbox )

        ## Enroques
        ly = Colocacion.G().control( self.cbBoo, 0, 0 ).control( self.cbNoo, 0, 1 )
        ly.control( self.cbBooo, 1, 0 ).control( self.cbNooo, 1, 1 )
        gbEnroques = Controles.GB( self, tr( "ENROQUES_POSIBLES" ), ly )

        ## Otros
        ly = Colocacion.G().controld( lbAlPaso, 0, 0 ).control( self.edAlPaso, 0, 1 )
        ly.controld( lbMedias, 1, 0 ).control( self.edMedias, 1, 1 )
        ly.controld( lbJugadas, 2, 0 ).control( self.edJugadas, 2, 1 )
        gbOtros = Controles.GB( self, "", ly )

        ## Botones adicionales
        lyBA = Colocacion.H().control( btPosInicial ).control( btLimpiaTablero ).control( btPegar ).control( btCopiar )

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

        ## Izquierda
        ly = Colocacion.V().control( gbColor ).relleno(1).control( gbEnroques ).relleno(1)
        ly.control( gbOtros ).relleno(1).control( gbAyuda ).margen(15 )
        lyI = Colocacion.V().control( tb ).otro( ly ).margen(3)

        ## Derecha
        # lyDA0 = Colocacion.H().relleno(1).control(self.dragDropWI).control( self.tablero ).control(self.dragDropBD).relleno(1)
        # lyDA = Colocacion.V().controlc(self.dragDropBA).otro( lyDA0 ).controlc(self.dragDropWB)
        lyDA = Colocacion.G()
        lyDA.controlc( self.dragDropBA, 0, 1 )
        lyDA.control( self.dragDropWI, 1, 0 ).control( self.tablero,1,1 ).control(self.dragDropBD,1,2)
        lyDA.controlc( self.dragDropWB, 2, 1 )

        lyD = Colocacion.V().otro( lyDA ).otro( lyBA )

        ## Completo
        ly = Colocacion.H().otro(lyI).otro(lyD).margen(3)
        self.setLayout( ly )

        if configuracion.siDGT :
            if not DGT.activarSegunON_OFF( self.dgt ) : # Error
                QTUtil2.mensError( self.pantalla, tr( "DGT_ERROR" )  )

    #--------------------------------------------------------------------------------------------------------------------------------
    def dgt( self, quien, dato ) :
        if quien == "scan" :
            siBlancas, alPaso, jugadas, movPeonCap, enroques = self.leeDatos()
            fen = dato + " " + \
                ("w" if siBlancas else "b") + " " + \
                enroques + " " + \
                alPaso + " " + \
                str(movPeonCap) + " " + \
                str(jugadas)
            posic = ControlPosicion.ControlPosicion()
            posic.leeFen(fen)
            if posic.fen() != self.posicion.fen() :
                self.posicion.leeFen( posic.fen() )
                self.resetPosicion()

    #--------------------------------------------------------------------------------------------------------------------------------
    def cierra( self ) :
        DGT.quitarDispatch()
    #--------------------------------------------------------------------------------------------------------------------------------
    def closeEvent( self, event ) :
        self.cierra()
        event.accept()

    #--------------------------------------------------------------------------------------------------------------------------------
    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 dispatchDrop( self, desde, pieza ) :
        if self.casillas[desde] :
            self.borraCasilla( desde )
        if pieza in "kK" :
            for pos,pz in self.casillas.iteritems() :
                if pz == pieza :
                    self.borraCasilla( pos )
                    break
        self.ponPieza( desde, pieza )

    #--------------------------------------------------------------------------------------------------------------------------------
    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
            self.ponPieza( desde, pieza )
    #--------------------------------------------------------------------------------------------------------------------------------
    def ponPieza( self, desde, pieza ) :
        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 leeDatos( self ) :
        siBlancas = self.rbBlancas.isChecked()
        alPaso = self.edAlPaso.texto().strip()
        if not alPaso :
            alPaso = "-"
        jugadas = self.edJugadas.value()
        movPeonCap = self.edMedias.value( )

        enroques = ""
        for cont, pieza in ( (self.cbBoo, "K" ),(self.cbBooo, "Q" ),(self.cbNoo, "k"),(self.cbNooo, "q") ) :
            if cont.isChecked() :
                enroques += pieza
        if not enroques :
            enroques = "-"
        return siBlancas, alPaso, jugadas, movPeonCap, enroques

    #--------------------------------------------------------------------------------------------------------------------------------
    def procesarTB( self ) :
        accion = self.sender().clave
        if accion == "aceptar" :
            if self.posicion.siExistePieza( "K" ) != 1 :
                QTUtil2.mensError( self, tr( "REY") + "-" + tr( "PGN_WHITE" ) + "???" )
                return
            if self.posicion.siExistePieza( "k" ) != 1 :
                QTUtil2.mensError( self, tr( "REY") + "-" + tr( "PGN_BLACK" ) + "???" )
                return
            self.posicion.siBlancas, self.posicion.alPaso, self.posicion.jugadas, self.posicion.movPeonCap, self.posicion.enroques = self.leeDatos()

            self.fen = self.posicion.fen() # Hace control de enroques y alPaso
            if self.fen == self.posicion.fenInicial :
                self.fen = ""
            self.cierra()
            self.accept()
        elif accion == "cancelar" :
            self.cierra()
            self.reject()

    #--------------------------------------------------------------------------------------------------------------------------------
    def pegarPosicion( self ) :
        cb = QtGui.QApplication.clipboard()
        fen = cb.text( )
        if fen :
            try :
                self.posicion.leeFen( str(fen) )
                self.resetPosicion()
            except :
                pass

    #--------------------------------------------------------------------------------------------------------------------------------
    def copiarPosicion( self ) :
        cb = QtGui.QApplication.clipboard()
        cb.setText( self.posicion.fen() )

    #--------------------------------------------------------------------------------------------------------------------------------
    def limpiaTablero( self ) :
        self.posicion.leeFen( "8/8/8/8/8/8/8/8 w - - 0 1" )
        self.resetPosicion()

    #--------------------------------------------------------------------------------------------------------------------------------
    def posInicial( self ) :
        self.posicion.posInicial()
        self.resetPosicion()

    #--------------------------------------------------------------------------------------------------------------------------------
    def resetPosicion( self ) :
        self.tablero.ponPosicion( self.posicion )
        self.casillas = self.posicion.casillas
        self.tablero.casillas = self.casillas
        self.tablero.activaTodas()

        if self.posicion.siBlancas :
            self.rbBlancas.activa( True )
        else :
            self.rbNegras.activa( True )

        # Enroques permitidos
        enroques = self.posicion.enroques
        self.cbBoo.setChecked( "K" in enroques )
        self.cbBooo.setChecked( "Q" in enroques )
        self.cbNoo.setChecked( "k" in enroques )
        self.cbNooo.setChecked( "q" in enroques )

        # Otros
        self.edAlPaso.ponTexto( self.posicion.alPaso )
        self.edJugadas.setValue( self.posicion.jugadas )
        self.edMedias.setValue( self.posicion.movPeonCap )

    #--------------------------------------------------------------------------------------------------------------------------------
    def ponTablero( self, nombre ) :
        if nombre == "N" :
            self.confTablero.lee( self.configuracion.cTableroN.graba() )
        else :
            self.confTablero.lee( self.configuracion.cTableroT.graba() )
        self.actualizaTablero()
#==========================================================================================================================================

def editarPosicion( win, config, fen=None ) :
    w = WPosicion( win, config, fen )
    if w.exec_() :
        return w.fen
    else :
        return None

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

    #--------------------------------------------------------------------------------------------------------------------------------
    def __init__(self, wParent, configuracion, titulo )  :
        super(WEntMaquina, self).__init__(wParent)

        self.setWindowTitle( titulo )
        self.setWindowIcon( Iconos.Motor() )
        self.setWindowFlags( QtCore.Qt.Dialog | QtCore.Qt.WindowTitleHint )

        self.configuracion = configuracion

        self.personalidades = Personalidades.Personalidades( self, configuracion )

        # Toolbar
        liAcciones = [ ( tr( "ACEPTAR" ), Iconos.TB_Aceptar(), "aceptar" ), None,
                    ( tr( "CANCELAR" ), Iconos.TB_Cancelar(), "cancelar" ), None,
                    ( tr( "MOTORES_EXTERNOS" ), Iconos.TB_Motores(), "motores" ), None,
                    ]
        tb = Controles.TB( self, liAcciones )

        # Blancas o negras
        self.rbBlancas = Controles.RB( self, tr( "PGN_WHITE" ) ).activa()
        self.rbNegras = Controles.RB( self, tr( "PGN_BLACK" ) )

        # Ayudas
        liAyudas = [ ("--", 0) ]
        for x in range( 1, 31 ) :
            liAyudas.append( (str(x),x))
        liAyudas.append( ( "99", 99 ))
        self.cbAyudas = Controles.CB( liAyudas, 7 ).capturaCambiado( self, self.ayudasCambiado )
        lbAyudas = Controles.LB2P( tr("AYUDAS") )

        # Atras
        self.cbAtras = Controles.CHB( "", True )

        # Posicion
        self.btPosicion = Controles.PB( self, " "*5+tr( "CAMBIAR" )+" "*5, self.editarPosicion ).ponPlano( False )
        self.fen = ""
        self.btPosicionQuitar = Controles.PB( self, "", self.posicionQuitar ).ponIcono( Iconos.Motor_No() )

        # Aperturas
        self.btApertura = Controles.PB( self, " "*5+tr( "APERTURA_LIBRE" )+" "*5, self.editarApertura ).ponPlano( False )
        self.bloqueApertura = None
        self.posicApertura = None # Utilizada para reeditar
        self.btAperturasFavoritas = Controles.PB( self, "", self.aperturasFavoritas ).ponIcono( Iconos.Favoritos() )
        self.btAperturasQuitar = Controles.PB( self, "", self.aperturasQuitar ).ponIcono( Iconos.Motor_No() )

        # Libros
        fvar = self.configuracion.ficheroBooks
        self.listaLibros = Books.ListaLibros()
        self.listaLibros.recuperaVar(fvar)
        ## Comprobamos que todos estén accesibles
        self.listaLibros.comprueba()
        li = [ (x.nombre, x) for x in self.listaLibros.lista ]
        libInicial = li[0][1] if li else None
        self.cbBooks = QTUtil2.comboBoxLB( li, libInicial )
        self.btNuevoBook = Controles.PB( self, "", self.nuevoBook, plano = False ).ponIcono( Iconos.TB_Nuevo(), tamIcon = 16 )
        ## Respuesta rival
        li = (
                (tr("LIBROS_RR_USUARIO"), "su" ),
                (tr("LIBROS_RR_ALEATORIO"), "au" ),
                (tr("LIBROS_RR_PROPORCIONAL"), "ap" ),
                (tr("LIBROS_RR_MAYOR"), "mp" ),
                )
        self.cbBooksRR = QTUtil2.comboBoxLB( li, "mp" )
        self.lbBooksRR = Controles.LB2P( tr( "LIBROS_RR" ) )

        # Motores
        self.liMotoresClave = configuracion.comboMotoresCompleto()
        self.liMotoresClavePV = configuracion.comboMotoresMultiPV20( )

        liDepths = [ ("--", 0) ]
        for x in range( 1, 31 ) :
            liDepths.append( (str(x),x))

        ## Rival
        self.cbRmotor = Controles.CB( self.liMotoresClave, configuracion.rivalInicial )
        self.edRtiempo = Controles.ED( self ).tipoFloat( ).anchoMaximo( 50 )
        self.cbRdepth = Controles.CB( liDepths, 0 ).capturaCambiado( self, self.cambiadoDepth )
        lbTiempoSegundosR = Controles.LB2P( tr( "ETI_TIEMPO" ) )
        lbNivel = Controles.LB2P( tr( "ETI_NIVEL" ) )

        ## Ajustar rival
        liAjustes = self.personalidades.listaAjustes(True)
        self.cbAjustarRival = Controles.CB( liAjustes, kAjustarMejor ).capturaCambiado( self, self.ajustesCambiado )
        lbAjustarRival = Controles.LB2P( tr("AJUSTAR_RIVAL") )
        btAjustarRival = Controles.PB( self, "", self.cambiaPersonalidades, plano=False ).ponIcono( Iconos.TB_Nuevo(), tamIcon = 16 )
        btAjustarRival.ponToolTip(tr("PERSONALIDADES"))

        ## Tutor
        self.cbTmotor, lbTmotor = QTUtil2.comboBoxLB( self.liMotoresClavePV, configuracion.tutorInicial, tr( "TUTOR" ) )
        self.edTtiempo = Controles.ED( self ).tipoFloat( ).anchoMaximo( 50 )
        lbTiempoSegundosT = Controles.LB2P( tr( "ETI_TIEMPO" ) )

        # Tiempo
        self.edMinutos, self.lbMinutos = QTUtil2.spinBoxLB( 15, 0, 99, maxTam=50, etiqueta=tr( "TIEMPO_MINUTOS_TOTAL" ) )
        self.edSegundos, self.lbSegundos = QTUtil2.spinBoxLB( 6, 0, 99, maxTam=50, etiqueta=tr( "TIEMPO_SEGUNDOS_JUGADA" ) )
        self.edMinExtra, self.lbMinExtra = QTUtil2.spinBoxLB( 15, 0, 99, maxTam=50, etiqueta=tr( "TIEMPO_MINUTOS_EXTRA" ) )

        # Layout
        ## Color
        hbox = Colocacion.H().relleno(1).control(self.rbBlancas).espacio(30).control(self.rbNegras).relleno(1)
        gbColor = Controles.GB( self, tr( "JUGAMOS_CON" ), hbox )

        ## Atras
        hbox = Colocacion.H().espacio(10).control( self.cbAtras )
        gbAtras = Controles.GB( self, tr( "TB_ATRAS" ), hbox ).alinCentrado()

        ## Color + Atras
        hAC = Colocacion.H().control( gbColor ).control( gbAtras )

        ## Posicion
        hbox = Colocacion.H().relleno(1).control( self.btPosicionQuitar ).control( self.btPosicion ).relleno(1)
        self.gbPosicion = gbPosicion = Controles.GB( self, tr( "POSICION_INICIAL" ), hbox )

        ## Apertura
        hbox = Colocacion.H().relleno(1).control( self.btAperturasQuitar ).control( self.btApertura ).control( self.btAperturasFavoritas ).relleno(1)
        self.gbApertura = gbApertura = Controles.GB( self, tr( "PGN_OPENING" ), hbox )

        ## Motores
        ### Rival
        ly = Colocacion.G()
        ly.controlc( self.cbRmotor, 0, 0, 1, 4 )
        ly.controld( lbTiempoSegundosR, 1, 0 ).controld( self.edRtiempo, 1, 1 )
        ly.controld( lbNivel, 1, 2 ).control( self.cbRdepth, 1, 3 )
        lyH = Colocacion.H().control(lbAjustarRival).control(self.cbAjustarRival).control(btAjustarRival).relleno(1)
        ly.otroc( lyH, 2, 0, 1, 4 )
        gbR = Controles.GB( self, tr( "RIVAL" ), ly )

        ### Tutor
        ly = Colocacion.G()
        lyH = Colocacion.H().control(lbAyudas).control(self.cbAyudas)
        ly.otroc( lyH, 0, 0, 1, 2 )
        ly.control( self.cbTmotor, 1, 0, 1, 2 )
        ly.controld( lbTiempoSegundosT, 2, 0 ).control( self.edTtiempo, 2, 1 )
        gbTT = Controles.GB( self, tr( "TUTOR" ), ly )

        lyMT = Colocacion.H().control(gbR).control(gbTT)

        ## Tiempo
        ly = Colocacion.G()
        ly.controld( self.lbMinutos, 0, 0 ).control( self.edMinutos, 0, 1 )
        ly.controld( self.lbSegundos, 0, 2 ).control( self.edSegundos, 0, 3 )
        ly.controld( self.lbMinExtra, 1, 0 ).control( self.edMinExtra, 1, 1 )
        gbT = Controles.GB( self, tr( "ETI_TIEMPO" ), ly ).conectar( self.cambiaTiempo )
        self.gbT = gbT
        self.cambiaTiempo()

        ## Books
        hbox = Colocacion.H().relleno(1).control(self.cbBooks).control(self.btNuevoBook).relleno(1)
        hboxRR = Colocacion.H().relleno(1).control(self.lbBooksRR).control(self.cbBooksRR).relleno(1)
        hboxV = Colocacion.V().otro(hbox).otro(hboxRR)
        gbBooks = self.gbBooks = Controles.GB( self, tr( "LIBRO" ), hboxV ).conectar( self.cambiaBook )
        self.cambiaBook()

        lyResto = Colocacion.V()
        lyResto.otro( hAC).espacio( 3 )
        lyResto.otro( lyMT ).espacio( 1 )
        lyResto.control( gbT ).espacio( 3 )
        lyResto.control( gbPosicion ).espacio( 3 )
        lyResto.control( gbApertura ).espacio( 3 )
        lyResto.control( gbBooks ).espacio( 3 )
        lyResto.margen( 8 )

        layout = Colocacion.V().control( tb ).otro( lyResto ).relleno(1).margen( 3 )

        self.setLayout( layout )

        self.liAperturasFavoritas = []
        self.btAperturasFavoritas.hide()
        self.recuperaDic()

        self.ajustesCambiado()
        self.ayudasCambiado()

    #--------------------------------------------------------------------------------------------------------------------------------
    def ayudasCambiado( self ) :
        ok = self.cbAyudas.resultado() > 0
        self.cbTmotor.setEnabled( ok )
        self.edTtiempo.setEnabled( ok )

    #--------------------------------------------------------------------------------------------------------------------------------
    def cambiaPersonalidades( self ) :
        siRehacer = self.personalidades.lanzaMenu()
        if siRehacer :
            actual = self.cbAjustarRival.resultado()
            self.cbAjustarRival.rehacer( self.personalidades.listaAjustes(True), actual )

    #--------------------------------------------------------------------------------------------------------------------------------
    def ajustesCambiado( self ) :
        resp = self.cbAjustarRival.resultado()
        if resp is None :
            self.cbAjustarRival.ponValor( kAjustarNivelAlto )
        actual = self.cbRmotor.resultado()
        liMotores = self.liMotoresClave if self.cbAjustarRival.resultado()==kAjustarMejor else self.liMotoresClavePV
        self.cbRmotor.rehacer( liMotores, actual )

    #--------------------------------------------------------------------------------------------------------------------------------
    def cambiadoDepth( self, num ) :
        if num > 0 :
            self.edRtiempo.ponFloat( 0.0 )
        self.edRtiempo.setEnabled(num==0)

    #--------------------------------------------------------------------------------------------------------------------------------
    def editarPosicion( self ) :
        resp = editarPosicion( self, self.configuracion, self.fen )
        if resp is not None :
            self.fen = resp
            self.muestraPosicion()

    #--------------------------------------------------------------------------------------------------------------------------------
    def muestraPosicion( self ) :
        if self.fen :
            rotulo = self.fen
            self.gbApertura.hide()
            self.btPosicionQuitar.show()
            self.bloqueApertura = None
        else :
            rotulo = tr( "CAMBIAR" )
            self.btPosicionQuitar.hide()
            self.gbApertura.show()
        rotulo = " "*5+rotulo + " "*5
        self.btPosicion.ponTexto( rotulo )

    #--------------------------------------------------------------------------------------------------------------------------------
    def editarApertura( self ) :
        self.btApertura.setDisabled( True ) # Puede tardar bastante tiempo
        me = QTUtil2.mensEspera.inicio( self, tr( "UN_MOMENTO" ) )
        w = PantallaAperturas.WAperturas( self, self.configuracion, self.bloqueApertura, self.posicApertura )
        me.final()
        self.btApertura.setDisabled( False )
        if w.exec_() :
            self.bloqueApertura, self.posicApertura = w.resultado()
            self.muestraApertura()

    #--------------------------------------------------------------------------------------------------------------------------------
    def aperturasFavoritas( self ) :
        if len(self.liAperturasFavoritas) == 0 :
            return
        menu = Controles.LMenu()
        menu.setToolTip( tr("EM_TOOTIPAPERTURASFAV") )
        f = Controles.TipoLetra( puntos=8, peso=75 )
        menu.ponFuente( f )
        nPos = 0
        for bloque, posic in self.liAperturasFavoritas :
            menu.opcion( (bloque,posic, nPos), tr(bloque.nombre), Iconos.PuntoVerde() )
            nPos += 1

        resp = menu.lanza()
        if resp :
            if menu.siIzq :
                self.bloqueApertura, self.posicApertura, nPos = resp
                self.muestraApertura()
            elif menu.siDer :
                bloqueApertura, posicApertura, nPos = resp
                if QTUtil2.pregunta( self, tr( "EM_BORRAMOSAPERTURA", tr(bloqueApertura.nombre) ) ) :
                    del self.liAperturasFavoritas[nPos]

    #--------------------------------------------------------------------------------------------------------------------------------
    def muestraApertura( self ) :
        if self.bloqueApertura :
            rotulo = tr(self.bloqueApertura.nombre) + "\n" + self.bloqueApertura.pgn
            self.gbPosicion.hide()
            self.btAperturasQuitar.show()
            self.fen = ""
        else :
            rotulo = " "*3 + tr( "APERTURA_LIBRE" ) + " "*3
            self.btAperturasQuitar.hide()
            self.gbPosicion.show()
        self.btApertura.ponTexto( rotulo )

    #--------------------------------------------------------------------------------------------------------------------------------
    def procesarTB( self ) :
        accion = self.sender().clave
        if accion == "aceptar" :
            self.aceptar()

        elif accion == "cancelar" :
            self.reject()

        elif accion == "motores" :
            self.motoresExternos()

    #--------------------------------------------------------------------------------------------------------------------------------
    def aceptar( self ) :
        dic = {}
        dic["SIBLANCAS"] = self.rbBlancas.isChecked()
        dic["FEN"] = self.fen
        dic["AYUDAS"] = self.cbAyudas.resultado()
        dic["APERTURA"] = self.bloqueApertura

        dr = dic["RIVAL"] = {}
        dr["MOTOR"] = self.cbRmotor.resultado()
        dr["TIEMPO"] = int(self.edRtiempo.textoFloat()*10)
        dr["PROFUNDIDAD"] = self.cbRdepth.resultado()

        dr = dic["TUTOR"] = {}
        dr["MOTOR"] = self.cbTmotor.resultado()
        t = int(self.edTtiempo.textoFloat()*10)
        dr["TIEMPO"] = t if t > 0 else 10

        dic["SITIEMPO"] = self.gbT.isChecked()
        if dic["SITIEMPO"] :
            dic["MINUTOS"] = self.edMinutos.value()
            dic["SEGUNDOS"] = self.edSegundos.value()
            dic["MINEXTRA"] = self.edMinExtra.value()

        dic["ATRAS"] = self.cbAtras.valor()
        dic["AJUSTAR"] = self.cbAjustarRival.resultado()

        siBook = self.gbBooks.isChecked()
        dic["BOOK"] = self.cbBooks.resultado() if siBook else None
        dic["BOOKRR"] = self.cbBooksRR.resultado() if siBook else None

        self.dic = dic
        self.guardaDic( dic )
        self.accept()

    #--------------------------------------------------------------------------------------------------------------------------------
    def motoresExternos( self ) :
        w = PantallaMotores.WMotores( self, self.configuracion.ficheroMExternos )
        if w.exec_() :
            liMotores = self.liMotoresClave
            for cb in [ self.cbRmotor, self.cbTmotor ] :
                previo = cb.resultado()
                cb.clear()
                for n, tp in enumerate(liMotores) :
                    cb.addItem( tp[0], tp[1] )
                    if tp[1] == previo :
                        cb.setCurrentIndex( n )

    #--------------------------------------------------------------------------------------------------------------------------------
    def guardaDic( self, dic ) :
        dic["POSICAPERTURA"] = self.posicApertura # Para recuperarDIC
        dic["APERTURASFAVORITAS"] = self.liAperturasFavoritas
        Util.guardaDIC( dic, self.configuracion.ficheroEntMaquina )

    #--------------------------------------------------------------------------------------------------------------------------------
    def recuperaDic( self ) :
        dic = Util.recuperaDIC( self.configuracion.ficheroEntMaquina )
        if dic :
            siBlancas = dic["SIBLANCAS"]
            self.rbBlancas.activa(siBlancas)
            self.rbNegras.activa(not siBlancas)

            self.fen = dic["FEN"]

            self.cbAyudas.ponValor(dic["AYUDAS"])

            self.bloqueApertura = dic["APERTURA"]
            self.posicApertura = dic["POSICAPERTURA"]
            self.liAperturasFavoritas = dic["APERTURASFAVORITAS"]
            if self.bloqueApertura :
                nEsta = -1
                for npos, v in enumerate(self.liAperturasFavoritas) :
                    bl, pos = v
                    if bl.a1h8 == self.bloqueApertura.a1h8 :
                        nEsta = npos
                        break
                if nEsta != 0 :
                    if nEsta != -1 :
                        del self.liAperturasFavoritas[nEsta]
                    self.liAperturasFavoritas.insert( 0, (self.bloqueApertura, self.posicApertura) )
                while len(self.liAperturasFavoritas) > 10 :
                    del self.liAperturasFavoritas[10]
            if len(self.liAperturasFavoritas) :
                self.btAperturasFavoritas.show()

            liMotores = self.liMotoresClave

            dr = dic["RIVAL"]
            motor = dr["MOTOR"]
            for n, v in enumerate(liMotores) :
                if v[1] == motor :
                    self.cbRmotor.setCurrentIndex( n )
                    break
            self.edRtiempo.ponFloat(float(dr["TIEMPO"])/10.0)
            self.cbRdepth.ponValor(dr["PROFUNDIDAD"])

            liMotores = self.liMotoresClavePV
            dr = dic["TUTOR"]
            motor = dr["MOTOR"]
            for n, v in enumerate(liMotores) :
                if v[1] == motor :
                    self.cbTmotor.setCurrentIndex( n )
                    break
            self.edTtiempo.ponFloat(float(dr["TIEMPO"])/10.0)

            siTiempo = dic.get("SITIEMPO", False)
            if siTiempo :
                self.gbT.setChecked( True )
                self.edMinutos.setValue( dic["MINUTOS"] )
                self.edSegundos.setValue( dic["SEGUNDOS"] )
                self.edMinExtra.setValue( dic.get("MINEXTRA", 0) )
            self.cambiaTiempo()

            book = dic.get( "BOOK", None )
            bookRR = dic.get( "BOOKRR", None )
            self.gbBooks.setChecked( book is not None )
            if book :
                self.cbBooks.ponValor( book )
                self.cbBooksRR.ponValor( bookRR )
            self.cambiaBook()

            self.cbAtras.setChecked( dic.get("ATRAS",True) )
            self.cbAjustarRival.ponValor( dic.get("AJUSTAR",kAjustarMejor) )

        self.muestraApertura()
        self.muestraPosicion()

    #--------------------------------------------------------------------------------------------------------------------------------
    def cambiaTiempo( self ) :
        si = self.gbT.isChecked()
        for control in ( self.edMinutos, self.lbMinutos, self.edSegundos, self.lbSegundos, self.lbMinExtra, self.edMinExtra ) :
            control.setVisible( si )

    #--------------------------------------------------------------------------------------------------------------------------------
    def cambiaBook( self ) :
        si = self.gbBooks.isChecked()
        for control in ( self.cbBooks, self.btNuevoBook, self.lbBooksRR, self.cbBooksRR ) :
            control.setVisible( si )

    #--------------------------------------------------------------------------------------------------------------------------------
    def nuevoBook( self ) :
        fbin = QTUtil2.leeFichero( self, self.listaLibros.path, "bin", titulo = tr("LIBROS_POLYGLOT") )
        if fbin :
            self.listaLibros.path = os.path.dirname( fbin )
            nombre = os.path.basename(fbin)[:-4]
            b = Books.Libro("P", nombre, fbin, False )
            self.listaLibros.nuevo( b )
            fvar = self.configuracion.ficheroBooks
            self.listaLibros.guardaVar( fvar )
            li = [ (x.nombre, x) for x in self.listaLibros.lista ]
            self.cbBooks.rehacer( li, b )

    #--------------------------------------------------------------------------------------------------------------------------------
    def aperturasQuitar( self ) :
        self.bloqueApertura = None
        self.posicApertura = None
        self.muestraApertura()

    #--------------------------------------------------------------------------------------------------------------------------------
    def posicionQuitar( self ) :
        self.fen = ""
        self.muestraPosicion()

# ----------------------------------------------------------------------------------------------
def entrenamientoMaquina( parent, configuracion, titulo ):

    w = WEntMaquina( parent, configuracion, titulo )
    if w.exec_() :
        return w.dic
    else :
        return None

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

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

    def __init__(self, wParent, configuracion, dic )  :
        super(WCambioRival, self).__init__(wParent)

        self.setWindowTitle(  tr( "CAMBIO_RIVAL" ) )
        self.setWindowIcon( Iconos.Motor() )
        self.setWindowFlags( QtCore.Qt.Dialog | QtCore.Qt.WindowTitleHint )

        self.configuracion = configuracion
        self.personalidades = Personalidades.Personalidades( self, configuracion )

        # Toolbar
        liAcciones = [ ( tr( "ACEPTAR" ), Iconos.TB_Aceptar(), "aceptar" ), None,
                    ( tr( "CANCELAR" ), Iconos.TB_Cancelar(), "cancelar" ), None,
                    ( tr( "MOTORES_EXTERNOS" ), Iconos.TB_Motores(), "motores" ), None,
                    ]
        tb = Controles.TB( self, liAcciones )

        # Blancas o negras
        self.rbBlancas = Controles.RB( self, tr( "PGN_WHITE" ) ).activa()
        self.rbNegras = Controles.RB( self, tr( "PGN_BLACK" ) )

        # Atras
        self.cbAtras = Controles.CHB( "", True )

        # Motores
        self.liMotoresClave = configuracion.comboMotoresCompleto()
        self.liMotoresClavePV = configuracion.comboMotoresMultiPV20( )

        liDepths = [ ("--", 0) ]
        for x in range( 1, 31 ) :
            liDepths.append( (str(x),x))

        ## Rival
        self.cbRmotor = Controles.CB( self.liMotoresClave, configuracion.rivalInicial )
        self.edRtiempo = Controles.ED( self ).tipoFloat( ).anchoMaximo( 50 )
        self.cbRdepth = Controles.CB( liDepths, 0 ).capturaCambiado( self, self.cambiadoDepth )
        lbTiempoSegundosR = Controles.LB2P( tr( "ETI_TIEMPO" ) )
        lbNivel = Controles.LB2P( tr( "ETI_NIVEL" ) )

        ## Ajustar rival
        liAjustes = self.personalidades.listaAjustes(True)
        self.cbAjustarRival = Controles.CB( liAjustes, kAjustarMejor ).capturaCambiado( self, self.ajustesCambiado )
        lbAjustarRival = Controles.LB2P( tr("AJUSTAR_RIVAL") )
        btAjustarRival = Controles.PB( self, "", self.cambiaPersonalidades, plano=False ).ponIcono( Iconos.TB_Nuevo(), tamIcon = 16 )
        btAjustarRival.ponToolTip(tr("PERSONALIDADES"))

        # Layout
        ## Color
        hbox = Colocacion.H().relleno(1).control(self.rbBlancas).espacio(30).control(self.rbNegras).relleno(1)
        gbColor = Controles.GB( self, tr( "JUGAMOS_CON" ), hbox )

        ## Atras
        hbox = Colocacion.H().espacio(10).control( self.cbAtras )
        gbAtras = Controles.GB( self, tr( "TB_ATRAS" ), hbox ).alinCentrado()

        ## Color + Atras
        hAC = Colocacion.H().control( gbColor ).control( gbAtras )

        ## Motores
        ### Rival
        ly = Colocacion.G()
        ly.controlc( self.cbRmotor, 0, 0, 1, 4 )
        ly.controld( lbTiempoSegundosR, 1, 0 ).controld( self.edRtiempo, 1, 1 )
        ly.controld( lbNivel, 1, 2 ).control( self.cbRdepth, 1, 3 )
        lyH = Colocacion.H().control(lbAjustarRival).control(self.cbAjustarRival).control(btAjustarRival).relleno(1)
        ly.otroc( lyH, 2, 0, 1, 4 )
        gbR = Controles.GB( self, tr( "RIVAL" ), ly )

        lyResto = Colocacion.V()
        lyResto.otro( hAC).espacio( 3 )
        lyResto.control( gbR ).espacio( 1 )
        lyResto.margen( 8 )

        layout = Colocacion.V().control( tb ).otro( lyResto ).relleno(1).margen( 3 )

        self.setLayout( layout )

        self.dic = dic
        self.recuperaDic()

        self.ajustesCambiado()

    def ajustesCambiado( self ) :
        actual = self.cbRmotor.resultado()
        liMotores = self.liMotoresClave if self.cbAjustarRival.resultado()==kAjustarMejor else self.liMotoresClavePV
        self.cbRmotor.rehacer( liMotores, actual )

    def cambiadoDepth( self, num ) :
        if num > 0 :
            self.edRtiempo.ponFloat( 0.0 )
        self.edRtiempo.setEnabled(num==0)

    def procesarTB( self ) :
        accion = self.sender().clave
        if accion == "aceptar" :
            self.aceptar()

        elif accion == "cancelar" :
            self.reject()

        elif accion == "motores" :
            self.motoresExternos()

    def aceptar( self ) :
        dic = self.dic
        dic["SIBLANCAS"] = self.rbBlancas.isChecked()

        dr = dic["RIVAL"] = {}
        dr["MOTOR"] = self.cbRmotor.resultado()
        dr["TIEMPO"] = int(self.edRtiempo.textoFloat()*10)
        dr["PROFUNDIDAD"] = self.cbRdepth.resultado()

        dic["ATRAS"] = self.cbAtras.valor()
        dic["AJUSTAR"] = self.cbAjustarRival.resultado()

        self.accept()

    def motoresExternos( self ) :
        w = PantallaMotores.WMotores( self, self.configuracion.ficheroMExternos )
        if w.exec_() :
            liMotores = self.liMotoresClave
            for cb in [ self.cbRmotor, self.cbTmotor ] :
                previo = cb.resultado()
                cb.clear()
                for n, tp in enumerate(liMotores) :
                    cb.addItem( tp[0], tp[1] )
                    if tp[1] == previo :
                        cb.setCurrentIndex( n )

    def recuperaDic( self ) :
        dic = self.dic
        siBlancas = dic["SIBLANCAS"]
        self.rbBlancas.activa(siBlancas)
        self.rbNegras.activa(not siBlancas)

        self.cbAtras.setChecked( dic.get("ATRAS",True) )

        liMotores = self.liMotoresClave

        dr = dic["RIVAL"]
        motor = dr["MOTOR"]
        for n, v in enumerate(liMotores) :
            if v[1] == motor :
                self.cbRmotor.setCurrentIndex( n )
                break
        self.edRtiempo.ponFloat(float(dr["TIEMPO"])/10.0)
        self.cbRdepth.ponValor(dr["PROFUNDIDAD"])
        self.cbAjustarRival.ponValor( dic.get("AJUSTAR",kAjustarMejor) )

    #--------------------------------------------------------------------------------------------------------------------------------
    def cambiaPersonalidades( self ) :
        siRehacer = self.personalidades.lanzaMenu()
        if siRehacer :
            actual = self.cbAjustarRival.resultado()
            self.cbAjustarRival.rehacer( self.personalidades.listaAjustes(True), actual )

# ----------------------------------------------------------------------------------------------
def cambioRival( parent, configuracion, dic ):

    w = WCambioRival( parent, configuracion, dic )

    if w.exec_() :
        return w.dic
    else :
        return None

#==========================================================================================================================================
def dameMinutosExtra( pantalla ) :
    liGen = [(None,None)]

    config = FormLayout.Spinbox( tr("TIEMPO_MINUTOS_EXTRA"), 1, 99, 50 )
    liGen.append( ( config, 5 ) )

    resultado = FormLayout.fedit( liGen, title= tr( "ETI_TIEMPO" ), parent = pantalla, icon = Iconos.MoverTiempo(), siDefecto = False )
    if resultado :
        accion, liResp = resultado
        return liResp[0]

    return None
