/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#+
#+     Internet Radio Automation & Encoding Toolkit
#+
#+     Copyright (C) 2018 - 2026 by Kevin C. O'Kane
#+
#+     Kevin C. O'Kane
#+     kc.okane@gmail.com
#+     https://www.cs.uni.edu/~okane
#+     https://threadsafebooks.com/
#+
#+ 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
#+
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

//	July 8, 2026

#include "includes.h"
#include "defines.h"
#include "common-externs.h"
#include "common-fcn-headers.h"

#include "global-extern-variables.h"


#include <vlc/libvlc.h>
#include <vlc/libvlc_renderer_discoverer.h>
#include <vlc/libvlc_media.h>
#include <vlc/libvlc_media_player.h>

#define SLASH '/'

void    overlay_vid(int);

void    on_overlay_preview_clicked(GtkButton *b) { // ok button dbx9
	overlay_vid(1);
	}

void    on_overlay_ok_clicked(GtkButton *b) { // ok button dbx9
	overlay_vid(0);
	}

void    on_overlay_ok1_clicked(GtkButton *b) { // ok button dbx9
	overlay1_vid(0);
	}

void	on_overlay_clear_clicked(GtkWidget *w) {
	gtk_editable_delete_text (GTK_EDITABLE(OverlayEntry1), 0, -1);
	gtk_editable_delete_text (GTK_EDITABLE(OverlayEntry2), 0, -1);
	gtk_spin_button_set_value (GTK_SPIN_BUTTON(clip_x), 0.0);
	gtk_spin_button_set_value (GTK_SPIN_BUTTON(clip_y), 0.0);
	}

void	on_overlay_clear1_clicked(GtkWidget *w) {
	gtk_editable_delete_text (GTK_EDITABLE(OverlayEntry4), 0, -1);
	gtk_editable_delete_text (GTK_EDITABLE(OverlayEntry5), 0, -1);
	}

void	on_OverlayEntry1_insert_text(GtkEditable  *entry, gchar *edit) {
	}

void	on_OverlayEntry4_insert_text(GtkEditable  *entry, gchar *edit) {
	}

void	on_OverlayEntry2_insert_text(GtkEditable  *entry, gchar *edit) {
	}

void	on_OverlayEntry5_insert_text(GtkEditable  *entry, gchar *edit) {
	}

void	OverlayEntry1_insert_text(int X) {

	int i;

	gtk_editable_delete_text (GTK_EDITABLE(OverlayEntry1), 0, -1);

	gtk_entry_set_text (GTK_ENTRY(OverlayEntry1), ProgramArray[X]);

	past_row1 = X;

	printf("Duration of first overlay entry %d \n",
	       i = (int)(GetTime(ProgramArray[X]) + 0.5) );

	return;
	}

void	OverlayEntry4_insert_text(int X) {

	int i;

	gtk_editable_delete_text (GTK_EDITABLE(OverlayEntry4), 0, -1);

	gtk_entry_set_text (GTK_ENTRY(OverlayEntry4), ProgramArray[X]);

	past_row1 = X;

	printf("Duration of first overlay entry %d \n",
	       i = (int)(GetTime(ProgramArray[X]) + 0.5) );

	return;
	}

void	OverlayEntry2_insert_text(int X) {

	int i;

	gtk_editable_delete_text (GTK_EDITABLE(OverlayEntry2), 0, -1);

	if ((filetype(ProgramArray[X])) >= 100) {
		error_message("Must be a video format clip.", NULL);
		}

	gtk_entry_set_text (GTK_ENTRY(OverlayEntry2), ProgramArray[X]);

	past_row2 = X;

	printf("Duration of second overlay entry %d %s\n",
	       i = (int)(GetTime(ProgramArray[X]) + 0.5) );

	gtk_adjustment_set_value(adjustment33, (double) i ); // set end time

	return;
	}

void	OverlayEntry5_insert_text(int X) {

	int i;

	gtk_editable_delete_text (GTK_EDITABLE(OverlayEntry5), 0, -1);

	if ((filetype(ProgramArray[X])) >= 100) {
		error_message("Must be a video format clip.", NULL);
		}

	gtk_entry_set_text (GTK_ENTRY(OverlayEntry5), ProgramArray[X]);

	past_row2 = X;

	printf("Duration of second overlay entry %d %s\n",
	       i = (int)(GetTime(ProgramArray[X]) + 0.5) );

	gtk_adjustment_set_value(adjustment43, (double) i ); // set end time

	return;
	}


//--------------------------
//	OVERLAY VIDEO CLIP
//--------------------------

// overlay still
// overlay transparent still

void    overlay_vid(int preview) {

	char tmp[16000];
	char tmp1[16000];
	int i, j, k;

	close_boxes();

	if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(frame_next))) 	// pause
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frame_next), TRUE);

//-------------------------------------------------
//	past1 is item being overlayed onto past2
//-------------------------------------------------

	gchar *first = gtk_entry_get_text(OverlayEntry1);
	gchar *secnd = gtk_entry_get_text(OverlayEntry2);

	for (past_row1 = 0; past_row1 < SP->scount; past_row1++)
		if (strcmp(ProgramArray[past_row1], first) == 0) break;

	for (past_row2 = 0; past_row2 < SP->scount; past_row2++)
		if (strcmp(ProgramArray[past_row2], secnd) == 0) break;

	printf("Overlay %d %s\n", past_row1, first);
	printf("onto  %d %s\n", past_row2, first);

	if (past_row1 < 0 || past_row2 < 0 ||
	        past_row1 > SP->scount || past_row2 > SP->scount) {

		error_message("Files not specified.", NULL);
		return;
		}

	printf("Overlay %s onto \n\t%s\n",
	       ProgramArray[past_row1], ProgramArray[past_row2]);

	for (i = strlen(ProgramArray[past_row2]); i > 0; i--) {
		if (ProgramArray[past_row2][i] == '.') break;
		}

	if (i == 0) strcpy(tmp1, "out.mp4");

	else {
		tmp1[i--] = 0;
		for (j = i; j >= 0; j--)
			tmp1[j] = ProgramArray[past_row2][j];
		}

	char new[16000];

	new_name(new, ProgramArray[past_row2], "ovl");

//---------------------------------------------------------------------------
//	cpu load note:
//	"taskset -c 0,1,2,3 ffmpeg -y -loglevel info -ss %d -i \"%s\" "
//	limit cpu time to keep from over heating. numbers are cpu core nbrs.
//---------------------------------------------------------------------------

	if (filetype(ProgramArray[past_row1]) < 100 ) {

		sprintf(tmp,

		        "ffmpeg -y -loglevel info -i \"%s\" -i \"%s\" "
		        " -filter_complex \"[0:0]setpts=PTS-STARTPTS[a]; "
		        "[a][1:0]overlay=enable='between(t,%d,%d):eof_action=pass:x=%d:y=%d'[out1]; "
		        "[out1]fps=25[out]\" -map [out] -map 0:1"
		        " -pix_fmt yuv420p "
		        " -c:a copy  -c:a libmp3lame -b:a 128k -c:v libx264 -preset veryslow -crf 20  ",

		        ProgramArray[past_row2],
		        ProgramArray[past_row1],
		        clip_start,
		        clip_end,
		        clip_x_coord,
		        clip_y_coord);
		}

	else {

		sprintf(tmp,

		        "ffmpeg -y -loglevel info -i \"%s\" -i \"%s\" "
		        " -filter_complex \"[0:v][1:v]overlay=enable="
		        "'between(t,%d,%d):x=%d:y=%d'\" -vcodec libx264  -c:a libmp3lame -b:a 128k -c:v libx264 -preset veryslow -crf 20   ",

		        ProgramArray[past_row2],
		        ProgramArray[past_row1],
		        clip_start,
		        clip_end,
		        clip_x_coord,
		        clip_y_coord);

		}

	if (preview) {
		strcat(tmp, FFPLAY);
		preview_run(tmp);
		return;
		}

	strcat(tmp, " \"");
	strcat(tmp, new);
	strcat(tmp, "\"");

	int err_stat = ff_run("Overlay", tmp, -1);

	if (err_stat != 0) {
		error_message(
			"An error or interrupt occurred - check video format compatibility\n", 
			tmp);
		return;
		}

	printf("Created: %s\n\n", new);

	clear_play();

	on_scan_video_dir_clicked(UPDATE_TILES);
        DisplayProgramButtons();

	}

//--------------------
//	OVERLAY AUDIO
//--------------------

void    overlay1_vid(int preview) {

	char tmp[16000];
	char tmp1[16000];
	int i, j, k;

	close_boxes();

	if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(frame_next))) 	// pause
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frame_next), TRUE);

//-------------------------------------------------
//	past1 is item being overlayed onto past2
//-------------------------------------------------

	gchar *first = gtk_entry_get_text(OverlayEntry4);
	gchar *secnd = gtk_entry_get_text(OverlayEntry5);

	for (past_row1 = 0; past_row1 < SP->scount; past_row1++)
		if (strcmp(ProgramArray[past_row1], first) == 0) break;

	for (past_row2 = 0; past_row2 < SP->scount; past_row2++)
		if (strcmp(ProgramArray[past_row2], secnd) == 0) break;

	printf("Overlay %d %s\n", past_row1, first);
	printf("onto  %d %s\n", past_row2, first);

	if (past_row1 < 0 || past_row2 < 0 ||
	        past_row1 > SP->scount || past_row2 > SP->scount) {

		error_message("Files not specified.", NULL);
		return;
		}

	printf("Overlay %s onto \n\t%s\n",
	       ProgramArray[past_row1], ProgramArray[past_row2]);

	for (i = strlen(ProgramArray[past_row2]); i > 0; i--) {
		if (ProgramArray[past_row2][i] == '.') break;
		}

	if (i == 0) strcpy(tmp1, "out.mp4");

	else {
		tmp1[i--] = 0;
		for (j = i; j >= 0; j--)
			tmp1[j] = ProgramArray[past_row2][j];
		}

	char new[16000];

	new_name(new, ProgramArray[past_row2], "aud-ovl");

//---------------------------------------------------------------------------
//	cpu load note:
//	"taskset -c 0,1,2,3 ffmpeg -y -loglevel info -ss %d -i \"%s\" "
//	limit cpu time to keep from over heating. numbers are cpu core nbrs.
//---------------------------------------------------------------------------


	sprintf(tmp, "ffmpeg -y -loglevel info -i \"%s\" -i \"%s\" -map 0:v -map 1:a "
	        "-c:v copy -shortest \"%s\"",
	        ProgramArray[past_row2], ProgramArray[past_row1], new);

	int err_stat = ff_run("Add audio", tmp, 0);

	if (err_stat != 0) {
		error_message("An error or interrupt occurred while processin", tmp);
		sprintf(tmp, "rm \"%s\"", new);
		system(tmp);
		return;
		}

	Zippy_says("Audio track altered.\n");

	printf("Created: %s\n\n", new);

	clear_play();

	on_scan_video_dir_clicked(UPDATE_TILES);
        DisplayProgramButtons();

	}

void    on_clip_x_value_changed(GtkSpinButton *r) {

	gdouble x = gtk_spin_button_get_value (GTK_SPIN_BUTTON(r));

	clip_x_coord = x;

	}

void    on_clip_y_value_changed(GtkSpinButton *r) {

	gdouble x = gtk_spin_button_get_value (GTK_SPIN_BUTTON(r));

	clip_y_coord = x;

	}

void    on_start_value_changed(GtkSpinButton *r) {

	gdouble x = gtk_spin_button_get_value (GTK_SPIN_BUTTON(r));

	clip_start = x;

	}

void    on_end_value_changed(GtkSpinButton *r) {

	gdouble x = gtk_spin_button_get_value (GTK_SPIN_BUTTON(r));

	clip_end = x;

	}

void    on_start1_value_changed(GtkSpinButton *r) {

	gdouble x = gtk_spin_button_get_value (GTK_SPIN_BUTTON(r));

	clip_start = x;

	}

void    on_end1_value_changed(GtkSpinButton *r) {

	gdouble x = gtk_spin_button_get_value (GTK_SPIN_BUTTON(r));

	clip_end = x;

	}

