
/*
 * JavaScript for Chessgame Shizzle pgn4web viewer.
 */


/*
Copyright 2017 - 2025  Marcel Pol  (marcel@timelord.nl)
Copyright 2025         mediaformat

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/


	"use strict";

	SetImagePath( cs_pgn4web.imagepath );
	SetImageType("png");
	SetHighlightOption(true); // true or false
	//SetGameSelectorOptions("Select a KK game...", false, 0, 8, 0, 0, 0, 0, 10); // (head, num, chEvent, chSite, chRound, chWhite, chBlack, chResult, chDate);
	SetGameSelectorOptions(null, false, 0, 0, 0, 15, 15, 0, 10); // (head, num, chEvent, chSite, chRound, chWhite, chBlack, chResult, chDate);
	SetCommentsIntoMoveText(true);
	SetCommentsOnSeparateLines(false);
	SetAutoplayDelay(1500); // milliseconds
	SetAutostartAutoplay(false);
	SetAutoplayNextGame(false); // if set, move to the next game at the end of the current game during autoplay
	SetInitialGame(1); // number of game to be shown at load, from 1 (default); values (keep the quotes) of "first", "last", "random" are accepted; other string values assumed as PGN search string
	SetInitialVariation(0); // number for the variation to be shown at load, 0 (default) for main variation
	SetInitialHalfmove(0,false); // halfmove number to be shown at load, 0 (default) for start position; values (keep the quotes) of "start", "end", "random", "comment" (go to first comment or variation), "variation" (go to the first variation) are also accepted. Second parameter if true applies the setting to every selected game instead of startup only
	SetShortcutKeysEnabled(false);

	//SetLiveBroadcast(0, false, false, false, false); // set live broadcast; parameters are delay (refresh delay in minutes, 0 means no broadcast, default 0) alertFlag (if true, displays debug error messages, default false) demoFlag (if true starts broadcast demo mode, default false) stepFlag (if true, autoplays updates in steps, default false) endlessFlag (if true, keeps polling for new moves even after all games are finished)




/*
 * Localized text strings for buttons.
 *
 * @since 1.0.0
 */
document.addEventListener("DOMContentLoaded", () => {

	cs_pgn4web_strings( 0 );

});
function cs_pgn4web_strings( counter ) {

	counter++;

	/*
	 * document.querySelectorAll() to check for the presence of the form(s).
	 * document.querySelector() to target each button.
	 * Optional chaining (?.) to avoid errors if an element isn't found.
	 */

	if (document.querySelectorAll('div#GameButtons form').length > 0) {
		document.querySelector('input#startButton')?.setAttribute('title', cs_pgn4web.startButton); // go to game start
		document.querySelector('input#backButton')?.setAttribute('title', cs_pgn4web.backButton); // move backward
		document.querySelector('input#autoplayButton')?.setAttribute('title', cs_pgn4web.autoplayButton); // toggle autoplay (start) // FIXME: js overrides on click event (stop, start).
		document.querySelector('input#forwardButton')?.setAttribute('title', cs_pgn4web.forwardButton); // move forward
		document.querySelector('input#endButton')?.setAttribute('title', cs_pgn4web.endButton); // go to game end
	} else {
		// Ensures it's checked at least 15 times
		if ( counter < 15 ) {
			//console.log( counter + ' not available yet: ' );
			setTimeout(
				function() {
					cs_pgn4web_strings( counter )
				}, 200 );
		}
	}
}


/*
 * View of single game.
 * Set focus to move inside gametext.
 *
 * @since 1.2.5
 */
document.addEventListener("DOMContentLoaded", () => {

	enableAutoScrollToCurrentMove("GameText");

});


/*
 * View of single game.
 * Toggle headers with more info.
 * Replicate slideDown and slideUp with CSS transitions.
 *
 * @since 1.0.0
 */
document.addEventListener('DOMContentLoaded', function () {
	document.querySelectorAll('span.cs_chessgame_meta_header').forEach(function (header) {
		header.addEventListener('click', function (e) {
			e.preventDefault();
			var metaContainer = header.closest('.cs_chessgame_meta');
			var inner = metaContainer.querySelector('.cs_chessgame_meta_inside');
			if (getComputedStyle(inner).display === 'none') {
				inner.style.display = 'block';
				inner.style.height = '0px';
				let fullHeight = inner.scrollHeight + 'px';
				setTimeout(() => {
					inner.style.transition = 'height 0.5s ease';
					inner.style.height = fullHeight;
				});
			} else {
				inner.style.transition = 'height 0.5s ease';
				inner.style.height = '0px';
				setTimeout( function() {
					inner.style.display = 'none';
				}, 500 );
			}

			return false;
		});
	});
});


/*
 * View of single game.
 * Download PGN file from the viewer when clicking a button.
 *
 * @since 1.0.8
 */
document.addEventListener('DOMContentLoaded', function () {
	document.querySelectorAll('input#cs-chessgame-download-pgn').forEach(function (input) {
		input.addEventListener('click', function () {
			var pgndata = document.getElementById('pgnText_for_export').value.trim();
			var downloadLink = document.getElementById('cs-chessgame-download-pgn-link');
			downloadLink.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(pgndata));
			downloadLink.click();
		});
	});
});


/*
 * View of single game.
 * Show an input field with the current FEN code.
 *
 * @since 1.2.1
 */
document.addEventListener('DOMContentLoaded', function () {
	document.querySelectorAll('input#cs-chessgame-gen-fen').forEach(function (input) {
		input.addEventListener('click', function (event) {
			event.preventDefault();
			var fen = CurrentFEN();
			document.querySelector('input#cs-chessgame-show-fen').value = fen;
			document.querySelector('div.cs-chessgame-show-fen').style.display = 'block';
		});
	});
});


/*
 * View of single game
 * Send request for image generation.
 * Return the CurrentFEN from an iframe to the main window.
 *
 * @since 1.1.0
 */
window.addEventListener('message', function(event) {
	if (typeof event.data == 'object' && event.data.call == 'cs-sendvalue') {
		// Do something with event.data.value;
		var value = event.data.value;
		if ( value == 'CurrentFEN' ) {
			var fen = CurrentFEN();
			event.source.postMessage({
				call:  'cs-sendvalue',
				value: fen
			}, event.origin );
		}
	}
}, false);


/*
 * View of single game.
 * Set a png image from a FEN position coming from the iframe.
 *
 * Uses fetch with FormData to match the behavior of jQuery.post.
 *
 * @since 1.1.0
 */
document.addEventListener('DOMContentLoaded', function () {
	document.querySelectorAll('input#cs-chessgame-fen-image').forEach(function ( input ) {
		input.addEventListener('click', function (event) {
			event.preventDefault();

			var fen = CurrentFEN();
			var nonce_fen = cs_pgn4web.nonce_fen;
			var ajax_url = cs_pgn4web.ajax_url;
			var post_id = cs_pgn4web.post_id;

			var formData = new FormData();
			formData.append('action', 'chessgame_shizzle_fen_image_ajax');
			formData.append('security', nonce_fen);
			formData.append('fen', fen);
			formData.append('post_id', post_id);

			fetch(ajax_url, {
				method: 'POST',
				body: formData,
				headers: {
					'X-Requested-With': 'XMLHttpRequest'
				}
			})
			.then(response => response.text())
			.then(response => {
				if (response === 'no FEN code or post ID set.') {
					// Handle error if needed
				} else {
					document.querySelectorAll('img.cs-chessgame-fen-image-png').forEach(img => {
						img.src = response;
					});

					document.querySelectorAll('div.cs-chessgame-remove-fen-image').forEach(div => {
						div.style.height = 'auto';
						div.style.display = 'block';

						// Also set the height of the meta box again, so we get the proper height.
						document.querySelectorAll('div.cs_chessgame_meta_inside').forEach(function (inside) {
							inside.style.height = 'auto';
						});
					});
				}
			});
		});
	});
});
/* Remove generated image again from page. */
document.addEventListener('DOMContentLoaded', function () {
	document.querySelectorAll('input#cs-chessgame-remove-fen-image').forEach(function (input) {
		input.addEventListener('click', function( event ) {
			event.preventDefault();
			document.querySelectorAll('img.cs-chessgame-fen-image-png').forEach(function (img) {
				img.src = '';
			});
			document.querySelectorAll('div.cs-chessgame-remove-fen-image').forEach(function (div) {
				div.style.height = '0px';
				div.style.display = 'none';
			});
			document.querySelectorAll('div.cs_chessgame_meta_inside').forEach(function (inside) {
				inside.style.height = 'auto';
			});
		});
	});
});


/*
 * View of single puzzle game.
 * Switch from puzzle text to PGN text.
 *
 * This checks for the presence of the element and its class using classList.contains.
 * Uses ?. for safe element access.
 * Replaces .html() with .innerHTML, and .css() with .style.
 *
 * @since 1.1.7
 */
document.addEventListener('DOMContentLoaded', function () {
	var wrapper = document.querySelector('.chessboard-wrapper');
	if (wrapper && wrapper.classList.contains('cs-puzzle')) {
		chessgame_shizzle_set_puzzle_data(0);
	}
});
function chessgame_shizzle_set_puzzle_data( counter ) {

	counter++;

	if ( firstStart === false ) { // startup of pgn4web has been done and we can use the CurrentPly() function.

		var white = document.querySelector('.cs-puzzle #GamePuzzleTask span.cs-text-white')?.innerHTML || '';
		var black = document.querySelector('.cs-puzzle #GamePuzzleTask span.cs-text-black')?.innerHTML || '';
		var title = (CurrentPly % 2 ? black : white);

		var taskLink = document.querySelector('.cs-puzzle #GamePuzzleTask a.cs-puzzle-task');
		if (taskLink) {
			taskLink.setAttribute('title', title);
			var html = Math.floor((CurrentPly / 2) + 1) + (CurrentPly % 2 ? "..." : ".") + " ?";
			taskLink.innerHTML = html;
		}

		var iconDiv = document.querySelector('.cs-puzzle #GamePuzzleTask div.cs-icon-color');
		if (iconDiv) {
			var iconcolor = (CurrentPly % 2 ? 'black' : 'white');
			iconDiv.style.backgroundColor = iconcolor;
		}

		if (taskLink) {
			taskLink.addEventListener('click', function (event) {
				event.preventDefault();
				var puzzleTask = document.getElementById('GamePuzzleTask');
				var gameText = document.getElementById('GameText');
				if (puzzleTask) puzzleTask.style.display = 'none';
				if (gameText) gameText.style.display = 'block';
				GoToMove(CurrentPly + 1);
			});
		}

	} else {

		if ( counter < 15 ) {
			// console.log( 'No startup yet: ' + counter );
			setTimeout(
				function() {
					chessgame_shizzle_set_puzzle_data( counter )
				}, 200 );
			}

	}

}









