/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#+
#+     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
#+
#+	astyle --style=banner --indent=tab load-program.c.in
#+
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

//	July 2, 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 '/'

//----------------------------------------------
//	remove starting and ending quote marks
//----------------------------------------------

void	quote_clean(char * in, char * out) {
	strcpy(out, &in[1]);
	out[strlen(out) - 1] = 0;
	}

int     hexcleaner(char *t) {

	char *_ftmp;
	int m, n = 0, p,f = 0;

	int i = strlen(t);

	_ftmp = (char *) malloc(i + 1);

	if (_ftmp == NULL ) {
		printf("Out of memory in hexcleaner\n");
		abort();
		}

	for(m=0; t[m]; m++) {

		if (t[m] == '\n' ) {
			f = 1;
			continue;
			}
		if (t[m] == '\r' ) {
			f = 1;
			continue;
			}

		if (t[m] == '%') {

			f = 1;
			if (t[m+1] >= 'a' && t[m+1] <= 'z') t[m+1] = t[m+1]-32;
			if (t[m+1] >= '0' && t[m+1] <= '9') p=( t[m+1]-'0' ) * 16;
			else p=(t[m+1]-'A'+10)*16;

			if (t[m+2] >= 'a' && t[m+2] <= 'z') t[m+2] = t[m+2]-32;
			if (t[m+2] >= '0' && t[m+2] <= '9') p = p+(t[m+2]-'0');
			else p = p + (t[m+2] - 'A' + 10);

			_ftmp[n] = p;  /* insert value into output string */
			n++;
			m = m + 2;
			}

		else {
			_ftmp[n++] = t[m];
			}
		}

	_ftmp[n]=0;
	strcpy(t,_ftmp);
	free(_ftmp);
	return f;
	}


void on_dialog_response (GtkWidget *dialog, gint response_id) {
	gtk_window_set_keep_above(GTK_WINDOW(dialog), FALSE);
	gtk_widget_destroy (dialog);
	return;
	}


void    Message(char * msg) {

	return; // unknow errors - won't destroy dislog
	if (strlen(msg) == 0) return;

	GdkColor color1;
	color1.red = 0x1111;
	color1.green = 0x1111;
	color1.blue = 0x9999;

	GdkColor color2;
	color2.red = 0xFFFF;
	color2.green = 0xFFFF;
	color2.blue = 0x0000;

	GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT ;

	GtkWidget *dialog = gtk_dialog_new_with_buttons ("Message", GTK_WINDOW(window),
	                    flags,
	                    "_OK", GTK_RESPONSE_CLOSE,
	                    NULL);

//	gtk_signal_connect (dialog, "close",

	g_signal_connect (dialog, "close",
	                    G_CALLBACK (on_dialog_response), NULL);

	gtk_widget_modify_bg(dialog, GTK_STATE_NORMAL, &color1);
	gtk_widget_modify_fg(dialog, GTK_STATE_NORMAL, &color2);

	gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);

	gtk_dialog_run (GTK_DIALOG (dialog));

	gtk_widget_destroy (dialog);
	}


void	gtk_widget_destroy(GtkWidget *w) { }

gboolean on_clip_markers_draw (GtkDrawingArea *widget, cairo_t *cr) {

	time_t 	len;
	double begin, end;

	if (mediaPlayer == NULL) return FALSE;

//---------------------
//	total length
//---------------------

	len = libvlc_media_player_get_length (mediaPlayer); // milliseconds

	end = clip_end;

	gint da_width, da_height;
	gtk_widget_get_size_request (GTK_WIDGET(widget), &da_width, &da_height);

	begin =
	    ((double) clip_start / (double) len) * (double) da_width; // da_width width of draw window

	end = ((double)(end) / (double) len) * (double) da_width;

	if (begin < end) {

		cairo_set_source_rgba(cr, 1.0, 0.2, 0.8, 1.0);
		cairo_rectangle (cr, begin, 0.0, end - begin, 10.);

		cairo_fill(cr); // fill in arc
		cairo_stroke (cr);

		}

	return FALSE;
	}

void	on_clear_clip_clicked(GtkWidget *w) {
	if (!mediaPlayer) return;
	vlc_no_pause();
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(full_speed), TRUE) ;
	clip_start = clip_end = 0;

#ifdef VLC4
	libvlc_media_player_set_time(mediaPlayer, 0, FALSE);
#else
	libvlc_media_player_set_time(mediaPlayer, 0);
#endif

	programData[SP->NowPlaying]->last_location = 0;
	frame_width = 0;
	frame_height = 0;
	mouse_ul_x = -1;
	vlc_start();
	gtk_widget_queue_draw(clip_markers);
	}


void    on_in_fade_value_changed(GtkSpinButton *s) {
	infade = gtk_spin_button_get_value(s);
	}

void    on_clip_duration_spinner_value_changed(GtkSpinButton *s) {
	clip_duration = gtk_spin_button_get_value(s);
	}

void    on_trans_duration_value_changed( GtkSpinButton *s) {
	trans_duration = gtk_spin_button_get_value(s);
	}

void    on_out_fade_value_changed( GtkSpinButton *s) {
	outfade = gtk_spin_button_get_value(s);
	}

void	reset_clipper() {
	cropLeft = 0.0, cropRight = 0.0;
	cropTop = 0.0, cropBottom = 0.0;
	outfade = gtk_spin_button_get_value(GTK_SPIN_BUTTON(out_fade));
	infade = gtk_spin_button_get_value(GTK_SPIN_BUTTON(in_fade));
	frame_height = 0;
	frame_width = 0;
	gtk_adjustment_set_value (adjustment40, 0.0);
	gtk_adjustment_set_value (adjustment54, 0.0);
	gtk_adjustment_set_value (adjustment6, 0.0);
	gtk_adjustment_set_value (adjustment7, 0.0);
	gtk_adjustment_set_value (adjustment1, 0.0);
	x_offset = 0;
	y_offset = 0;
	}

void	on_snapshot_clicked(GtkWidget *w) {

	char tmp[MAX_FILE_NAME], *p1, tmp1[MAX_FILE_NAME];

	if (!mediaPlayer) {
		error_message("No media playing.", NULL);
		return;
		}

	time_t t = time(0);

        sprintf(tmp, "mkdir -p \"%s/snapshots\" ", Music_Home_Directory);
        printf("%s\n", tmp);
        system(tmp);

	strcpy(tmp, SP->playThis);
	strcpy(tmp1, basename(tmp));

	new_name1(tmp, tmp1);

	printf("Snapshot:  %s\n",tmp);
	libvlc_video_take_snapshot(mediaPlayer,0, tmp, 0, 0);

	}

void	on_full_speed_clip_pressed(GtkWidget *w) { // radio button
	}

void	on_half_speed_clip_pressed(GtkWidget *w) {
	}


void	clear_play() {
	for (int i = 0; i < SP->scount; i++)
		programData[i]->play = 0;
	DisplayProgramButtons();
	}

void	on_clear_all_clicked(GtkWidget *w) {

	int i;

	for (i = 0; i < (SP->scount); i++) {
		programData[i]->play = 0;
		}
	DisplayProgramButtons( );
	}

void	on_select_all_clicked(GtkWidget *w) {

	int i;

	for (i = 0; i < (SP->scount); i++) {
		programData[i]->play = 1;
		}

	DisplayProgramButtons( );
	}

void	on_play_clip_clicked(GtkWidget *w) {

	if (!mediaPlayer) return;

#ifdef VLC4
	libvlc_media_player_set_time(mediaPlayer, clip_start, FALSE);
#else
	libvlc_media_player_set_time(mediaPlayer, clip_start);
#endif

	vlc_no_pause();

	}


void    on_granularity_value_changed( GtkSpinButton *s, GtkScrollType scr) {

	gdouble x = (int) gtk_adjustment_get_value(adjustment20);

	gtk_adjustment_set_step_increment (adjustment6, x);
	gtk_adjustment_set_step_increment (adjustment7, x);
	gtk_adjustment_set_step_increment (adjustment54, x);
	gtk_adjustment_set_step_increment (adjustment40, x);

	}

void    on_frame_forward2_value_changed(GtkSpinButton *r) { // start clip

	if (!mediaPlayer) return;

	if (ignore_me) {
		ignore_me = 0;
		return;
		}

	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(frame_next)))
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frame_next), FALSE);

	gdouble x = gtk_spin_button_get_value(r);

	t_position = x * 1000;

	clip_start = t_position;

	ignore_me = 1;

	frame_update();

	gtk_widget_queue_draw(clip_markers);

	}

void    on_frame_forward1_value_changed(GtkSpinButton *r) { // end clip

	if (!mediaPlayer) return;

	if (ignore_me) {
		ignore_me = 0;
		return;
		}

	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(frame_next)))
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frame_next), FALSE);

	gdouble x = gtk_spin_button_get_value(r);

	t_position = x * 1000;

	clip_end = t_position;

	ignore_me = 1;

	frame_update();

	gtk_widget_queue_draw(clip_markers);

	}

void	on_frame_reset_clicked(GtkWidget *w) {

	if (!mediaPlayer) return;
	clip_start = 0;
	clip_end = 0;
	ignore_me = 1;
	gtk_adjustment_set_value(adjustment22, 0.0);
	while (gtk_events_pending()) gtk_main_iteration();
	ignore_me = 1;
	gtk_adjustment_set_value(adjustment23, 0.0);
	while (gtk_events_pending()) gtk_main_iteration();
	}

void	on_check_format_clicked(GtkWidget *w) {

	int i, first = -1, second = -1;

	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frame_next), TRUE);

	for (i = 0; i < SP->scount; i++) {
		if (programData[i]->play) {
			first = i;
			break;
			}
		}

	if (first < 0) {
		error_message("No checked rows found", NULL);
		return;
		}

	for (i = first + 1; i < SP->scount; i++) {
		if (programData[i]->play) {
			second = i;
			int t = geo_test(ProgramArray[first], ProgramArray[second]);
			if (t == 0 ) {
				return;
				}
			first = second;
			}
		}

	}

void	close_boxes() {

	if (!mediaPlayer)
		if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(frame_next)))
			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frame_next), TRUE);

	}

//------------------------------------------------------
//	The following should not occur under Linux but
//	do, at present, under WSL2 Linux.
//------------------------------------------------------

gboolean on_merge_fixed_delete_event ( GtkWidget* w) {
	gtk_widget_hide(w);
	return TRUE;
	}


gboolean on_dbox4_delete_event ( GtkWidget* w) {
	gtk_widget_hide(w);
	return TRUE;
	}


void    strip(char* str) {
	int i, x;
	for(i = x = 0; str[i]; ++i)
		if( !isspace(str[i] ) || (i > 0 && !isspace(str[i - 1])))
			str[x++] = str[i];
	str[x] = '\0';
	}


//-----------------------------------------------------------------
//      cursors can be found here:
//      http://developer.gimp.org/api/2.0/gdk/gdk-Cursors.html
//-----------------------------------------------------------------

void    gtkSetCursor(GdkCursorType cursorType) {

	GdkScreen * screen = gdk_screen_get_default();
	GdkWindow * win = gdk_screen_get_root_window(screen);
	GdkCursor * cursor = gdk_cursor_new(cursorType);
	gdk_window_set_cursor(win, cursor);
	while (gtk_events_pending()) gtk_main_iteration();
	}

void    on_audio_ok_clicked(GtkButton *b) { // ok button dbx9

	close_boxes();

	audio_modify();

	clear_play();
	}

int	lastWord(char *x, int y) { 
	error_message("lastWord function error.", NULL);
	abort();
	return 0; 
	};

void on_Top1_map (GtkWidget *w) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frame_next), TRUE);
}

void on_fx12_map (GtkWidget *w) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frame_next), TRUE);
}

void on_ovl_holder2_map (GtkWidget *w) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frame_next), TRUE);
}

void on_ovl_fixed_map (GtkWidget *w) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frame_next), TRUE);
}

void on_opt_panel_map(GtkWidget *w) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frame_next), TRUE);
}

void on_ovl_fixed1_map (GtkWidget *w) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(frame_next), TRUE);
}

void	on_rename_clicked(GtkWidget *w) {
	char tmp[8192];
	sprintf(tmp, "caja --no-desktop \"%s\" &", Music_Home_Directory);
	system(tmp);
	}

//--------------------------------------------
//	launch MPV player with current file
//--------------------------------------------

void	on_mpv_player_clicked(GtkWidget *w) {

	if (!mediaPlayer) {
		error_message("No file plying.", NULL);
		return;
		}

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

	char tmp[MAX_FILE_NAME];

	sprintf(tmp, "mpv \"%s\" &", SP->playThis);

	system(tmp);

	}

void	on_end_play_clicked(GtkWidget *w) {
		skip = 1;
		}
