//--Copyright 2001-2010 - Francois Leysour de Rohello - www.iechecs.com
g_debug=false;
// description d'une position ----- notation fen (minuscule = noire, majsucule = blancs)
var g_pos_init_fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq"
var g_pos_init = "tcfdrfctpppppppppppppppptcfdrfct"
var g_random_tab  = new Array(0,1,2,3,4,5,6,7,8);

// variable globale
//var g_path ="img/t2/";	// path des images
//var g_cote = 20; // 	taille d'une case en pixel wchess=36, fritz 40
var g_path ="img/";	// path des images
var g_cote = 40 // 40	taille d'une case en pixel wchess=36, fritz 40
var g_orig_x			// coordonnée coin supérieur gauche de la case H8
var g_orig_y

var g_path_vide  = g_path + "v.png"
var g_path_point = g_path + "p.png"
var g_bc = "#fde9ac" // background color
var g_sc = "yellow"   // couleur coup courant
var g_lastcel = null // derniere coup courant
var g_nb_col = 3 // nombre de colonne
var g_mc_col = 25 // nombre de coup par colonne (50 demi-coup)
var g_mc = g_nb_col*g_mc_col*2;	// max demi-coup par feuille
var g_first_col = 0;	// col 0 commmence à 1, col 1 commence à 26..
var g_style = ".png"
var g_ext   = ".png"
var g_trace = false;
var g_resize =false;
var g_colpromo = true;	// choix de la promotion
var g_noclic  = true;	// pour gerer le choix de la promotion
var g_nb_piece = 32 + 22;	// nombre de piece + nombre de piece promotion
var g_blanc     = " ";		    // pour netscape blanc = "&nbsp;"
var g_ie_min_w	= 348	// largeur minimum
var g_ie_min_h = 469	// hauteur minimum
var g_ie_std_w	= 684	// largeur standard
var g_ie_std_h = 469	// hauteur standard
var g_rac = true; // raccourci clavier activé
var g_dal = false; // simule mode modale pour panneau
var g_stopkeypress = false;	// true pour annuler traitement keypress

// variables globales initialisées une seule fois au chargement de la page
var g_lettre = new Array("","a","b","c","d","e","f","g","h")	// lettre pour colonne
var g_lettrepiece_fr = "CFTDR"
var g_lettrepiece_us = "NBRQK"
var g_lettreidpiece  = "cftdr"
var g_lettrepiece = g_lettrepiece_fr

// variable de l'objet iechecs
var g_p = new Array(900) // stocke une partie 1 demi-coup = 6 elements (2*3)
var g_r = new Array(300) // indique si roque possible bitarray
var g_PRB = 8; // petit roque blanc
var g_GRB = 4; // grand roque blanc
var g_PRN = 2; // petit roque noir
var g_GRN = 1; // grand roque noir

// piece depart/capture/promu,   col_start, lig_start
// type action,                  col_end,   lig_end
var g_notation_partie = new Array(300);	// stocke chaque demi coup

var g_occupe = new Array(100)	// stocke piece sur une case de l'échiquier (id : rn, db..)
var g_chess960 =false;	// position initiale standard ou chess960

var g_fichier = ""				// nom du fichier importé

var g_mode      = 1				// mode partie par défaut
var g_notation  = true			// true : notation abrégée / false : notation algébrique complète
var g_notationpgn;   			// text pour l'exporation au format pgn
var g_notationtext;				// accede a la texte textarea pour import /export fen et pgn
var g_cadrefenpgn  = false		// vrai si le cadre fenpgn  est visible
var g_cadreopts    = false		// vrai si le cadre options est visible

var g_nc = 0						// numero du coup courant
var g_coup_joue = 0  		// nombre de coup joue
var g_couleur = true		// indique le tour : true = blanc

// pour le mode demo et actions
var g_pieceaction = null		// indique la piece en action
var g_piecepromo  = null		// indique la piece promue
var g_demo  = false;		// indique mode demo (apprendre)
var g_setup = false;		// indique la saisie d'une position
var g_reverse = false;	// indique si l'échiquier est renversé (noir en bas)
var g_load = false;		// indique le chargement d'une partie

var g_lstouverture = null		// référence la liste box des ouvertures
var g_lstdatabase  = null		// référence la liste box des parties

var g_lig_start, g_col_start		// coordonne de depart de la piece deplacée

// a simplifier
var g_curX = - g_cote/2;
var g_curY = - g_cote/2;	// pour drag & drop
var g_mouX, g_mouY;			// position souris

var g_taille_mini = false;	// vrai si en taille mini

var g_min_w	= g_ie_min_w	// largeur minimum
var g_min_h = g_ie_min_h	// hauteur minimum
var g_std_w	= g_ie_std_w	// largeur standard
var g_std_h = g_ie_std_h	// hauteur standard

var g_bApp = false;			// vrai si iEchecs est lance dans une fenetre independante

function init_variable_onload()
{
g_bSybase = (location.search.substr(0,4) == "?syb")
g_bApp    = (location.search.substr(0,4) == "?app")  // mode application (nouvelle fenetre)

lib_init_browser()

//preload images
preloadImages('tb.png','cb.png','fb.png','rb.png','db.png','pb.png','tn.png','cn.png','fn.png','rn.png','dn.png','pn.png','v.png','p.png')

// initialisation commune
// accès au cadre notation html
g_cursor    = getObj("cursor")	// cursor de deplacement d'une piece
g_cursor_id = null;			   // id  de la piece deplacer avec le cursor
g_last_id   = "rb";			   // id  de la derniere piece deplace (pour le setup)

g_divheader  = getObj("notahead")
g_divpartie  = getObj("notationhtml")
g_divpgnfen  = getObj("divpgnfen")
g_divoptions = getObj("divoptions")
g_divboite   = getObj("divboite")
g_lstouverture = getObj("divouverture")
g_lstprobleme  = getObj("divprobleme")
g_lstapprendre = getObj("divapprendre")
g_lstdatabase  = getObj("divdatabase")

g_notationtext = getObj("notationtext")

set_pan(true,false,false,false,false,false)

// surcharge handler souris
document.onmousedown = doMouseDown;
document.onmouseup   = doMouseUp;
document.onmousemove = doMouseMove;
// surcharge hanlder clavier
document.onkeypress  = doKeyPress;
document.onkeydown   = doKeyDown;

// point origine (coin superieure gauche de la case A8)
g_orig_x = get_left(getObj("iezone"));
g_orig_y = get_top(getObj("iezone"));

init_ouverture();
init_probleme();
init_database();

// initialise une nouvelle partie
set_nouveau();

set_mode(1) // mode partie
set_focus_apprendre(-1);

init_header("<Evenement>","<lieu>","<date>","?","<blancs>","<noirs>","*","<elo>","<elo>","")
renum_feuille(0)

// parametre passee (partie, mode , action..)
if (location.search.length > 1)
	execute(location.search.substr(1))

init_point_vert()
set_visible(getObj("grille"), true)
g_bLoaded = true;
}

function set_syn(page) { g_syn_text = page  } // page pour synchroniser le cadre texte

function set_taille(){
g_taille_mini=!g_taille_mini
g_taille_mini ? window.resizeTo(g_min_w,g_min_h) : window.resizeTo(g_std_w,g_std_h)
}

function preloadImages(){
var d=document;
if(d.images){
	if(!d.p)
		d.p = new Array();
  	var i, j=d.p.length;
 	a=preloadImages.arguments;
 	for(i=0; i<a.length; i++){
		d.p[j]=new Image;
		d.p[j++].src= "img/"+a[i];
	}
}
}

function cache_point_vert(){ for (lig1=8; lig1>=1; --lig1) for (col1=1; col1<=8; ++col1) vide_grille_point(col1,lig1) }
function init_point_vert(){ for (lig1=8; lig1>=1; --lig1) for (col1=1; col1<=8; ++col1) init_grille_point(col1,lig1) }

// change l'image de l'échiquier
function init_case(breverse) { getObj("echiquier").src = breverse ? g_path+"boardn.png" : g_path+"board.png" }

// vide l'echiquier de toutes les pieces
function vider()
{
	g_nc = 0		// numero du coup courant
	g_coup_joue = 0 // nombre de coup joue

	montre_ligne(false,false,false)
	cache_point_vert()

	// vide toutes les pieces l'echiquier
	for (col=1; col <=8;++col)
		for (lig=8; lig >=1;--lig)
			vide_case(col,lig)

	// vide toutes les cases
	for (lig=8; lig>=1; --lig)
		for (col=1; col<=8; ++col)
			g_occupe[lig*8 + col] = null
}

// propose le choix d'une piece pour la promotion du pion
function ChoisirPromotion(bCouleur)
{
   g_colpromo = bCouleur ? "blanc":"noir";
	var dame   = bCouleur ? "D":"d";
	if (g_ie) // seul ie gere les boites modales
	{
	   g_colpromo = showModalDialog("promo.htm", bCouleur?"blanc":"noir", "dialogWidth:220px;dialogHeight:110px;status=no;toolbar=no;menubar=no;location=no" );
	   if (g_colpromo==null)
	   	g_colpromo = dame;
	}
 	else
	{
		g_dlgpromo = window.open("promo.htm",null,"height=80,width=220,status=no,toolbar=no,menubar=no,location=no")
		// pas d'autre solution pour attendre le choix de l'utilisateur dans la fenetre...
		alert("Choisissez la piece de promotion puis validez ou\nvalidez tout de suite pour choisir une dame")
		// g_colpromo est mis à jour via la fenetre de choix
		if (g_colpromo == "blanc" ||  g_colpromo == "noir")
		{
			g_dlgpromo.close() // ferme la fenetre de choix de promotion
			g_colpromo = dame;
		}
 	}
 	return g_colpromo;
}

function action_enpassant()
{
lire_position_fen("8/5p2/8/4P3/8/8/8/8 w")
lire_partie("1. ... f5 2. exf6",false)
set_debut(-1)
}

function action_roque(bPetitRoque)
{
if (bPetitRoque)
{
	lire_position_fen("8/8/8/8/8/8/8/4R2T/")
	lire_partie("1.O-O",false)
}
else
{
	lire_position_fen("8/8/8/8/8/8/8/T3R3/")
	lire_partie("1.O-O-O",false)
}
set_debut(-1)
}

function action_promotion()
{
lire_position_fen("8/3P4/8/8/8/8/8/8/")
lire_partie("1.d8D",false)
set_debut(-1)
}

// situation de pat
function action_pat(n_action)
{
lire_position_fen("7r/5R2/6PP/8/8/8/8/8/ b")
}

// situation d'echec perpetuel
function action_perpetuel(n_action)
{
lire_position_fen("1r6/1p4T1/2D5/8/8/8/6PR/4d3/ b")
lire_partie("1. ... Dh4 2.Rg1 De1 3.Rh2 Dh4 4.Rg1 De1 5.Rh2 Dh4",false)
set_debut(-1)
}

// Gestion des boutons debut, retour, avance et fin
// revient au debut d'une position (num=-1) ou revient de num demi_coup
function set_debut(num)
{
	while (g_nc > 0 &&  (num==-1 || num-->0))
		if (!set_arriere())
			break;
}

// revient un coup en arriere
function set_arriere()
{
	if (g_nc > 0)
	{
		if (g_p[g_nc-6]==".")
			return false;

		// joue un coup en arriere
		g_nc -= 6

		set_courant(g_nc/6)

		var piece = g_p[g_nc].substr(0,2)
		// repositionne piece joue sur sa case de depart
		set_case(piece, g_p[g_nc+1], g_p[g_nc+2])

		// si mode trace, efface le dernier point vert
		if (g_trace)
			vide_grille(g_p[g_nc+1], g_p[g_nc+2]) // efface point vert

		if (g_p[g_nc+3] == 0)	// deplacement simple
			vide_case(g_p[g_nc+4], g_p[g_nc+5])	// libere case d'arrivée
		else if (g_p[g_nc+3] == 1) // piece capture a remettre
			set_case(g_p[g_nc].substr(2,2), g_p[g_nc+4], g_p[g_nc+5])
		else if (g_p[g_nc+3] == 2) // prise en passant
		{
			// remet pion capturée en passant
			var lig = (g_p[g_nc+5] == 3) ? 4 : 5;
			set_case(g_p[g_nc].substr(2,2), g_p[g_nc+4], lig)
			vide_case(g_p[g_nc+4], g_p[g_nc+5])	// libere case d'arrivée
		}
		else if (g_p[g_nc+3] == 3) // petit roque
		{
      vide_case( g_p[g_nc+4] , g_p[g_nc+5])	// libere case d'arrivée
      vide_case( 6, g_p[g_nc+2])	// libere case de la tour
		  if (g_chess960) {
        vide_case( 7, g_p[g_nc+2])	// libere case roi
        set_case(g_p[g_nc].substr(0,2), g_random_tab[8], g_p[g_nc+2]) // remet tour
        set_case(g_p[g_nc].substr(2,2), g_random_tab[5], g_p[g_nc+2]) // remet roi
      }
      else {
        set_case(g_p[g_nc].substr(2,2), 8, g_p[g_nc+2]) // remet tour
			}
		}
		else if (g_p[g_nc+3] == 4) // grand roque
		{
      vide_case( g_p[g_nc+4] , g_p[g_nc+5])	// libere case d'arrivée
      vide_case( 4, g_p[g_nc+2])	// libere case de la tour
		  if (g_chess960) {
        vide_case( 3, g_p[g_nc+2])	// libere case roi
        set_case(g_p[g_nc].substr(0,2), g_random_tab[1], g_p[g_nc+2]) // remet tour
        set_case(g_p[g_nc].substr(2,2), g_random_tab[5], g_p[g_nc+2]) // remet roi
      }
      else {
        set_case(g_p[g_nc].substr(2,2), 1, g_p[g_nc+2]) // remet tour
      }
		}
		else if (g_p[g_nc+3] == 5) // promotion
			vide_case(g_p[g_nc+4], g_p[g_nc+5])	// libere case d'arrivée
		else if (g_p[g_nc+3] == 6) // promotion avec prise
			set_case(g_p[g_nc].substr(4,2), g_p[g_nc+4], g_p[g_nc+5])

		if (!g_demo)
			change_couleur()
	}
	
	return true;
}

// --------------------------------------------
// clic sur le bouton AVANT
// --------------------------------------------
function set_avant()
{
	if (g_coup_joue != g_nc)
	{
		// rejoue un coup en avant
		if (!g_demo && !g_trace)
			change_couleur()

		if (g_p[g_nc]!=".")
		{
			vide_case( g_p[g_nc+1], g_p[g_nc+2])	// libere case de depart
			if (g_trace)
				affiche_point(g_p[g_nc+1], g_p[g_nc+2]) // affiche point vert
		}

		if (g_p[g_nc+3] ==0 || g_p[g_nc+3] ==1 ) // deplacement / prise
		{
			set_case(g_p[g_nc].substr(0,2), g_p[g_nc+4] , g_p[g_nc+5]) // positionne piece joue
		}
		else if (g_p[g_nc+3] ==2 ) // prise en passant
		{
			set_case(g_p[g_nc].substr(0,2), g_p[g_nc+4] , g_p[g_nc+5]) // positionne piece joue
			var lig = (g_p[g_nc+5] == 3) ? 4 : 5;
			vide_case(g_p[g_nc+4], lig) // libere case du pion
		}
		else if (g_p[g_nc+3] == 3  ) // petit roque
		{
      vide_case(g_random_tab[8], g_p[g_nc+2])	// libere case tour
      if (g_chess960) {
			  vide_case(g_p[g_nc+4], g_p[g_nc+2])	// libere case roi
			  set_case(g_p[g_nc].substr(0,2),6,g_p[g_nc+2]) // tour
			  set_case(g_p[g_nc].substr(2,2),7,g_p[g_nc+2]) // roi
			}
			else {
		    set_case(g_p[g_nc].substr(0,2), g_p[g_nc+4] , g_p[g_nc+5]) // roi
		    set_case(g_p[g_nc].substr(2,2), 6 , g_p[g_nc+5]) // tour
      }
		}
		else if (g_p[g_nc+3] == 4 ) // grand roque
		{
      vide_case(g_random_tab[1], g_p[g_nc+2])	// libere case tour
		  if (g_chess960) {
			  vide_case(g_random_tab[5], g_p[g_nc+2])	// libere case roi
			  set_case(g_p[g_nc].substr(0,2),4,g_p[g_nc+2]) // tour
			  set_case(g_p[g_nc].substr(2,2),3,g_p[g_nc+2]) // roi
		  }
		  else {
        set_case(g_p[g_nc].substr(0,2), g_p[g_nc+4] , g_p[g_nc+5]) // positionne piece joue
        set_case(g_p[g_nc].substr(2,2), 4 , g_p[g_nc+5]) // positionne tour
			}
		}
		else if (g_p[g_nc+3] >= 5 ) // promotion , promotion avec prise
		{
			set_case(g_p[g_nc].substr(2,2), g_p[g_nc+4] , g_p[g_nc+5]) // positionne piece promu
		}

		g_nc += 6

		set_courant(g_nc/6)
	}
}

//-- se positonne a la fin ou de num demi coup en avant
function set_fin(num)
{
	while ((num==-1 || num-->0) && g_coup_joue != g_nc)
		set_avant()
}


// positionne le trait (vrai = blanc, false = noir)
function set_couleur(bCouleur)
{
	g_couleur = bCouleur
	set_visible(getObj("traitblanc"), bCouleur);
	set_visible(getObj("traitnoir") , !bCouleur);
}

// gere visibilité panneau Partie / Position /Problème / Ouvertures / Apprendre
function set_pan(b1,b2,b3,b4,b5,b6)
{
	set_visible(g_divpartie,    b1);	// partie
	set_visible(g_divheader,    b1);	// header
	set_visible(g_divboite,     b2); // boite des pieces
	set_visible(g_lstprobleme,  b3); // probleme
	set_visible(g_lstouverture, b4); // apprendre
	set_visible(g_lstapprendre, b5);	// ouvertures
	set_visible(g_lstdatabase,  b6);	// databases
}

//---- Positionne le mode :
//---- 1) Mode Partie     : pour jouer une partie
//---- 2) Mode Position   : pour saisir une position
//---- 3) Mode Problème   : selection de problème d'échecs
//---- 4) Mode ouvertures : présentation des ouvertures
//---- 5) Mode apprendre  : pour apprendre les régles
//---- 6) Mode Database   : base parties
function set_mode(selectedIndex)
{
	g_trace = false;
	g_lastmode = g_mode
	g_mode = selectedIndex;
	g_demo = false;
	g_pieceaction = null;
	g_setup = false;

	// met a jour la combo
   getObj("combomode").selectedIndex = selectedIndex-1;

	if (g_mode == 1)	// mode partie
	{
		set_pan(true,false,false,false,false,false)
		window.focus();
	}
	else if (g_mode == 2)	// position (pour saisir une position)
	{
		set_pan(false,true,false,false,false,false)

		g_setup = true;
		montre_ligne(false,false,false);
		cache_point_vert();
	}
	else if (g_mode == 3)	// problème
	{
		set_syn("probleme.htm")
		set_pan(false,false,true,false,false,false)
	}
	else if (g_mode == 4)	// ouverture
	{
		g_lettrepiece = g_lettrepiece_fr;
		set_syn("ouverture.htm")
		set_pan(false,false,false,true,false,false)
	}
	else if (g_mode == 5)	// mode apprendre
	{
		set_couleur(true);
		set_pan(false,false,false,false,true,false)
	}
	else if (g_mode == 6)	// mode base de données
	{
		set_pan(false,false,false,false,false,true)
	}

}

// change le temoin de trait (petit rond à droite de l'échiquier)
function change_couleur()
{
	g_couleur = !g_couleur
	if (g_trace == false)
	{
		set_visible(getObj("traitblanc"),  g_couleur)
		set_visible(getObj("traitnoir") , !g_couleur)
	}
}

// entoure une case donnée
function set_contour(col,lig)
{
	// encadre la case col,lig
	set_case("casev",col,lig)
}

// dessine une ligne horizontale sur la ligne lig de col1 à col2
function set_ligneh(col1,col2,lig)
{
	for (i=col1; i<= col2; ++i)
		set_case("lineh", i, lig)
}

// dessine une ligne verticale sur la colonne col de la ligne lig1 à lig 2
function set_lignev(col, lig1,lig2)
{
	for (i=lig1; i<= lig2; ++i)
		set_case("linev", col, i)
}

// renvoie le nom de la case a modifier a8,b8...
function get_idcase(col,lig)
{
	if (g_reverse)
	{
		lig = 9 - lig;
		return g_lettre[9-col] + lig;
	}
	else
		return g_lettre[col] + lig;
}

// positionne une image pour la case col,lig (a8..)
function set_piece(piece,col,lig)
{
	obj = document.getElementById(g_lettre[col] + lig)
	obj.src = g_path + piece + g_style
}

// positionne une image sur la case col,lig (a8..)
function set_case(piece,col,lig)
{
	obj = document.getElementById(get_idcase(col,lig))
	obj.src = g_path + piece + g_style
	g_occupe[ lig*8 + col] = piece
	if (!g_ie5)
   	obj.style.cursor ="pointer"
}

// positionne une image sur la case col,lig (a8..)
function set_case3(piece,col,lig) { document.getElementById(get_idcase(col,lig)).src = g_path + piece + g_style }

// vide une case
function vide_case(col,lig)
{
	var obj = document.getElementById(get_idcase(col,lig))
	obj.src = g_path_vide
	if (!g_ie5)
		obj.style.cursor ="default"
	g_occupe[ lig*8 + col] = null
}

// vide une case de la grille (point vert)
function vide_grille(col,lig) { set_visible(document.getElementById("g"+get_idcase(col,lig)),false) }
function vide_grille_point(col,lig) { set_visible(document.getElementById("g"+get_idcase(col,lig)),false) }
function init_grille_point(col,lig) { document.getElementById("g"+get_idcase(col,lig)).src = g_path_point }
function affiche_point(col, lig) { set_visible(document.getElementById("g"+get_idcase(col,lig)),true) }

function est_vide_grille(col,lig) {
	return document.getElementById("g"+get_idcase(col,lig)).style.visibility == "hidden"
}

// vide une case
function vide_case2(col,lig)
{
	obj = document.getElementById(get_idcase(col,lig))
	obj.src = g_path + "v.png"
	if (!g_ie5)
		obj.style.cursor ="default"
}

// positionne une image pour la case col,lig (a8..)
function joue_piece(piece,col,lig)
{
}

function set_case2(piece,col,lig,col1,lig1)
{
	set_case(piece,col,lig)
	vide_case(col1,lig1) // case de départ

	if (g_trace && col1) 	{
		affiche_point(col1, lig1) // marque la case quitter par la piece d'un point vert
	}
}

// joue une piece a la position col , lig (coordonn echiquier)
function joue_piece2(piece,col,lig,col1,lig1)
{
	set_case(piece,col,lig)
	g_occupe[ lig*8 + col] = piece

	if (g_trace && col1)
	{
		// marque la case quitter par la piece d'un point vert
		affiche_point(col1, lig1)
	}
}

// joue une piece sur la case x,y (casexy est une chaine ex "E4")
function move_piece1(piece, casexy_deb, casexy_fin)
{
	var col = (casexy_deb.charCodeAt(0) & 223) - 64  // code ascii de A = 65
	var lig = eval(casexy_deb.charAt(1))
	vide_case(col,lig)
	col = (casexy_fin.charCodeAt(0) & 223) - 64  // code ascii de A = 65
	lig = eval(casexy_fin.charAt(1))
	set_case(piece,col,lig)
}

// joue une piece sur la case x,y (casexy est une chaine ex "E4")
function joue_piece1(piece, casexy)
{
	var col = (casexy.charCodeAt(0) & 223) - 64  // code ascii de A = 65
	var lig = eval(casexy.charAt(1))
	set_case(piece,col,lig)
	g_occupe[ lig*8 + col] = piece
}

// retourne la couleur d'une piece (true si blanc)
function get_couleur(piece) { return piece.substr(1,1) == "b"	} // vrai si piece blanche

//-- recupère position graphique d'une piece
function get_pospiece(x, y , i, piece)
{
	x[i] = get_left(piece)
	y[i] = get_top(piece)
}

function montre_ligne(bDiag, bRangee, bColonne)
{
	if (getObj("diagonale"))
	{
		set_zindex(getObj("diagonale"), bDiag)
		set_zindex(getObj("rangee"), bRangee)
		set_zindex(getObj("colonne"), bColonne)
	}
}
function montre_centre(bMontre)
{
	if (bMontre)
	{
		set_case("angle1v",4,5)
		set_case("angle2v",5,5)
		set_case("angle3v",5,4)
		set_case("angle4v",4,4)
	}
}

// initialise la ligne ayant le focus dans la liste apprendre
function set_focus_apprendre(indice) { getObj("apprendre").selectedIndex = indice; }
function set_focus_probleme(indice) { getObj("probleme").selectedIndex = indice; }
function get_focus_action() { return getObj("apprendre").selectedIndex; }

function set_actiondemo(action,col,lig)
{
	cache_point_vert();

	if (action == 'leroi')
	{
		set_case("rb", col, lig)
		set_mouvement_roi(col, lig, true)
	}
	else if (action == "ladame")
	{
		set_case("db", col, lig)
		set_mouvement_dame(col,lig, true)
	}
	else if (action == "lefou")
	{
		set_case("fb", col, lig)
		set_mouvement_fou(col,lig, true)
	}
	else if (action == "lecavalier")
	{
		set_case("cb", col, lig)
		set_mouvement_cava(col,lig,true)
	}
	else if (action == "latour")
	{
		set_case("tb", col, lig)
		set_mouvement_tour(col,lig,true,0,0)
	}
	else if (action == 'lepion')
	{
	  set_case("pb", col, lig)
		set_mouvement_pion(col,lig, true, 0,0, true)
	}
}

// initialise une action ou scenario (echec perpertuel...)
function set_action(action,col,lig)
{
	if (action == "")
		return

	g_demo = false;

	if (action == "ouverture")
	{
		set_mode(4)
		return;
	}
	else if (action == "fenpgn")
	{
		set_mode(1)
		btn_fenpgn();
		return;
	}
	else if (action == "position")
	{
		set_mode(2)
		return;
	}
	else if (action == "probleme")
	{
		set_mode(3)
		return;
	}
	else if (action == "huitreines")
	{
		set_mode(3)
		set_focus_probleme(3)
		set_probleme(3*3)
		return;
	}
	else if (action == "parcourscavalier")
	{
		set_mode(3)
		set_focus_probleme(4)
		set_probleme(4*3)
		return;
	}
	else if (action == "finale")
	{
		set_mode(5)
		set_focus_apprendre(20)
		return;
	}

	// active le mode apprentissage
	if (action != "random")
    set_mode(5);

	vider()
	// lig : rangée  (de 1 à 8)
	// col : colonne (de A à H)

	// action pour les scénarios de finales
	if (action.charAt(0) <='9')	// action pour les finales
	{
		set_syn("finale.htm")
		var num = eval(action)
		if (num > 0)
		{
			if (num<=4)
				set_focus_apprendre(20+num)
			else
				set_focus_apprendre(20+num+1)

			lire_position_fen(g_finale[ (num-1)*2 ])  // lit la position en francais
			lire_partie(g_finale[ (num-1)*2+1 ],false)      // lit la solution
			set_debut(-1);	// revient au debut de la position
		}
	}
	// action pour la description de l'echiquier
	else if (action == 'echiquier')
	{
		set_syn("echiquier.htm")
	}
	else if (action.substr(0,4) == 'case')
	{
		set_syn("echiquier.htm")
		var col = (action.charCodeAt(5) & 223) - 64  // code ascii de A = 65
		var lig = eval(action.substr(6,1))
		set_contour(col,lig);
	}
	else if (action == 'rangee')
	{
		set_syn("echiquier.htm#rangee")
	   set_focus_apprendre(1)
		montre_ligne(false,true,false)
	}
	else if (action == 'colonne')
	{
	   set_syn("echiquier.htm#posinit")
	   set_focus_apprendre(2)
		montre_ligne(false,false,true)
   }
	else if (action == 'diagonale')
	{
    set_syn("echiquier.htm#diagonale")
	  set_focus_apprendre(3)
		montre_ligne(true,false,false)
	}
	else if (action == 'centre')
	{
		set_syn("echiquier.htm#centre")
	   set_focus_apprendre(4)
		montre_centre(true)
	}
	else if (action == 'posinit')	// position initiale des pieces
	{
	  set_syn("echiquier.htm#posinit")
	  set_focus_apprendre(5)
		set_nouveau()
	}
	// action pour le deplacement des pièces
	else if (action == 'deplacement')
	{
	   set_syn("pieces.htm")
	}
	else if (action == 'leroi')
	{
	   set_syn("pieces.htm#roi")
	   set_focus_apprendre(7)
	}
	else if (action == "ladame")
	{
	   set_syn("pieces.htm#dame")
	   set_focus_apprendre(8)
	}
	else if (action == "lefou")
	{
	   set_syn("pieces.htm#fou")
	   set_focus_apprendre(9)
	}
	else if (action == "lecavalier")
	{
	   set_syn("pieces.htm#cavalier")
	   set_focus_apprendre(10)
	}
	else if (action == "latour")
	{
	   set_syn("pieces.htm#tour")
	   set_focus_apprendre(11)
	}
	else if (action == 'lepion')
	{
		set_syn("pieces.htm#pion")
		set_focus_apprendre(12)
	}
	// action pour la description des regles
	else if (action == "regles")
	{
	   set_syn("regles.htm")
  }
	else if (action == "enpassant")
	{
	  set_syn("pieces.htm#enpassant")
		set_focus_apprendre(14)
		action_enpassant()
	}
	else if (action == "lapromotion")
	{
	  set_syn("pieces.htm#promotion")
		set_focus_apprendre(15)
		action_promotion()
	}
	else if (action == "lepetitroque" || action == "leroque")
	{
	   set_syn("pieces.htm#roque")
		set_focus_apprendre(16)
		action_roque(true)
	}
	else if (action == "legrandroque")
	{
	  set_syn("pieces.htm#roque")
		set_focus_apprendre(17)
		action_roque(false)
	}
	else if (action == "lepat")
	{
	  set_syn("regles.htm#pat")
		set_focus_apprendre(18)
		action_pat(0)
	}
	else if (action == "leperpetuel")
	{
	  set_syn("regles.htm#perpetuel")
		set_focus_apprendre(19)
		action_perpetuel(0)
	}
	else if (action == "random")
	{
		set_syn("divers.htm#randomchess")
		g_chess960 = true;
		set_nouveau();
		//g_chess960 = false;
	}

	if (action == "leroi" || action == "ladame" || action == "lecavalier" || action == "latour" ||
	    action == "lepion" || action == "lefou")
	{
		g_demo = true
		g_pieceaction = action;
		set_actiondemo(action,col,lig)
	}

}

// valide le deplacement d'une piece
function test_deplacement(pieceid, col,lig, col1, lig1, couleur, bTestEchec)
{
	// la case d'arrivée ne doit pas contenir une piece de même couleur sauf si roque pour chess960
	var piece = g_occupe[col1 + lig1*8]
	if (piece != null && !g_demo && couleur == get_couleur(piece))
  {
    if (g_chess960) // tst si roque valide en chess960
    {
      if (pieceid=="t" && piece[0]=='r')
        return true;
    }
    return false; // on ne capture pas ses pièces 
  }
	if (g_trace) // si point vert case occupe (cas parcours cavalier)
		if (!est_vide_grille(col1,lig1))
			return false;

	// la case d'arrivée doit etre valide par rapport au deplacement de la piece
	if (pieceid == "p")
	{
		if (set_mouvement_pion(col, lig, false, col1, lig1, couleur) == false)
			return false;
	}
	else if (pieceid == "f")
	{
		if (set_mouvement_fou(col, lig, false, col1, lig1) == false)
			return false;
	}
	else if (pieceid == "d")
	{
		if ( (set_mouvement_tour(col, lig, false, col1, lig1) == false) &&
		     (set_mouvement_fou(col, lig, false, col1, lig1)  == false)
		   )
			return false;
	}
	else if (pieceid == "t")
	{
		if (set_mouvement_tour(col, lig, false, col1, lig1) == false)
			return false;
	}
	else if (pieceid == "r")
	{
		if (set_mouvement_roi(col, lig, false, col1, lig1, couleur) == false)
			return false;
	}
	else if (pieceid == "c")
	{
		if (set_mouvement_cava(col, lig, false, col1, lig1) == false)
			return false;
	}

	// il ne doit pas avoir de pieces entre les deux cases (sauf pour le cavalier)
	if (!g_demo && (pieceid != "c") && test_presence_piece(col,lig, col1, lig1) )
		return false;

	// le roi ne doit pas etre mis en echec
	if (!g_demo && bTestEchec && test_roi_en_echec(pieceid, col, lig, col1, lig1, couleur))
		return false;

	return true;
}

// test si le roi est mis en echec sur le mouvement d'une piece
function test_roi_en_echec(pieceid, col,lig, col1, lig1, couleur)
{
	if (pieceid != "r")	// on deplace une piece autre que le roi
	{
		// recherche position du roi sur l'échiquier
		var roi ="r"
		roi += couleur?"b":"n"
		case_id  = get_case(roi);
		if (case_id != null)
		{
			col_roi  = (case_id.charCodeAt(0) & 223) - 64  // code ascii de A = 65
			lig_roi  = eval(case_id.charAt(1))
		}
		else
			return false;
	}
	else // le roi se déplace en col1,lig1
	{
		col_roi = col1
		lig_roi = lig1
	}

	// a optimiser en utilisant un tableau des pieces presentes sur l'echiquier
	// pour toutes les pieces adverses test si le roi est attaqué
  var en_passant =false;
  var sauve_pion;
  var lig_capture = lig1;

	if ((pieceid == "p") && (col!= col1) && (g_occupe[ lig1*8 + col1]==null))
	{
		en_passant = true
		couleur ? --lig_capture : ++lig_capture
    sauve_pion = g_occupe[col1 + lig_capture*8];
    g_occupe[col1 + lig_capture*8] = null;		
	}

	var sauve_piece  = g_occupe[col + lig*8];  // deplace temporairement la piece
	g_occupe[col+ lig*8]   = null;				 // pour tester mise en echecs

	var sauve_piece1 = g_occupe[col1+ lig1*8]; // sauve piece en col1,lig1
	g_occupe[col1+ lig1*8] = sauve_piece;

	// test si le roi est en echec
	bechec = test_roi_en_echec1(col_roi, lig_roi, !couleur)

	g_occupe[col+ lig*8]   = sauve_piece
	g_occupe[col1+ lig1*8] = sauve_piece1
	if (en_passant)
	   g_occupe[col1 + lig_capture*8] = sauve_pion;

	return bechec
}

// test si le roi est en echec
function test_roi_en_echec1(col_roi,lig_roi, couleur)
{
	// parcours tout l'echiquier
	for (i=1; i<=8; ++i)
		for (j=1 ; j<=8; ++j)
		{
			// regarde si la piece met en echec le roi
			piece = g_occupe[j + i*8]
			if (piece != null && (get_couleur(piece) == couleur))
			{
				if (test_deplacement(piece.substr(0 ,1), j, i , col_roi, lig_roi, couleur, false))	// si vrai la piece attaque le roi
					return true
			}
		}
	return false
}

// retourne vrai si une piece est presente entre col,lig et col1,lig1
function test_presence_piece(col,lig, col1, lig1)
{
	var piece = null;
	var delta = 1;
	var inv   = false

	if (col1 < col)
	{
		aux = col; col = col1; col1 =aux; inv = true
	}

	if ( (col1 - col)>=2 && Math.abs(lig1 - lig)>=2)
	{
		// deplacement en diagonale
		if ( (!inv && (lig1 < lig)) || (inv && (lig1 > lig)) )
			delta = -1;

		if (lig1 < lig)
			(delta == 1) ? yy = lig1 + delta : yy = lig  + delta
		else
			(delta == 1) ? yy = lig  + delta : yy = lig1 + delta

		for (xx=col+1; xx<col1; ++xx)	// parcours les colonnes
		{
			if (g_occupe[xx+yy*8] != null)
				return true;
			yy += delta
		}
	}
	else if ((col1 - col)>=2)	// deplacement horizontale sur une rangée
	{
		for (xx=col+1; xx<col1; ++xx)	// parcours les colonnes
		{
			if (g_occupe[xx+lig*8] != null)
				return true;
		}
	}
	else if  (Math.abs(lig1 - lig)>=2)	// deplacement verticale sur une colonne
	{
		if (lig1 < lig)
		{
			aux = lig; lig = lig1; lig1 =aux
		}
		for (yy=lig+1; yy<lig1; ++yy)	// parcours les colonnes
		{
			if (g_occupe[col+yy*8] != null)
				return true;
		}
	}

	return false
}

// test si roi et tour sur leur case initiale
function test_roque(bCouleur, bPetitRoque)
{
  var lig = 8;
  var col = 1;
  if (bCouleur)
    lig = 1
  if (bPetitRoque)
    col = 8;
  var tour = (bCouleur) ? "tb":"tn"
  
	return g_occupe[col+lig*8]==tour;
}

// calcule mouvement valide pour le roi
function set_mouvement_roi(col,lig, display, col1, lig1, couleur)
{
	if (display == false)
	{
		// deplacement d'une case dans une direction quelconque
		if ( (Math.abs(col1-col)<=1) && (Math.abs(lig1-lig) <= 1))
			return true;

		// cas du roque : roi et tour ne doivent pas avoir bouger
		if (!g_demo && !g_chess960)
		{
			if ( (lig1==lig) && (col==5) && (Math.abs(col1-col)==2) && (g_occupe[col1+lig1*8]==null) && test_roque(couleur, col1 != 3) &&
				  ((col1 != 3) || (g_occupe[col1-1+lig1*8]==null) )	&& // grand roque colone 2 doit etre vide
				  !(test_roi_en_echec1(col,lig,!couleur)) && // roi n'est pas en échec
				  !test_roi_en_echec("r", col,lig, (col1 != 3)?col1-1:col1+1, lig1, couleur) ) // pas de case echec
				return true
		}
	}
	else
	{
		// marque d'un rond vert les cases accessible par le roi.
		for (xx=col-1; xx<=col+1; ++xx)	// parcours colonne
			for (yy=lig-1; yy<= lig+1; ++yy)	// parcours ligne
				if ( !((xx==col) && (yy==lig)) && (xx >= 1) && (xx <= 8) && (yy >= 1) && (yy <= 8))
					affiche_point(xx, yy)
	}
	return false;

}

// calcule mouvement valide pour le pion
function set_mouvement_pion(col,lig, display, col1, lig1, couleur)
{
	if (display == false)
	{
		if (col==col1 && (g_occupe[col1 + lig1*8] == null) ) // pion avance case doit etre libre
		{
			if (  (  couleur && ( (lig1-lig==1) || ((lig==2) && (lig1-lig==2)) ) )  ||  // pion blanc
					( !couleur && ( (lig-lig1==1) || ((lig==7) && (lig-lig1==2)) ) )  )  // pion noir
					return true
		}
		else if (Math.abs(col1-col)==1)	// pion prend en diagonale en avancant, case ne doit pas etre vide
		{
			if  ( (  couleur && (lig1-lig==1) && (g_occupe[col1 + lig1*8] != null) ) ||
				   ( !couleur  && (lig-lig1==1) && (g_occupe[col1 + lig1*8] != null) ) )
				   return true

			//cas de la prise en passant
			if (g_occupe[col1 + lig1*8] == null)
			{
				if ((couleur && lig==5) || (!couleur && lig==4))
				{
					coup_avant = g_nc - 6	// test si coup precedent pion avance de 2 cases
					if ( (g_p[coup_avant].substr(0,1) == "p") && (col1==g_p[coup_avant+1]) &&	(Math.abs((g_p[coup_avant+2]-g_p[coup_avant+5]))==2) )
					{
						return true
					}
				}
			}
		}
	}
	else // affiche les déplacements possible du pion
	{
		couleur ? n=1 : n=-1
		if (lig != 8)
		{
			affiche_point(col, lig+n*1);
			if ((couleur && lig == 2) || (!couleur && lig == 7)) // pion sur case de départ
				affiche_point(col, lig+n*2)
			// pion prend en diagonale
			if  ( g_occupe[col-1 + (lig+n*1)*8] != null )
				affiche_point(col-1, lig+n*1)
			if (g_occupe[col+1 + (lig+n*1)*8] != null )
   			affiche_point(col+1, lig+n*1)
		}
	}

	return false
}

// ---------------------------------------------------
// --- reverse la position de l'échiquier
// ---------------------------------------------------
function reverse(breverse)
{
	g_reverse = breverse
	init_case(g_reverse)	// reinitialise coordonnées des cases

	// change le témoin de trait
	aux = get_left(getObj("traitblanc"))
	set_left(getObj("traitblanc"), get_left(getObj("traitnoir")))
	set_left(getObj("traitnoir"), aux)

	aux = get_top(getObj("traitblanc"))
	set_top(getObj("traitblanc"), get_top(getObj("traitnoir")))
	set_top(getObj("traitnoir"), aux)

	// redessine les pieces
	for (i=1; i<=8; ++i)
		for (j=1 ; j<=8; ++j)
		{
			piece = g_occupe[j + i*8]
			if (piece != null)
				set_case3(piece,j,i)
			else
				vide_case(j,i)
		}

}

//----- reinitialise le cadre historique
function init_historique()
{
	// efface cadre notation
	ecrire_cadrepartie("")	// efface cadre partie

	g_nc = 0			// numero du coup courant
	g_coup_joue = 0  		// nombre de coup joue
	g_pieceaction = null;
	g_demo	     = false  // tous les controles de deplacement sont actifs
}

// renvoie position au hasard sur case libre restante
function get_pos_random(nb_pos_libre, random_free)
{
	var pos = nb_pos_libre;
	if (pos>0)
		pos = Math.round(Math.random()*(nb_pos_libre-1));
	// cherche pos ieme case libre
	var nb_libre = 0;
	var i;
	for (i=1; i<=8; ++i)
	{
		if (random_free[i]==false)
			++nb_libre;
		if (nb_libre>pos)
			break;
	}
	random_free[i]=true;
	return i;
}

// ---------------------------------------------------
// initialise une nouvelle partie
// ---------------------------------------------------
function set_nouveau()
{
	// met à zero l'historique
	init_historique()

	// initialise les coordonnées pour accéder à l'échiquier
	init_case(g_reverse)
	set_couleur(true)

	// cache les points verts
	montre_ligne(false,false,false)
	cache_point_vert()

	// initialize tableau occupe
	for (lig=8; lig>=1; --lig)
		for (col=1; col<=8; ++col)
			g_occupe[lig*8 + col] = null

  g_random_tab  = new Array(0,1,2,3,4,5,6,7,8);

	if (g_chess960)	// position des pieces aleatoire
	{
		// tableau indiquant le numero de colonne
		// par défaut pos  standard :   T C F D R F C T
		var random_free = new Array(false,false,false,false,false,false,false,false,false);

		// position completement aléatoire :
		/*var aux;
		for (k=0; k<8; ++k)	// melange le tableau
		{
			k1 = Math.round(Math.random()*7);
			aux = g_random_tab[k];	g_random_tab[k] = g_random_tab[k1];	g_random_tab[k1] = aux;
		}*/

		// position avec contrainte du Fischer Random Chess
		// positionne le fou de case noir
		g_random_tab[3] = (Math.round(Math.random()*3)) * 2 + 1;
		random_free[g_random_tab[3]] = true;
		// positionne le fou de case blanche
		g_random_tab[6] = (Math.round(Math.random()*3)+1) * 2;
		random_free[g_random_tab[6]] = true;
		// positionne les cavaliers
		g_random_tab[2] = get_pos_random(6,random_free);
		g_random_tab[7] = get_pos_random(5,random_free);
		// positionne la dame
		g_random_tab[4] = get_pos_random(4,random_free);
		// positionne tour, roi , tour
		g_random_tab[1] = get_pos_random(0,random_free);
		g_random_tab[5] = get_pos_random(0,random_free);
		g_random_tab[8] = get_pos_random(0,random_free);
	}

	// positionne les pieces
	var num_piece = 0;
	// pieces noir
	for (col=1; col<=8; ++col)
		set_case(g_pos_init.charAt(num_piece++)+"n", g_random_tab[col], 8)	// pieces noires
	for (col=1; col<=8; ++col)
		set_case(g_pos_init.charAt(num_piece++)+"n", col, 7) // pions noirs

	// vide les case du milieu de l'échiquier
	for (lig=3; lig<=6; ++lig)
		for (col=1; col<=8; ++col)
			vide_case(col, lig)
	// pieces blanches
	for (col=1; col<=8; ++col)
		set_case(g_pos_init.charAt(num_piece++)+"b", col, 2) // pions blancs
	for (col=1; col<=8; ++col)
		set_case(g_pos_init.charAt(num_piece++)+"b", g_random_tab[col], 1) // pieces blanches

}

// ecrit le coup dans la feuille de match
function ecrire_cadrepartie(coup, i)
{
	var line = new String;

	// notation html, feuille de match
	if (coup == "")	// efface toute la notation
	{
		if (g_lastcel) g_lastcel.style.background = g_bc;

		for (i=1; i<=g_mc; ++i)
			getObj("n"+i).innerHTML=""
	}
	else
	{
		// ajout <a onclick="gomv(i)" href="javascript:go()">
		num_demi = i/6 + 1 // numero de demi_coup
		line = line + '<a class="notahtml" onclick="GoMv(' + num_demi + ')" href="javascript:go()">'
		line+= coup + '</a>';

		getCel(num_demi).innerHTML = line;
		set_courant(num_demi);
	}
}

function set_courant(coup) {
	if (g_load) return
	if (g_lastcel)
		g_lastcel.style.background = g_bc;
	if (coup) {
		getCel(coup).style.background = g_sc;
		g_lastcel = getCel(coup); }
}

function get_left(piece) { return parseInt(piece.style.left); }
function get_top(piece)  {	return parseInt(piece.style.top);  }
function set_left(piece, left) {	piece.style.left = left+"px"; }
function set_top(piece, top)   { piece.style.top = top+"px";   }

// retrouve une piece sur l'échiquier
function get_case(piece)
{
	for (lig=8; lig>=1; --lig)
		for (col=1; col<=8; ++col)
			if (g_occupe[lig*8 + col] == piece)
				return g_lettre[col]+lig;
	return null;
}

// retourne la colonne
function get_case_col(x) { if (g_reverse) return 8 - Math.floor( (x - g_orig_x) / g_cote); else return Math.floor( (x - g_orig_x) / g_cote) + 1;}
// retourne la ligne
function get_case_lig(y) { if (g_reverse) return Math.floor( (y - g_orig_y) / g_cote) + 1; else return 8 - Math.floor( (y - g_orig_y) / g_cote);}

// retourne la colonne
function get_col(piece)
{
	if (g_reverse)
		return 8 - Math.floor( (get_left(piece) + (g_cote/2) - g_orig_x) / g_cote);
	else
		return Math.floor( (get_left(piece) + (g_cote/2) - g_orig_x) / g_cote) + 1;
}

// retourne la ligne
function get_lig(piece)
{
	if (g_reverse)
		return Math.floor( (get_top(piece) + (g_cote/2) - g_orig_y) / g_cote) + 1;
	else
		return 8 - Math.floor( (get_top(piece) + (g_cote/2) - g_orig_y) / g_cote);
}

// appeler pour gerer le curseur de la souris
function init_cursor_id(id,col,lig)
{
	if (id == null)
		return false;
	if (onboard(col,lig)) // element sur l'échiquier
	{
		g_cursor_id = g_occupe[col+lig*8]
		if (g_cursor_id != null)	// presence d'une piece
			return true;
	}
	else if (id.substr(0,1) == "_") // element de la boite (mode position)
	{
		g_cursor_id = id.substr(1,2)
		return true;
	}

	return false // element non deplacable
}

function doKeyDown1(e)
{
	var i
	if (g_net)
	{
		/*
		Alt only              modifiers=1 (001)
		Ctrl only             modifiers=2 (010)
		Ctrl+Alt              modifiers=3 (011)
		Shift only            modifiers=4 (100)
		Shift+Alt             modifiers=5 (101)
		Shift+Ctrl            modifiers=6 (110)
		Shift+Alt+Ctrl        modifiers=7 (111)
		None of these keys    modifiers=0 (000)
		*/

		i = e.which
		//if (e.modifiers == Event.ALT_MASK)
		//	alert("alt")
	}
	else
	{
		//altKey ctrlKey shiftKey
		i = event.keyCode
	}
}


function doKeyDown(e)
{
	if (!g_rac || g_dal) // raccourci non activé
		return;

	var ev = e || event;
	if (ev.ctrlKey || ev.altKey)
		return;
	var i;
	if (g_net) { i = e.which } else { i = event.keyCode }

	if (i>=33 && i<40 && i!=38)
	{
		if (i==37) set_arriere();
		else if (i==39) set_avant();
		else if (i==35) set_fin(-1); //fin
		else if (i==36) set_debut(-1); //debut
		else if (i==38) ; // haut
		else if (i==40) ; // bas
		else if (i==33) ; // page haut
		else if (i==34) ; // page bas

		g_stopkeypress = true;
		return false;
   }
}

// gestion des raccourcis clavier
function doKeyPress(e)
{
	if (g_stopkeypress)
	{
		g_stopkeypress = false;
		return false;
	}

	//ALT_MASK, CONTROL_MASK, SHIFT_MASK (majuscule), and META_MASK (Alt Gr).
	var i
	if (g_net) { i = e.which } else { i = event.keyCode }

  if (g_dal && i==13)
  {
    if (g_cadrefenpgn) { lire(); return false }
  }

	if (!g_rac || g_dal) // raccourci non activé
		return;

	var ev = e || event;
	if (ev.ctrlKey || ev.altKey)
		return;


	if (i>=65 || i<= 90) // touche a à z
	{
		var c = String.fromCharCode(i & 223);
		if (c=='C') 	  btn_opts();   //options
		else if (c=='I') { btn_fenpgn(); return false } //Import/export
		
		else if (c=='N') { set_nouveau(); return false } //Nouvelle partie
		else if (c=='V') { vider(); return false } //vide echiquier
		else if (c=='T') { reverse(g_reverse=!g_reverse); return false } //tourne l'échiquier
		
		else if (c=='P') { set_mode(1); return false }  //partie
		else if (c=='S') { set_mode(2); return false } //Setup (position)
		else if (c=='E') { set_mode(3); return false } //Exercice (probleme)
		else if (c=='O') { set_mode(4); return false } //Ouverture
		else if (c=='A') { set_mode(5); return false } //Apprendre
		else if (c=='D') { set_mode(6); return false } //Database
	}
}

// clic gauche sur la souris
function doMouseDown(e) {
	if (g_dal)
		return;

	var curElement = null;
	var curSrc=null;
	g_col_start=0;
	g_lig_start=0;
	var id;

	if (getObj("echiquier1").style.zIndex==-1)
		id="aveugle"
	else
	{
		if (g_net) id = e.target.id; else id = event.srcElement.id
		if (id=="")
			return;
	}

	if (g_setup)
	{
		// en mode setup permet de choisir le trait (bascule en cliquant sur le temoin)
		if (id.substr(0,5) == "trait")
		{
			set_couleur(id != "traitblanc")
			return;
		}
	}

	if (g_net)
	{
		// recupere coordonnée de depart
		g_col_start = get_case_col(e.pageX)
		g_lig_start = get_case_lig(e.pageY)

		if (!init_cursor_id(id, g_col_start, g_lig_start))
			return;

		// source courante
		if (getObj("echiquier1").style.zIndex==-1) //mode aveugle
			curSrc = g_path_vide
		else
		{
			curElement = document.getElementById(id)
			curSrc = curElement.src
		}
		g_mouX  = e.pageX + g_curX;
		g_mouY  = e.pageY + g_curY;
	}
	else if (event.button==1) // clic gauche sur la souris, selection d'une piece
	{
		// recupere coordonnée de depart
		g_col_start = get_case_col(event.clientX + document.body.scrollLeft)
		g_lig_start = get_case_lig(event.clientY + document.body.scrollTop)
		if (! init_cursor_id(id, g_col_start, g_lig_start))
			return;

		// source courante
		if (getObj("echiquier1").style.zIndex==-1) //mode aveugle
			curSrc = g_path_vide
		else
		{
			curSrc = event.srcElement.src
			curElement = event.srcElement
		}

		g_mouX  = event.clientX + document.body.scrollLeft + g_curX;
		g_mouY  = event.clientY + document.body.scrollTop  + g_curY;
	}
	else
		return

	// si c'est une piece
	// verifie que l'on joue la bonne couleur
	if (g_demo || g_trace || g_setup || g_couleur == get_couleur(g_cursor_id))
	{
		g_noclic = false;

		// initialise image cursor
		set_left(g_cursor, g_mouX)
		set_top(g_cursor, g_mouY)
		g_cursor.src = curSrc
		g_cursor.style.zIndex = 15;
		//g_cursor.style.visibility = "visible";

		// vide la case de depart
		if (onboard(g_col_start, g_lig_start))
			if (getObj("echiquier1").style.zIndex!=-1)
				curElement.src = g_path_vide

		return false;
	}

	reset_cursor();
}

// gere le deplacement d'une piece avec la souris
function doMouseMove(e)
{
	var newleft=0, newTop = 0
	if (g_noclic)
		return

	if (g_net)
	{
		newleft =  g_curX + e.pageX
		newtop  =  g_curY + e.pageY
	}
	else //if ((event.button==1))
	{
		newleft= g_curX + event.clientX + document.body.scrollLeft;
	  	newtop= g_curY + event.clientY + document.body.scrollTop;
   }

	// limite le deplacement
	if (newleft<0) newleft=0
	if (newleft>410) newleft = 410
	set_left(g_cursor, newleft)
	if (newtop<0) newtop=0
	if (newtop > 350) newtop = 350
	set_top(g_cursor, newtop)

   return false;
}

// souris relachée - le joueur pose la piece
function doMouseUp()
{
	if (g_dal)
		return;

	g_noclic = true;

	// recupere case d'arrivée
	var col = get_col(g_cursor);
	var lig = get_lig(g_cursor);

	// mode de saisie d'une position
	if (g_setup)
	{
		if (g_cursor_id == null)
		{
			if (onboard(g_col_start,g_lig_start))
			{
				g_cursor_id = g_last_id
				set_case(g_last_id, g_col_start, g_lig_start)
				reset_cursor();
			}
		}
		else
		{
			positionne_piece(g_cursor_id, g_col_start, g_lig_start, col, lig)
			reset_cursor();
		}

		return
	}

	if (g_cursor_id == null)
		return;

	// valide le deplacement
	if ((g_col_start == col && g_lig_start == lig) || // piece relachée sur même case
           !onboard(col,lig) )   // piece en dehors de l'échiquier
	{
		// remet la piece sur sa case de départ et annule le deplacement
		set_case(g_cursor_id, g_col_start, g_lig_start)
		reset_cursor();
		return
	}

	// test que le déplacement de la piece est valide
	if (!test_deplacement(g_cursor_id.substr(0 ,1), g_col_start,g_lig_start, col, lig, g_couleur, true))
	{	// remet la piece sur sa case de départ et annule le deplacement
		set_case(g_cursor_id, g_col_start, g_lig_start)
		reset_cursor();
		return
	}

	var cursor_id = g_cursor_id;
	reset_cursor(); // a faire ici pour effacer piece avec choix promotion

	// joue et enregistre le coup, change le trait
	enregistre_coup(cursor_id,g_col_start,g_lig_start, col, lig, null, g_couleur)

	if (g_pieceaction) //appele pour afficher les points verts indiquant les déplacement possible pour une piece
		set_actiondemo(g_pieceaction, col, lig,false)

	// ecrit le coup dans la textarea
	ecrire_coup_joue(!g_couleur, g_coup_joue)	// la couleur du trait a été changer dans enregistre_coup
}


function reset_cursor()
{
	g_last_id   = g_cursor_id
	g_cursor_id = null;
	g_cursor.style.zIndex = -10;
	g_cursor.src = g_path_vide
	set_left(g_cursor, get_left(g_cursor))
}

//--- enregistre et joue le coup dans le tableau partie
function enregistre_coup(pieceid,col_start,lig_start, col, lig, piecepromo, couleur)
{
	lettrepiece = pieceid.substr(0 ,1)
	// g_p[0] = id piece deplace + id piece capture
	// g_p[3] Type d'action :
	//   action vide             -1 (noir joue en premier)
 	//   deplacement simple       0 D
  //   deplacement avec capture 1 X
  //   prise en passant         2 E
  //   petit roque              3 o
  //   grand roque              4 O
  //   promotion                5 p
  //   promotion avec capture   6 P

	// cas particulier ou le premier coup est noir
	if (!couleur && g_nc==0)
	{
		// enregistre un coup vide
		g_p[g_nc]   = "."
		g_p[g_nc+3] = -1
		g_nc += 6
		ecrire_coup_joue(couleur, g_nc)
	}

	// stocke la case de départ
	g_p[g_nc+1] = col_start
	g_p[g_nc+2] = lig_start
	g_p[g_nc+3] = 0	// par defaut deplacement simple
	g_p[g_nc+4] = col
	g_p[g_nc+5] = lig

	// gere la capture d'une piece
	var lig_capture = lig
	var en_passant = false;

	// test si prise en passant
	if ((lettrepiece == "p") && (col_start!= col) && (g_occupe[ lig*8 + col]==null))
	{
		en_passant = true
    couleur ? --lig_capture : ++lig_capture
	}

	var occupe = g_occupe[ lig_capture*8 + col]
	if (en_passant)
		vide_case(col,lig_capture)	// libere la case du pion capturé

	set_case2(pieceid, col, lig, col_start, lig_start) // déplace la pièce

	// cas de la promotion d'un pion
	if ( (piecepromo == null) && (lettrepiece == "p") && (lig==1 || lig==8))
	{
		choix = ChoisirPromotion(couleur)
		piecepromo = get_piece_from_lettre(choix)

		if (g_demo) //appele pour afficher les points verts indiquant les déplacement possible pour une piece
		{
			g_pieceaction = get_action_from_lettrepromo(choix);
			set_actiondemo(g_pieceaction, col, lig,false)
		}
	}

	if (piecepromo != null)	// promotion d'une piece
	{
		set_case(piecepromo, col, lig)
		pieceid += piecepromo
		g_p[g_nc+3] = 5
	}

  var b_roque =false;

	// enregistre le coup dans le tableau g_p
	if (occupe != null)	// capture d'une piece
	{
		if (piecepromo == null)
		{
			if (en_passant)
				g_p[g_nc+3] = 2
			else
			{
			  if (g_chess960 && ((pieceid=="tn" && occupe=="rn")||(pieceid=="tb" && occupe=="rb")))
			    b_roque = true; // on pose la tour sur le roi pour roquer
        else
				  g_p[g_nc+3] = 1
			}	
		}
		else
		{
      g_p[g_nc+3] = 6
		}
		pieceid += occupe
	}
	else
	{
		// cas du roque standard, il faut jouer la tour
		if ((Math.abs(col - col_start) == 2) && lettrepiece == "r")
		  b_roque = true;
	}

  if (b_roque)
  {
    (test_petit_roque(col_start,col)) ? pr = 2 : pr = 1		// petit roque pr = 2 (tour 2)
    var tour = (couleur) ? "tb":"tn"
    var roi  = (couleur) ? "rb":"rn"
    vide_case( ((pr==2) ? g_random_tab[8] : g_random_tab[1]), lig) // vide case de la tour
    if (g_chess960)
    {
  		vide_case( col, lig) // vide case du roi
		  set_case(roi,  (pr==2) ? 7 : 3, lig)
		  pieceid += roi; // stocke le roi comme piece capturée pour retour arriere
  	}
  	else
      pieceid += tour; // stocke la tour comme piece capturée pour retour arriere

    set_case(tour, (pr==2) ? 6 : 4, lig)
		if (pr==2) { g_p[g_nc+3] = 3 } else { g_p[g_nc+3] = 4 } // 3 petit roque, 4 grand roque
  }

	g_p[g_nc] = pieceid   // piece joue

  // mise à jour possibilité de roque
  

	g_nc += 6; // debut coup suivant

	if (g_nc > g_coup_joue)
		g_coup_joue = g_nc		// met a jour le nombre de coup joue
	else	// nouveau coup, on met a jour le cadre notation jusqu'a ce coup
	{
		mettre_a_jour_notation(g_nc-6)
		g_coup_joue = g_nc		// met a jour le nombre de coup joue
	}

	// change la couleur a jouer
	if (!g_demo) // && !g_trace)
		change_couleur()	// modifie variable globale g_couleur
}

function test_petit_roque(col_deb,col_fin)
{
  return g_chess960 ? col_deb>col_fin : col_fin>col_deb
}

function onboard(col,lig) { return (col>=1 && col<=8 && lig>=1 && lig<= 8) }

//-- mode position
function positionne_piece(piece, col_start, lig_start, col, lig)
{
	// si piece deplace sur l'échiquier libère case de départ
	if (onboard(col_start, lig_start))	// piece sur l'echiquier
		g_occupe[ col_start + lig_start*8 ] = null
	if (onboard(col,lig))
		set_case(piece,col,lig)
}

// retourne la lettre en fonction de l'identifiant de la piece
function getlettrefrompiece(piece, lettrepiece)
{
	// retourne la lettre correspondand à la piece
	return lettrepiece.substr(g_lettreidpiece.search(piece),1);
}

// retourne la lettre identifiant une piece defini avec g_lettreidpiece
function get_pieceid_from_lettre(lettre)
{
	var piece = null;
	piece = g_lettreidpiece.substr(g_lettrepiece.search(lettre),1);
	return piece;
}


// recherche_deplacement a partir d'une notation abregée ex Cf3
function recherche_deplacement(dep, couleur)
{
	str = null;
	var str_piece = new String;
	var piece     = new String;
	var ambi_col  = 0;
	var ambi_lig  = 0;
	if (dep.charAt(0) >= 'A' && dep.charAt(0) <= 'Z') // deplacement d'une piece
	{
		var ind = 1;
		if (dep.charAt(1) == 'x')
			++ind
		else if (dep.charAt(2) == 'x')	// prise avec ambiguité (Cbxc3)
		{
			if (dep.charAt(1) <= '8')
				ambi_lig = eval(dep.charAt(1))	// leve ambiquite sur colonne
			else
			   ambi_col = (dep.charCodeAt(ind) & 223) - 64 // leve ambiguite sur rangée

			ind+=2;
		}
		else if (dep.charAt(1) <= '8') // cas d'ambiguité sur rangee
		{
			ambi_lig = eval(dep.charAt(1))
			ind+=1;
		}
		else if ( (dep.charAt(1) >= 'A') && (dep.charAt(2) >= 'A') ) // cas d'ambiguité sur colonne
		{
			ambi_col = (dep.charCodeAt(ind) & 223) - 64
			ind+=1;
		}

		var col = (dep.charCodeAt(ind) & 223) - 64  // code ascii de A = 65
		var lig = eval(dep.substr(ind+1,1))

		piece = get_pieceid_from_lettre(dep.charAt(0));

		// cas particulier du mode trace
		if (g_trace)
		{
			// on deplace une seul piece (ex : remplissage cavalier)
			piece += "b";	// piece blanche

			case_id  = get_case(piece);
			if (case_id != null)
			{
				col_p  = (case_id.charCodeAt(0) & 223) - 64  // code ascii de A = 65
				lig_p  = eval(case_id.charAt(1))
				str = g_lettre[col_p] + lig_p + '-' + g_lettre[col] + lig
			}
			else
				alert("error")
			return str;
		}

		if (couleur)
			piece += "b"
		else
			piece += "n"

		// recherche la piece sur l'echiquier
		for (lig_p=8; lig_p>=1; --lig_p)
			for (col_p=1; col_p<=8; ++col_p)
				if (g_occupe[lig_p*8 + col_p] == piece)
				{
					if (ambi_col==0 || ambi_col == col_p)
					{
						if (ambi_lig==0 || ambi_lig == lig_p)
						{
							if (test_deplacement(piece.substr(0,1), col_p, lig_p , col, lig, couleur, true))	// vrai si déplacement possible
							{
								str = g_lettre[col_p] + lig_p + '-' + g_lettre[col] + lig
								return str
							}
						}
					}
				}

	}
	else	// deplacement d'un pion
	{
		ind = 0;
		col_d = (dep.charCodeAt(ind) & 223) - 64;  // colonne de depart

		if (dep.substr(1,1) == 'x')	// indique une prise
			ind += 2

		var col = (dep.charCodeAt(ind) & 223) - 64;  // code ascii de A = 65
		var lig = eval(dep.charAt(ind+1));

		var piece = null;
		if (couleur)
			piece = "pb"
		else
			piece = "pn"

		// test si promotion
		var promo = "";
		if (dep.length >= 5 && dep.charAt(2)!='+') // fxg8D
		{
			promo = dep.substr(dep.charAt(4)=='='?5:4,1)
		}
		else if (dep.substr(1,1) != 'x' && dep.length >= 3 && dep.charAt(2)!='+') // e8D
		{
			promo = dep.substr(dep.charAt(2)=='='?3:2,1)
		}

		// pas de lettre pour un pion
		for (lig_p=8; lig_p>=1; --lig_p)
			for (col_p=1; col_p<=8; ++col_p)
				if (g_occupe[lig_p*8 + col_p] == piece)
				{
					if (col_p != col_d)
						continue
					if (test_deplacement(piece.substr(0,1), col_p, lig_p , col, lig, couleur, true))	// vrai si déplacement possible
					{
						str = g_lettre[col_p] + lig_p + '-' + g_lettre[col] + lig
						return str + promo
					}
				}
	}

	return str
}

//-- determine le langage (francais (defaut) RDFCT ou anglais KQBNR )
function set_langage(str)
{
	if ((str.search('N') != -1) || (str.search('B') != -1) ||
	    (str.search('Q') != -1) || (str.search('K') != -1) )
	{
		// langue us
		g_lettrepiece = g_lettrepiece_us
		getObj("R4EN").checked = true
	}
	else
	{
		g_lettrepiece = g_lettrepiece_fr
	  getObj("R4FR").checked = true
	}
}

function set_o960(b960)
{
	if (b960){
		// langue us
		g_chess960 = true
		getObj("R5ALE").checked = true
	}
	else
	{
		g_chess960 = false;
	  getObj("R5STD").checked = true
	}
}


//---- Renvoie le coup joue en notation complete e1-e4
function get_notation_complete(dep, couleur)
{
	r = dep.search("-"); // si present c'est une notation complete
	if ((r == -1) &&  !(dep.charAt(2)=='x' && dep.charAt(0)>='a') &&
	    !(dep.length >=6 && dep.charAt(3)=='x') )
		return recherche_deplacement(dep, couleur)

	// verifie que le coup n'est pas en notation complete de la forme Cg1-f3
	// dans ce cas supprime la première lettre
	if (dep.charAt(0)>='A'	&& dep.charAt(0)<='Z')
		return dep.substr(1)

	return dep;
}

// deplace une piece, couleur = true si blanc
// utilise lors de la lecture d'une partie
function deplace_piece(dep, couleur)
{
	var pr = dep.substr(0,3)
	var gr = dep.substr(0,5)
	if (gr == "O-O-O" || gr == "o-o-o" || gr == "0-0-0") // grand roque
	{
		var lig = (couleur?1:8)
		piece = g_occupe[ g_random_tab[g_chess960?1:5] + lig*8 ] // il doit y avoir une piece
		if (piece == null)
			return false
		if (g_chess960)
		  enregistre_coup(piece, g_random_tab[1] ,lig, g_random_tab[5], lig, null, couleur) // tour sur roi
    else
		  enregistre_coup(piece, 5 ,lig, 3, lig, null, couleur)
	}
	else if (pr == "O-O" || pr == "o-o" || pr == "0-0")	// petit roque
	{
		var lig = (couleur?1:8)
		piece = g_occupe[ g_random_tab[g_chess960?8:5] + lig*8 ] // il doit y avoir une piece
		if (piece == null)
			return false
		if (g_chess960)
		  enregistre_coup(piece, g_random_tab[8] ,lig, g_random_tab[5], lig, null, couleur) // tour sur roi
    else
		  enregistre_coup(piece, 5 ,lig, 7, lig, null, couleur)
	}
	else
	{
		// détermine si notation algébrique abrégée ou complète
		dep = get_notation_complete(dep, couleur);

		// coup en notation algébrique complète  xy-xy
		if (dep != null)
		{
		   // extrait case de depart
			var col = (dep.charCodeAt(0) & 223) - 64  // code ascii de A = 65
			var lig = eval(dep.charAt(1))
			// extrait case d'arrivée
			var casexy = dep.substr(3,2)
			var col1 = (dep.charCodeAt(3) & 223) - 64  // code ascii de A = 65
			var lig1 = eval(casexy.charAt(1))

			piece = g_occupe[ col + lig*8 ] // il doit y avoir une piece
			if (piece == null)
				return false

			piecepromo = null;
			// cas de la promotion
			if (dep.length >=6  && dep.charAt(5) != '+')	// c'est une promotion
			{
				var i = 5;
				if (dep.charAt(i) == '=')
					++i
				lettre = get_pieceid_from_lettre(dep.charAt(i))
				if (couleur)	// blanc
					lettre = lettre.toUpperCase()
				piecepromo = get_piece_from_lettre(lettre)
			}
			else // la lettre de la piece de promotion est optionelle
				 // dans ce cas c'est une promotion en dame
			if ( (piece.substr(0,1) == "p") && ((lig1==1) || (lig1==8)))
			{
				lettre = 'd'
				if (couleur)	// blanc
					lettre = lettre.toUpperCase()
				piecepromo = get_piece_from_lettre(lettre)
			}

			// enregistre et joue le coup
			enregistre_coup(piece,col,lig, col1, lig1, piecepromo, couleur)
		}
		else
			return false
	}

	// ecrit
	ecrire_coup_joue(couleur, g_coup_joue)

	return true
}

function init_tag(tag,value)
{
if (tag == "Event")
	getObj("he").value = value
else if (tag == "Site")
	getObj("hs").value = value
else if (tag == "Date")
	getObj("hd").value = value
else if (tag == "Round")
	getObj("hr").value = value
else if (tag == "White")
	getObj("hb").value = value
else if (tag == "Black")
	getObj("hn").value = value
else if (tag == "WhiteElo")
	getObj("heb").value = value
else if (tag == "BlackElo")
	getObj("hen").value = value
else if (tag == "Result")
	getObj("hres").value = value
else if (tag == "ECO")
	getObj("heco").value = value
else if (tag == "SetUp")
{
}
else if (tag == "FEN") // charge une position de départ
{
	lire_position_fen(value)
}

}

// lit les tag du format pgn
function lire_entete(str, index)
{
	var i_deb=0, i_fin=0;
	var tag = new String;
	var value = new String;
	//ignore blanc,retour à la ligne

	while (str.charAt(index)=='[') //debut tag
	{
		i_deb = str.indexOf(" ",index);
		tag = str.substring(index+1,i_deb);
		i_fin = str.indexOf("]",index)
		value = str.substring(i_deb+2, i_fin-1)
		init_tag(tag,value)
		index = i_fin+1;
		while ( (index < str.length) && (str.charAt(index) == ' ' || str.charAt(index) == '\r' || str.charAt(index) == '\n'))
			++index;
	}

	return index+1;
}

//-- Lit une partie en notation algérique complète ou abrégée
function lire_partie(str,bNettoie)
{
	g_load = true;
	var bsetLang = true;
	var index= 0
	coup_blanc = new String
	coup_noir  = new String
	var l=str.length;

  if (bNettoie) // nettoye du texte pgn
  {
  	str = str.replace(/\{[^}]+}/g,"") // supprime commentaire entre { }
  	
  	// supprime variantes entre ( )
    while(str.match(/\(/) && str.match(/\)/)){
      str=str.replace(/\([^\(\)]+\)/g,"");
    }	
  	
  	str = str.replace(/\$[0-9]{1,3}/g,"") // supprime les NAG : $ suivi de 1 à 3 chiffre
  	str = str.replace(/[0-9]{1,2}\.{3}/g,"") // suprime reprise blanc xx...
  }
  str = str.replace(/\t/g," ")
  index = lire_entete(str, index);	// import tag pgn

	// recherche la presence du terminateur
	if (str.indexOf("1-0", index)!=-1)
		l= str.indexOf("1-0", index)
	else if (str.indexOf("0-1", index)!=-1)
		l= str.indexOf("0-1", index)
	else if (str.indexOf("1/2-1/2", index)!=-1)
		l= str.indexOf("1/2-1/2", index)
	else if (str.indexOf("*", index)!=-1)
		l= str.indexOf("*", index)

	while (index < l)
	{
		coup_blanc = ""
		coup_noir = ""
    while (index<l && (str.charAt(index) == ' ' || str.charAt(index) == '\r' || str.charAt(index) == '\n')) ++index
		while (index<l && str.charAt(index) != ' ' && str.charAt(index) != '.') ++index
		if (str.charAt(index) == '.') ++index // numero peut suivi d'un point
     	while (index<l && (str.charAt(index) == ' ' || str.charAt(index) == '\r' || str.charAt(index) == '\n')) ++index

		while (index<l && str.charAt(index) != ' ' && str.charAt(index) != '\r' && str.charAt(index) != '\n')
		{
			if (str.charAt(index)!='!' && str.charAt(index)!='?' && str.charAt(index)!='#')
				coup_blanc += str.charAt(index)
			++index
		}


		while (index<l && (str.charAt(index) == ' ' || str.charAt(index) == '\r' || str.charAt(index) == '\n')) ++index

		while (index<l && str.charAt(index) != ' ' && str.charAt(index) != '\r' && str.charAt(index) != '\n')
		{
			if (str.charAt(index)!='!' && str.charAt(index)!='?' && str.charAt(index)!='#')
				coup_noir += str.charAt(index)
			++index
		}

		if (bsetLang)
		{
		 	if (coup_blanc.length==3 || coup_blanc.length>5)
		 	{
				set_langage(coup_blanc);
				bsetLang=false;
			}
			else if (coup_noir.length==3 || coup_noir.length>5)
			{
				set_langage(coup_noir);
				bsetLang=false;
			}
		}
		if (coup_blanc != "..." && coup_blanc != "..")
		{
			if (coup_blanc.length && !deplace_piece(coup_blanc, true))
			{
				alert("coup blanc invalide : >"+coup_blanc+"<")
				g_load = false
				return false
			}
		}
		else if (g_couleur == true)
		{
			change_couleur()
		}

		if (coup_noir != "")
			if (!deplace_piece(coup_noir, false))
			{
				alert("coup noir invalide : >"+coup_noir+"<")
				g_load = false
				return false
			}
	}

	g_load = false

	if (g_nc>0)
		set_courant(g_nc/6)

	return true
}

//----- reaffiche la notation de la partie jusqu'au coup num_coup
function mettre_a_jour_notation(num_coup)
{
	if (g_demo || g_trace)
		return;

	ecrire_cadrepartie("");
	var bCouleur = get_couleur(g_p[0]);
	for (i=0; i< num_coup; i+=6)
	{
		ecrire_cadrepartie(g_notation_partie[i/6], i);
		bCouleur = !bCouleur
	}
}

// affiche partie à partir du coup n
function affiche_notation(num_coup)
{
	ecrire_cadrepartie("");
	if (num_coup==0 && g_nc==0 )
		return;
	var bCouleur = true;
	g_load = true;
	for (i=num_coup; i< g_coup_joue && i < num_coup + 6*75*2; i+=6)
	{
		ecrire_cadrepartie(g_notation_partie[i/6], i);
		bCouleur = !bCouleur
	}
	g_load = false;

}

function renum_feuille(delta) {
	// renumerote feuille
	for (i=1; i<=g_mc/2; ++i) 	getObj("i"+i).innerHTML= delta+i
	// decale coup
	affiche_notation(delta*6*2);
}

// renvoie cellule de la feuille de partie
function getCel(i)
{
	var n = i; // numero du demi-coup
	if ((n > (g_mc+g_first_col*g_mc_col*2)) && ( (n-1)%50 == 0)) // changement de page
	{
		if (((n-1)/50 - 2) != g_first_col)
		{
			g_first_col = (n-1)/50 - 2
			renum_feuille(g_first_col * g_mc_col) // renumerote colonne
		}
	}
	else if (i < (g_first_col*g_mc_col*2)+1) // changement de page, retour arriere
	{
		--g_first_col;
		renum_feuille(g_first_col * g_mc_col) // renumerote colonne
	}
	return getObj("n"+(n - (g_first_col*g_mc_col*2)))
}


function e_tag(tag,value) { return '['+tag+' "'+value+'"]\n' }

//-- export format pgn
// param l : fr ou en
function export_pgn(exp_tag,l)
{
	str = new String
	if (exp_tag)
	{
		str+=e_tag("Event", getObj("he").value)
		str+=e_tag("Site",getObj("hs").value)
		str+=e_tag("Date",getObj("hd").value)
		str+=e_tag("Round",getObj("hr").value)
		str+=e_tag("White",getObj("hb").value)
		str+=e_tag("Black",getObj("hn").value)
		str+=e_tag("Result",getObj("hres").value)

		//e_tag(getObj("heb").value
		//e_tag(getObj("hen").value
		//e_tag(getObj("heco").value

	}
	str1 = new String

	for (i=0; i*6 < g_coup_joue; ++i)
	{
		if (i%2 == 0)
			str1+= i/2 + 1 +".";

		str1 += " "+g_notation_partie[i];

		if (i%2 !=0)
			str1 += "\n"
	}
	
	if (g_lettrepiece == g_lettrepiece_fr && l=='en') // traduit de fr en en
	{
	   str1 = str1.replace(/R/g,'K')
	   str1 = str1.replace(/D/g,'Q')
	   str1 = str1.replace(/F/g,'B')
	   str1 = str1.replace(/C/g,'N')
	   str1 = str1.replace(/T/g,'R')
  }
  else if (g_lettrepiece == g_lettrepiece_us && l=='fr') // traduit de en en fr
	{
	   str1 = str1.replace(/R/g,'T')
	   str1 = str1.replace(/K/g,'R')
	   str1 = str1.replace(/Q/g,'D')
	   str1 = str1.replace(/B/g,'F')
	   str1 = str1.replace(/N/g,'C')
  }
  
	return str + str1;
}

// export notation fen
// param l : fr ou en
function export_fen(l)
{
	str = new String
	for (lig=8; lig>=1; --lig)
	{
		nb_case_vide = 0
		for (col=1; col<=8; ++col)
		{
			piece = g_occupe[lig*8 + col]
			if (piece == null) // case vide
				 ++nb_case_vide
			else // case occupé
			{
				if (nb_case_vide > 0)
				{
					str += nb_case_vide
					nb_case_vide = 0
				}
				piecelettre = piece.charAt(0)
				if (piecelettre != "p")
				    piecelettre = getlettrefrompiece(piece.charAt(0), l=='fr' ? g_lettrepiece_fr : g_lettrepiece_us)
				piecelettre = piecelettre.toLowerCase()
				if (get_couleur(piece) == true)
					piecelettre = piecelettre.toUpperCase()	// piece blanche en majuscule
				str += piecelettre
			}
		}
		if (nb_case_vide > 0) { str += nb_case_vide;	nb_case_vide = 0; }
		if (lig != 1) str = str + "/"
	}
	// ajoute trait w (white) ou b (black)
	str += g_couleur ? " w":" b"
	
	return str
}

//----- affiche une position a partir du tableau g_occupe
function affiche_position()
{
	for (lig=8; lig>=1; --lig)
		for (col=1; col<=8; ++col)
		{
			piece = g_occupe[lig*8 + col]
			if (piece != null)
				joue_piece2(piece, col, lig)
		}
}


//-- lecture d'une partie notation algébrique abrégée
function lire_notation_algebrique(str)
{
	var ligne = null
	while (str != "")
	{
		// lit une ligne
		i=str.indexOf("\n")
		ligne = i>0 ? str.substr(0,i-1) : str
		// ignore ligne commencant par ; ou [ et les lignes vides
		if (ligne.charAt(0) !=';' && ligne.charAt(0) != '' && ligne.charAt(0) != '[')
		{
			coup = ligne.substr(ligne.indexOf(" ")+1)		   // passe le numero du coup : 1.
			coupblanc = coup.substr(0,coup.indexOf(" "));   // e2-e4 coup blanc
			coupnoir  = coup.substr(coup.indexOf(" ")+1);	// e5-e7 coup noir
			if (!deplace_piece(coupblanc, true))
				return false
			if (!deplace_piece(coupnoir, false))
				return false

		}
		i=str.indexOf("\n")
		str = i>=0 ? str.substr(i+1) : "";
	}
	return true
}

//-- lecture du cadre contenant une partie (ou une position)
function lire()
{
	var str = g_notationtext.value	// recupere la notation algébrique de la partie
	if (str == null)
		return
	if (g_mode > 2) // autre mode que partie ou position
		set_mode(1)
	lire_fen_pgn(str, true,true)

	//ferme le cadre fenpgn
	btn_fenpgn()
}

function exp_fen(l) { g_notationtext.value = export_fen(l); g_notationtext.select() }
function exp_pgn(exp_tag,l) { g_notationtext.value = export_pgn(exp_tag,l); g_notationtext.select() }

// importe un fichier historique de yahoo chess
// utilise un control activeX FileSystemObject
function get_yahoo1()
{
	if (g_fichier == "")
		g_fichier = "c:\\temp\\game.txt"
	g_fichier = showModalDialog("import.htm", g_fichier, "dialogWidth:400px;dialogHeight:160px" );

	if (g_fichier != "")
	{
		var fso, f, r;
		var ForReading = 1, ForWriting = 2;
		fso = new ActiveXObject("Scripting.FileSystemObject");
		if (fso != null)
		{
			f = fso.OpenTextFile(g_fichier, ForReading);
			r =  f.ReadLine();
			while (!r.AtEndOfStream)
			{
				// ignore ligne commencant par ; et ligne vide
				if (r.charAt(0) !=';' && r.charAt(0) != '')
				{
					coup = r.substr(r.indexOf(" ")+1)
					coupblanc = coup.substr(0,coup.indexOf(" "));
					coupnoir  = coup.substr(coup.indexOf(" ")+1);
					if (!deplace_piece(coupblanc, true))
						return false
					if (!deplace_piece(coupnoir, false))
						return false

				}
				r =  f.ReadLine();
			}
		}
	}
	return true
}

//--- ajoute une lettre (ou chiffre) pour lever l'ambiguité
function leve_ambiguite(couleur)
{
	var i = g_coup_joue - 6; // coup deja enregistre
	// piece joue
	var piecejoueid = g_p[i].substr(0 ,1)
	// coordonnée d'arrivée
	col_start = g_p[i+1]
	lig_start = g_p[i+2]
	col_end   = g_p[i+4]
	lig_end   = g_p[i+5]

	// repositionne temporairement la piece deplace
	var sauve_piece  = g_occupe[col_end + lig_end*8];
	g_occupe[col_start + lig_start*8] = sauve_piece;
	g_occupe[col_end + lig_end*8] = null

	// si même piece sur l'echiquier teste si elle peut aller sur la même case
	// parcours tout l'echiquier
	var col,lig;
	var piece = null
	var pieceid
	for (lig=1; lig<=8; ++lig)
		for (col=1 ; col<=8; ++col)
		{
			if ( col == col_start && lig == lig_start)
				continue;

			// si même pièce
			piece = g_occupe[col + lig*8]
			if (piece != null)
			{
				if ( (piecejoueid == piece.substr(0,1)) && (get_couleur(piece) == couleur) )
				{
					if (test_deplacement(piece.substr(0,1), col, lig , col_end, lig_end, couleur, false))	// vrai si déplacement possible
					{
						var ret;
						if (col_start != col)
							ret = g_lettre[col_start]
						else
							ret = lig_start;
						g_occupe[col_end + lig_end*8] = sauve_piece;
						g_occupe[col_start + lig_start*8] = null;
						return ret;
					}
				}
			}
		}

	// restaure piece
	g_occupe[col_end + lig_end*8] = sauve_piece;
	g_occupe[col_start + lig_start*8] = null;

}

//--- regenere la notation d'une partie quand la langue change fr/us
function regenere_notation_langage(from, to)
{
	var i;
	var nb_coup = g_nc/6;
	var str_from = from
	var str_to   = to
	for (i=0; i< nb_coup; ++i)
	{
		for (j=0;j<5;++j)
		{
			if (g_notation_partie[i].search(str_from.charAt(j)) != -1)
			{
				g_notation_partie[i] = g_notation_partie[i].replace(str_from.charAt(j),str_to.charAt(j));
				break;
			}
		}
	}

	regenere_notation()
}

//--- regenere la notation d'une partie
function regenere_notation()
{
	// efface notation
	ecrire_cadrepartie("")	// efface cadre partie

	// reecrit notation
	if (g_nc > 0)
	{
		var bCouleur = get_couleur(g_p[0]);
		var i;
		for (i=0; i< g_nc; i+=6)
		{
			ecrire_cadrepartie(g_notation_partie[i/6], i);
			bCouleur = !bCouleur
		}
	}
}

//-- Ecrit en notation algébrique le coup joue
function ecrire_coup_joue(couleur, nb_coup_jouer)
{
	if (g_demo)
		return;

	var coup = new String	   // le coup joué
	var i = nb_coup_jouer - 6;	// indice du coup joue

	// genere le demi-coup dans la notation selectionnée
	if ( g_p[i+3]==3 || g_p[i+3]==4 )	// roque
	{
		coup += (g_p[i+3]==3) ? "O-O" : "O-O-O"
	}
	else if (g_p[i+3]==-1) // coup vide (noir joue en premier)
	{
		coup = "..."
	}
	else	// autre coup
	{
		if (g_notation)  // notation algébrique abrégée
		{
			lettrepiece = g_p[i].charAt(0).toUpperCase() // lettre réprésentant la piece

			if (lettrepiece != "P")
			{
				coup = getlettrefrompiece(g_p[i].charAt(0), g_lettrepiece)
				// lève l'ambiguité si nécesaire

				ambiguite = leve_ambiguite(couleur)	// retourne colonne ou rangée levant l'ambiguité
				if (ambiguite != null)
					coup += ambiguite
			}
			sep = ""
			if ((g_p[i+3] == 1) || (g_p[i+3] == 2) || (g_p[i+3] == 6))
				sep = "x"	// capture d'une pièce
			if ( (sep == "x") && (lettrepiece == "P") )          // si pion prend
				coup+= g_lettre[g_p[i+1]]		// case de départ (colonne)
			coup+= sep + g_lettre[g_p[i+4]]	// case d'arrivée (colonne)
			coup+= g_p[i+5]						// case d'arrivée (rangée)
		}
		else
		{
			// notation algébrique complète
			coup = g_lettre[g_p[i+1]]			// case de départ
			coup+= g_p[i+2];
			sep = "-"
			if ((g_p[i+3] == 1) || (g_p[i+3] == 2) || (g_p[i+3] == 6))
				sep = "x"	// capture d'une pièce
			coup = coup + sep + g_lettre[g_p[i+4]]	// case d'arrivée
			coup+= g_p[i+5]
		}
	}

	// test promotion, recupere la lettre de piece
	if (g_p[i+3] >= 5)
		coup += g_p[i].charAt(2).toUpperCase()

	// test si le roi adverse est mis en echecs par le coup joue
	//TESTFLSvar roi ="r"
	//roi += couleur?"n":"b" //prends la couleur du roi adverse
	//if (test_roi_en_echec1(get_col(getObj(roi)), get_lig(getObj(roi)), couleur))
	//	coup += "+"

	// stocke le demi-coup dans le tableau g_notation_partie
	g_notation_partie[i/6] = coup

	ecrire_cadrepartie(coup, i);
}

// sauve dans un fichier la partie
// utilise controle ActiveX
function sauver_partie1()
{
	// notation
   var fso, f;
   var ForReading = 1, ForWriting = 2;
	fso = new ActiveXObject("Scripting.FileSystemObject");
	f = fso.CreateTextFile("c:\\temp\\partie1.txt", true);
	// ecrit chaque coup
	line = new String
	li   = 0
	for (i=0; i < g_coup_joue; i+=6)
	{
		line = line + g_lettre[g_p[i+1]]
		line+= g_p[i+2]
		line = line + " " + g_lettre[g_p[i+4]]
		line+= g_p[i+5]
		if (li==1)
		{
			f.WriteLine(line);
			line = ""
		}
		else
			line = line + " - "
		li=1-li
	}
	f.Close();
}

// ferme le cadre iEchecs
function btn_close(bAppli) { if (bAppli) { if (window.opener) window.self.close(); window.opener.g_window = null;  } }

//-- Affiche panneau fen/pgn pour import/export
function btn_fenpgn()
{
   // cache panneau option si visible
   if (g_cadreopts)
   	btn_opts()
   g_cadrefenpgn = !g_cadrefenpgn
   g_dal = g_cadrefenpgn // deactive raccourci clavier
   set_visible(g_divpgnfen, g_cadrefenpgn)
   g_notationtext.focus()
}

//-- Affiche panneau des options
function btn_opts()
{
   // cache panneau fenpgn si visible
   if (g_cadrefenpgn)
      btn_fenpgn()
   g_cadreopts = !g_cadreopts
   g_dal = g_cadreopts // deactive raccourci clavier
   set_visible(g_divoptions, g_cadreopts)
}

// efface l'historique de la partie
// mais garde la position courante
function btn_hist() { init_historique() }

// se positionne au demi_coup i (appeler depuis le cadre partie)
function GoMv(i)
{
	num_coup = i*6
	if (g_nc > num_coup)
		while (g_nc > num_coup)
			set_arriere()
	else
		while (g_nc < num_coup)
			set_avant()
}

// positionne une option choisie à partir du panneau d'option
function set_o(opt)
{
	if (opt=='n_montre') // taille standard
	{
		g_taille_mini=false
	}
	else if (opt=='n_cache') // taille mini
	{
		g_taille_mini=true
	}
	else if (opt=='n_abregee')
	{
	   g_notation = true;
	}
	else if (opt=='n_complete')
	{
	   g_notation = false;
	}
	else if (opt=='n_fdmv')	// feuille de match visible
	{
		set_visible(g_divpartie, true)
		set_visible(g_divpartie, true)
		set_visible(g_divheader, true)
	}
	else if (opt=='n_fdmc') // feuille de match cachee
	{
		set_visible(g_divpartie, false)
		set_visible(g_divpartie, false)
		set_visible(g_divheader, false)
	}
	else if (opt == 'n_fr') // notation en francais
	{
		regenere_notation_langage(g_lettrepiece_us, g_lettrepiece_fr)
		g_lettrepiece = g_lettrepiece_fr;
	}
	else if (opt == 'n_us') // notation en anglais
	{
	   regenere_notation_langage(g_lettrepiece_fr, g_lettrepiece_us)
	   g_lettrepiece = g_lettrepiece_us;
	}
	else if (opt == 'p_std')
		g_chess960 = false;	// position initiale standard
	else if (opt == 'p_ale')
		g_chess960 = true;    // position initiale aléatoire
	else if (opt == 's_owl')
		change_style(opt)
	else if (opt == 's_fri')
		change_style(opt)
	else if (opt == 'jn') // jeu normale
		getObj("echiquier1").style.zIndex = 5
	else if (opt == 'ja') // jeu à l'aveugle
		getObj("echiquier1").style.zIndex = -1
	else if (opt == "ro") // raccourci activé
		g_rac = true;
	else if (opt == "rn") // déactivé
		g_rac = false;
}

// action choisi dans le mode apprendre
function set_action_apprendre(action){
(action=="lepion") ? set_action(action,4,2,false) : set_action(action,4,4,false);
}

// Synchronise texte ou change taille en mode app
function btn_sync_text(bApp) { if (bApp) 	set_taille() }

//----- Gestion des actions de la toolbar
function play(num)
{
switch (num){
case 0: aide(); break;
case 1: btn_fenpgn(); break;
case 2: vider(); break;
case 3: reverse(g_reverse=!g_reverse); break;
case 4: set_nouveau(); break;
case 5: window.location="index.htm"; break;
case 6: window.location="index.htm"; break;
case 7: btn_opts(); break;
case 8: btn_hist(); break;
case 9: btn_sync_text(g_bApp); break;
case 10: if (!g_demo) set_debut(-1); break;
case 11: if (!g_demo) set_debut(5);  break;
case 12: if (!g_demo) set_arriere(); break;
case 13: if (!g_demo) set_avant();   break;
case 14: if (!g_demo) set_fin(5); break;
case 15: if (!g_demo) set_fin(-1); break;
case 16: btn_close(g_bApp); break;
case 17: iechecs(g_taille_mini ? "appe":"app",1); break;
}
return false;	// cancel navigation
}

function get_action_from_lettrepromo(lettre)
{
switch (lettre)
{
case 'd':
case 'D':
	return "ladame"
case 'c':
case 'C':
	return "lecavalier"
case 'f':
case 'F':
 return "lefou"
case 't':
case 'T':
	return "latour"
}
}

//-- Retourne la code piece désignée par une lettre
function get_piece_from_lettre(lettre)
{
//                  012345
//lettre des pièces "CFTDR"
if (g_lettrepiece == g_lettrepiece_us)
{
   if (lettre=='r')
       lettre = 't'
   else if (lettre=='R')
       lettre = 'T'
   else if (lettre=='n')
       lettre = 'c'
   else if (lettre=='N')
       lettre = 'C'
}

var piece;
switch (lettre)
{
case 'r':
case 'k': piece = "rn"; break;
case 'R':
case 'K': piece = "rb"; break;
case 't': piece = "tn"; break;
case 'T': piece = "tb";	break;
case 'b':
case 'f': piece = "fn"; break;
case 'F':
case 'B': piece = "fb";	break;
case 'd':
case 'q': piece = "dn"; break;
case 'D':
case 'Q': piece = "db";	break;
case 'c': piece = "cn"; break;
case 'C': piece = "cb"; break;
case 'p': piece = "pn"; break;
case 'P': piece = "pb"; break;
}
return piece
}

// determine une lecture FEN, Descriptive ou PGN
// on recherche des / sur la premiere ligne
function lire_fen_pgn(str, bNew, bNettoie)
{
	if (str == "")
		return

	var i=str.indexOf("/");
	var bFEN = (i>0 && i<=9 && str.indexOf("[")==-1)
	var bDescriptive = ( (str.substr(0,2) == "B:") && (str.indexOf("/N:")!=-1) )

	if (bDescriptive)
		lire_position_descriptive(str)
	else if (bFEN)
		lire_position_fen(str)
	else
	{
		if (bNew) // la lecture se fait à partir de la position initiale
			set_nouveau()
		else
			init_historique() // reinitialise l'historique

		lire_partie(str, bNettoie)
	}
}

// initialise ches 960 et position de départ
// 12345678
// tcfdrfct
function init_chess960(pos_init)
{
  pos_t = 1
  pos_c = 2
  set_o960(true)
  for (i=1;i<=8;++i)
  {
    piece = get_piece_from_lettre(pos_init[i-1])
    if (piece=="rn")
      g_random_tab[5] = i
    else if (piece=="dn")
      g_random_tab[4] = i
    else if (piece=="tn")
    {
        g_random_tab[pos_t] = i
        pos_t=8
    }
    else if (piece=="cn")
    {
        g_random_tab[pos_c] = i
        pos_c=7
    }
    else if (piece=="fn")
    {
      if (i%2 == 0) // fou sur case noire
        g_random_tab[3] = i
      else
        g_random_tab[6] = i
    }
  }
}

//-- Initialise une position à partir d'une notation FEN
//-- Piece blanche en majuscule, piece noire en minuscule
//-- ex : position initiale : "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq"
//-- ex : 1t3C1r/6p1/5c1p/p7/1d2D1P1/5FP1/5P2/6R1
function lire_position_fen(str)
{
	if (str == "")
		return

	var lettrepiece_save = g_lettrepiece;
	set_langage(str) // modifie var g_lettrepiece

  // si position correspond à une position initiale potentiel, on positionne chess960
  if (str.match(/[a-z]{8}\/p{8}(\/8){4}\/P{8}\/[A-Z]{8}/))
    init_chess960(str.substr(0,8))

	index = 0;
	vider()
	// parcours tout l'echiquier
	i=8;
	while (i>=1)
	{
		j = 1;
		while (j<=8)
		{
			car = str.charAt(index)
			if (car >= '0' && car <= '8')
				j += eval(car)
			else if (car != '/')
			{
				// positionne piece
				joue_piece2(get_piece_from_lettre(car),j,i)
				++j
			}
			++index
		}
		--i
	}
	++index;
	while (index < str.length && str.charAt(index)==' ') ++index;

	// lecture du trait
	if (index < str.length) set_couleur(str.charAt(index)=='w')

	g_lettrepiece = lettrepiece_save; //restaure langage
}

//-- Initialise une position à partir d'une notation descriptive
//-- ex : position initiale : 
//-- ex : B:Rg1,Fg1,e3,d3/N:Rg8,Fc5
function lire_position_descriptive(str)
{
	if (str == "")
		return

	var lettrepiece_save = g_lettrepiece;
	//set_langage(str) // modifie var g_lettrepiece
	g_lettrepiece = g_lettrepiece_fr

	var i = 2;	// commence apres le B:
	var piece;
	var bCouleur = true;
	vider()
	
	while (i<str.length)
	{
		j=0;
		while (i<str.length && str.charAt(i)!=',' && str.charAt(i)!='/') { ++i; ++j }
		if (j==3)
			piece = get_pieceid_from_lettre(str.charAt(i-j))
		else // pion
			piece = "p"
			
		bCouleur ? piece += "b" : piece += "n"

		var col = (str.charCodeAt(i-2) & 223) - 64  // code ascii de A = 65
		var lig = eval(str.charAt(i-1))

		// positionne piece
		joue_piece2(piece,col,lig)
		
		if (str.charAt(i)==',') ++i
		if (str.charAt(i)=='/')	{ i+=3; bCouleur = false }
	}

	g_lettrepiece = lettrepiece_save; //restaure langage
}

// calcule les mouvements valides de la dame
function set_mouvement_dame(col,lig, display){
	set_mouvement_fou(col,lig, display);
	set_mouvement_tour(col,lig, display, 0, 0);
}

// calcule les mouvements valides de la tour
function set_mouvement_tour(col,lig, display, col1, lig1)
{
	if (display == false)
		return (col == col1 || lig == lig1)

	// marque d'un rond vert les cases accessible par la tour.
	for (xx=1; xx<=8; ++xx) // parcours colonne
	{
		if (xx != col)	affiche_point(xx, lig)
		else for (yy=1; yy<=8; ++yy) if (yy != lig) affiche_point(xx, yy)
	}
}

// calcule mouvement valide fou
function set_mouvement_fou(col,lig, display, col1, lig1)
{
	// marque d'un rond vert les cases accessible par le fou.
	for (xx=1; xx<=8; ++xx)	// parcours les colonnes
	{
		delta = col - xx;	  // deplacement en diagonale
		if (xx != col)
		{
			yy = lig + delta;  // deplacement en diagonale vers le haut
			if (yy >=1 && yy <= 8)
			{
				if (display == true)	// affiche un point vert sur case valide
					affiche_point(xx, yy)
				else	// return true si col1, lig1 est une case valide
				{
					if (xx==col1 && yy==lig1)
						return true
				}
			}
			yy = lig - delta; // deplacement en diagonale vers le bas
			if (yy >= 1 && yy <= 8)
			{
				if (display == true)	// affiche un point vert sur case valide
					affiche_point(xx, yy)
				else	// return true si col1, lig1 est une case valide
				{
					if (xx==col1 && yy==lig1)
						return true
				}
			}
		}
	}

	return false
}

// calcule mouvement valide pour le cavalier
function set_mouvement_cava(col,lig, display, col1, lig1)
{
	if (display == false)
		return ( (Math.abs(col-col1)==2 && Math.abs(lig-lig1)==1)  ||
	          (Math.abs(col-col1)==1 && Math.abs(lig-lig1)==2)  )
	else
	{
		var str;
		// marque d'un rond vert les cases accessible par le cavalier.
		for (xx=col-2; xx<=col+2; ++xx)	// parcours colonne
		{
			if (xx == col)
				continue;
			delta = Math.abs(xx - col);
			(delta == 2) ? delta = 1 : delta = 2
			for (yy=lig-delta; yy<= lig+delta; yy=yy+delta)	// parcours ligne
			{
				if (yy == lig)
					continue;
				if ( (xx >= 1) && (xx <= 8) && (yy >= 1) && (yy <= 8))
					affiche_point(xx, yy)
			}
		}
	}
}

// change le style des pièces owl / fritz
function change_style(style) { if (style == "s_owl") g_style = "1.png"; else g_style = ".png"; }

function init_header(event,site,date,round,blancs,noirs,result,elo_b,elo_n,eco)
{
	getObj("he").value = event
	getObj("hs").value = site
	getObj("hd").value = date
	getObj("hr").value = round
	getObj("hb").value = blancs
	getObj("hn").value = noirs
	getObj("heb").value = elo_b
	getObj("hen").value = elo_n
	getObj("hres").value = result
	getObj("heco").value = eco
}


function sauver_fen()
{
var str = export_fen('fr') + "|" + getObj('nompos').value;
var dat_fin = new Date(2020,1,1);
var solution = "f"+getObj('numsol').selectedIndex;
document.cookie = solution+"=" + str +";expires="+dat_fin.toGMTString();
}


function lire_cookie(nom,bAlert)
{
if (document.cookie=="" && bAlert) { alert("Pas de sauvegarde numéro : "+getObj('numsol').selectedIndex);	return }
var coo = document.cookie.split('; ') // split les cookies
// recherche la solution numero num
var bFound = false;
var str;
for (i=0; i<coo.length; ++i)
{
	str = coo[i]
	res = str.split('=')
	if (res[0]==nom)
	{
		str = res[1];
		bFound = true;
		break;
	}
}
if (!bFound) { if (bAlert) alert("Pas de sauvegarde numéro : "+getObj('numsol').selectedIndex); return null}
else
return str;
}

function set_nompos(pos)
{
var solution = "f"+pos;
var nompos ="<nom de la position>"
var res = lire_cookie(solution,false);
if (res != null && res.length > 1){
		str = res.split('|'); // sépare valeur cookie
		if (str != null && str.length == 2) { nompos = str[1]; }
}
getObj('nompos').value = nompos;
}


function charger_fen()
{
var solution = "f"+getObj('numsol').selectedIndex;
var res = lire_cookie(solution,true);
if (res !=null && res.length > 1)
{
	str = res.split('|') // sépare valeur cookie
  lire_position_fen(str[0])
}
}

// lecture d'une action dans l'url
function execute(param)
{
	//var par = param.split(',') // chaque parametre est separe par une virgule
	var indx = param.indexOf("a="); // action
	if (indx>=0)
	{
		if (param.indexOf("p=t")>=0)
			reverse(g_reverse=!g_reverse);
		param = param.substr(indx+2);
		set_action(param,4,4);
	}
	else
	{
		indx = param.indexOf("p=t");
		if (indx>=0)
			reverse(g_reverse=!g_reverse);
		indx = param.indexOf("pgn=");
		if (indx==-1)
			indx = param.indexOf("fen=");
		if (indx>=0)
		{
			param = param.substr(indx+4);
			param = param.replace(/%20/g," ")
			param = param.replace(/%22/g,'"')
			param = param.replace(/%E9/g,'é')
			param = param.replace(/%E8/g,'è')
			param = param.replace(/%E7/g,'ç')
			param = param.replace(/%E0/g,'à')
			param = param.replace(/%F9/g,'ù')
			set_nouveau()
			lire_fen_pgn(param,true,false)
		}
	}
}
function set_rac(bValue) { g_rac = bValue }
