<commit_before>using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Bloom.Api;
using Bloom.Publish.Android;
using SIL.PlatformUtilities;

namespace Bloom.Publish.Video
{
	/// <summary>
	/// API calls starting with publish/video, used in the Publish panel for Video
	/// </summary>
	public class PublishAudioVideoAPI
	{
		private readonly BloomWebSocketServer _webSocketServer;
		// It's slightly weird that we use one of these, but the video is done by means
		// of an android-type book preview, and this class knows all about how to make one.
		private PublishToAndroidApi _publishToAndroidApi;
		private const string kApiUrlPart = "publish/av/";
		private RecordVideoWindow _recordVideoWindow;

		public PublishAudioVideoAPI(BloomWebSocketServer bloomWebSocketServer, PublishToAndroidApi publishToAndroidApi)
		{
			_webSocketServer = bloomWebSocketServer;
			_publishToAndroidApi = publishToAndroidApi;
		}

		public void RegisterWithApiHandler(BloomApiHandler apiHandler)
		{


			apiHandler.RegisterEndpointHandler(kApiUrlPart + "recordVideo", request =>
			{
				RecordVideo(request);
				request.PostSucceeded();
			}, true, false);

			// This is sent directly from BloomPlayer when it gets to the end of making the recording.
			// The player gives Bloom a list of all the sounds it played and their timings so we can
			// merge them into the captured video.
			apiHandler.RegisterEndpointHandler(kApiUrlPart + "soundLog", request =>
			{
				var soundLog = request.RequiredPostJson();
				_recordVideoWindow.StopRecording(soundLog);
				request.PostSucceeded();
			}, true, false);

			apiHandler.RegisterEndpointHandler(kApiUrlPart + "playVideo", request =>
			{
				_recordVideoWindow.PlayVideo();
				request.PostSucceeded();
			}, true, false);

			apiHandler.RegisterEndpointHandler(kApiUrlPart + "settings", request =>
			{
				if (request.HttpMethod == HttpMethods.Get)
				{
					var settings = request.CurrentBook.BookInfo.PublishSettings.AudioVideo;
					request.ReplyWithJson(new {
						format= settings.Format,
						pageTurnDelay = settings.PageTurnDelayDouble,
						motion = settings.Motion
					});
				}
				else
				{
					var data = DynamicJson.Parse(request.RequiredPostJson());
					var settings = request.CurrentBook.BookInfo.PublishSettings.AudioVideo;
					var oldMotion = settings.Motion;
					settings.Format = data.format;
					settings.PageTurnDelayDouble = data.pageTurnDelay;
					settings.Motion = data.motion;

					request.CurrentBook.BookInfo.SavePublishSettings();

					_recordVideoWindow?.SetPageReadTime(settings.PageTurnDelayDouble.ToString());
					_recordVideoWindow?.SetFormat(request.CurrentBook.BookInfo.PublishSettings.AudioVideo.Format,
						ShouldRecordAsLandscape(request.CurrentBook));
					if (settings.Motion != oldMotion)
					{
						UpdatePreview(request); // does its own success/fail
					}
					else
					{
						request.PostSucceeded();
					}
				}
			}, true, false);
			apiHandler.RegisterEndpointHandler(kApiUrlPart + "videoSettings", request =>
			{
				if (request.HttpMethod == HttpMethods.Get)
				{
					request.ReplyWithText(request.CurrentBook.BookInfo.PublishSettings.AudioVideo.PlayerSettings ?? "");
				}
				else
				{
					request.CurrentBook.BookInfo.PublishSettings.AudioVideo.PlayerSettings =
						request.RequiredPostString();
					request.CurrentBook.BookInfo.SavePublishSettings();
				}
			}, true, false);


			apiHandler.RegisterBooleanEndpointHandler(kApiUrlPart + "hasActivities",
				request =>
				{
					return request.CurrentBook.HasActivities;
				},
				null, // no write action
				false,
				true); // we don't really know, just safe default

			apiHandler.RegisterEndpointHandler(kApiUrlPart + "startRecording", request =>
			{
				_recordVideoWindow?.StartFfmpeg();
				request.PostSucceeded();
			}, true, false);

			apiHandler.RegisterEndpointHandler(kApiUrlPart + "tooBigForScreenMsg",
				request =>
				{<commit_msg>Fix error when switching languages in Video preview (BL-11125)<commit_after>using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Bloom.Api;
using Bloom.Publish.Android;
using SIL.PlatformUtilities;

namespace Bloom.Publish.Video
{
	/// <summary>
	/// API calls starting with publish/video, used in the Publish panel for Video
	/// </summary>
	public class PublishAudioVideoAPI
	{
		private readonly BloomWebSocketServer _webSocketServer;
		// It's slightly weird that we use one of these, but the video is done by means
		// of an android-type book preview, and this class knows all about how to make one.
		private PublishToAndroidApi _publishToAndroidApi;
		private const string kApiUrlPart = "publish/av/";
		private RecordVideoWindow _recordVideoWindow;

		public PublishAudioVideoAPI(BloomWebSocketServer bloomWebSocketServer, PublishToAndroidApi publishToAndroidApi)
		{
			_webSocketServer = bloomWebSocketServer;
			_publishToAndroidApi = publishToAndroidApi;
		}

		public void RegisterWithApiHandler(BloomApiHandler apiHandler)
		{


			apiHandler.RegisterEndpointHandler(kApiUrlPart + "recordVideo", request =>
			{
				RecordVideo(request);
				request.PostSucceeded();
			}, true, false);

			// This is sent directly from BloomPlayer when it gets to the end of making the recording.
			// The player gives Bloom a list of all the sounds it played and their timings so we can
			// merge them into the captured video.
			apiHandler.RegisterEndpointHandler(kApiUrlPart + "soundLog", request =>
			{
				var soundLog = request.RequiredPostJson();
				_recordVideoWindow.StopRecording(soundLog);
				request.PostSucceeded();
			}, true, false);

			apiHandler.RegisterEndpointHandler(kApiUrlPart + "playVideo", request =>
			{
				_recordVideoWindow.PlayVideo();
				request.PostSucceeded();
			}, true, false);

			apiHandler.RegisterEndpointHandler(kApiUrlPart + "settings", request =>
			{
				if (request.HttpMethod == HttpMethods.Get)
				{
					var settings = request.CurrentBook.BookInfo.PublishSettings.AudioVideo;
					request.ReplyWithJson(new {
						format= settings.Format,
						pageTurnDelay = settings.PageTurnDelayDouble,
						motion = settings.Motion
					});
				}
				else
				{
					var data = DynamicJson.Parse(request.RequiredPostJson());
					var settings = request.CurrentBook.BookInfo.PublishSettings.AudioVideo;
					var oldMotion = settings.Motion;
					settings.Format = data.format;
					settings.PageTurnDelayDouble = data.pageTurnDelay;
					settings.Motion = data.motion;

					request.CurrentBook.BookInfo.SavePublishSettings();

					_recordVideoWindow?.SetPageReadTime(settings.PageTurnDelayDouble.ToString());
					_recordVideoWindow?.SetFormat(request.CurrentBook.BookInfo.PublishSettings.AudioVideo.Format,
						ShouldRecordAsLandscape(request.CurrentBook));
					if (settings.Motion != oldMotion)
					{
						UpdatePreview(request); // does its own success/fail
					}
					else
					{
						request.PostSucceeded();
					}
				}
			}, true, false);
			apiHandler.RegisterEndpointHandler(kApiUrlPart + "videoSettings", request =>
			{
				if (request.HttpMethod == HttpMethods.Get)
				{
					request.ReplyWithText(request.CurrentBook.BookInfo.PublishSettings.AudioVideo.PlayerSettings ?? "");
				}
				else
				{
					request.CurrentBook.BookInfo.PublishSettings.AudioVideo.PlayerSettings =
						request.RequiredPostString();
					request.CurrentBook.BookInfo.SavePublishSettings();
					request.PostSucceeded();
				}
			}, true, false);


			apiHandler.RegisterBooleanEndpointHandler(kApiUrlPart + "hasActivities",
				request =>
				{
					return request.CurrentBook.HasActivities;
				},
				null, // no write action
				false,
				true); // we don't really know, just safe default

			apiHandler.RegisterEndpointHandler(kApiUrlPart + "startRecording", request =>
			{
				_recordVideoWindow?.StartFfmpeg();
				request.PostSucceeded();
			}, true, false);

			apiHandler.RegisterEndpointHandler(kApiUrlPart + "tooBigForScreenMsg",
				request =>
				{
{'fraction_non_alphanumeric': 0.09443278607579311, 'fraction_numerical': 0.0006172077521293668, 'mean_word_length': 3.8370149253731345, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5778988', 'n_tokens_mistral': 2843, 'n_tokens_neox': 2251, 'n_words': 503}