/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#+
#+     Internet Radio Automation & Encoding Toolkit
#+
#+     Copyright (C) 2018 - 2025 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
#+
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

//	Sept 27, 2025

//------------------------------------------------------------------
//	This is the root file for the Linux version of the player
//------------------------------------------------------------------

#define _GNU_SOURCE

#include "includes.h"
#include "common-externs.h"
#define SLASH '/'

//extern GtkWidget *plug;	// socket video
//extern unsigned int sockId;	// socket video

//---------------------
//	Play a file
//---------------------

int	vlc_start() {

//--------------------------------------------
//	socket video interface
//--------------------------------------------
//
//
//	if (ft == MP4 || ft == DVD) {
//		mpv_socket_running = 1;
//		EmbedVideo();
//		return 1;
//		}
//--------------------------------------------

	/*	compressor interface does not work on the VLC side

		const char *argv1[] = {"--verbose=-2", "--height=188", "--width=334",
	            "--audio-filter=compressor",
	            "--compressor-rms-peak=5.00",
	            "--compressor-attack=24.00",
	            "--compressor-release=250.00",
	            "--compressor-threshold=-25.00",
	            "--compressor-ratio=2.00",
	            "--compressor-knee=4.50",
	            "--compressor-makeup-gain=17.00" };
	*/

//-------------------------------------------------------------------------
//	Some instances of Linux have problems with the nvidia driver that
//	preevents .mkv files from dispklaying. The hardware driver is
//	disabled in the following. You may turn it on if your driver
//	has no issues.
//-------------------------------------------------------------------------

//	const char *argv1[] = {"--verbose=-2", "--avcodec-hw=vdpau_avcodec"};
	const char *argv1[] = {"--verbose=-2", "--avcodec-hw=none"};
	int argc = 2;

	const char *argv[] = {"--no-video", "--verbose=0" }; // audio only

	int i;
	char tmp[2048];

	if ( strncmp(SP->playThis, "http:", 5) !=0 &&
	        strncmp(SP->playThis, "https:", 6) !=0 &&
	        strncmp(SP->playThis, "file:", 5) !=0 &&
	        strncmp(SP->playThis, "smb:", 4) !=0 ) {  // not a special file link

		if (SP->playThis[0] != '/' ) {
			printf("*** file name does not begin with a / character\n");
			return EXIT_FAILURE;
			}

		if ( access(SP->playThis, R_OK) ) {   // returns non zero if bad
			printf("*** %s not found.\n", SP->playThis);
			return EXIT_FAILURE;
			}
		}

	if (inst) vlc_stop();

	int type = filetype(SP->playThis);

	strcpy(SP->CurrentPlay, SP->playThis);
	DisplayProgramButtons();

//--------------------------------------------------
//	send it to the webkit - under developement
//--------------------------------------------------

	if (strncmp(tmp, "https://",8) == 0 ||
	        strncmp(tmp, "file://",7) == 0 ||
	        strncmp(tmp, "http://",7) == 0 ) {
		printf("webkit says play this: %s\n",SP->playThis);
		SP->playProgram = FALSE;
		strcpy(web_url, SP->playThis);
		webkit_web_view_load_uri(WEBKIT_WEB_VIEW(webkit), web_url);
		gtk_entry_set_text (GTK_ENTRY(web_entry), SP->playThis);
		gtk_stack_set_visible_child (GTK_STACK(stack1), web_panel);
		return 1;
		}

//-----------------------
//	create an inst
//-----------------------

	if (!inst) {

		printf("New VLC instance created\n");

//-----------------------------
//		video setup
//-----------------------------

		if (SP->showVideo) {  // VIDEO

			inst = libvlc_new (argc, (const char * const *) argv1);

//---------------------------------------------------
//			display modules available
//---------------------------------------------------

			libvlc_module_description_t* vlc_mods = libvlc_video_filter_list_get(inst);

//--------------------------------------------------------------------------
//	uncomment to see video modules available
//--------------------------------------------------------------------------
//
//			printf("Video modules available \n");
//			while(vlc_mods != NULL) { // module list
//				printf("	modules available %s\n",
//					vlc_mods->psz_name);
//				vlc_mods = vlc_mods->p_next;
//				}
//
//--------------------------------------------------------------------------

			libvlc_module_description_list_release(vlc_mods);

			vlc_mods = libvlc_audio_filter_list_get(inst);

//--------------------------------------------------------------------------------
//	uncomment to se audio modules available
//--------------------------------------------------------------------------------
//
//			printf("Audio modules available \n");
//			while(vlc_mods != NULL) { // module list
//				printf("	modules available %s\n",
//					vlc_mods->psz_name);
//				vlc_mods = vlc_mods->p_next;
//				}
//
//--------------------------------------------------------------------------------

			libvlc_module_description_list_release(vlc_mods);
			}

//----------------------------------
//		audio only setup
//----------------------------------

		else {  // AUDIO ONLY

			inst = libvlc_new (2, (const char * const*) &argv);

//---------------------------------------------------
//			display modules available
//---------------------------------------------------

			libvlc_module_description_t* vlc_mods = libvlc_audio_filter_list_get(inst);

//-------------------------------------------------------------------------------------
//	Uncomment the following to see display of audio modules available
//-------------------------------------------------------------------------------------
//
//
//			printf("	Audio modules available \n");
//
//			while(vlc_mods != NULL) { // module list
//				printf("	modules available %s\n",
//					vlc_mods->psz_name);
//				vlc_mods = vlc_mods->p_next;
//				}
//
//-------------------------------------------------------------------------------------

			libvlc_module_description_list_release(vlc_mods);
			}

		}

	if (media) {
		libvlc_media_release (media);
		media = NULL;
		}

	if (strncmp(SP->playThis, "smb:", 4) == 0) { // under development
		char vlcRef[4096] = "";
		if (smbParse(vlcRef, SP->playThis) == 0) return 0;

//--------------------------------------------------------------------------------------------------
//		format looks like:
//		/run/user/1000/gvfs/smb-share:server=lenovo,share=lenovoshare/Country/Quickstep.mp4
//--------------------------------------------------------------------------------------------------

		printf("vlc smb ref: *%s*\n", vlcRef);
//		media = libvlc_media_new_path (inst, vlcRef);

#ifdef VLC4
		media = libvlc_media_new_path (vlcRef);
#else
		media = libvlc_media_new_path (inst, vlcRef);
#endif

		return 1;

		}

//-----------------------------------
//	regular file path reference
//	connect media to path
//-----------------------------------

//	else  media = libvlc_media_new_path (inst, SP->playThis);

#ifdef VLC4
	else  media = libvlc_media_new_path (SP->playThis);
#else
	else  media = libvlc_media_new_path (inst, SP->playThis);
#endif


	if (!media) {
		vlc_stop();    // fail
		return EXIT_FAILURE;
		}

//--------------------------
//	get media meta data
//--------------------------

	get_meta(media);

//-------------------------------------------------
//	Create a media player playing environement
//-------------------------------------------------

	if (mediaPlayer) {
		libvlc_media_player_release (mediaPlayer);
		mediaPlayer = NULL;
		}

//	mediaPlayer = libvlc_media_player_new_from_media (media); // create media player

#ifdef VLC4
	mediaPlayer = libvlc_media_player_new_from_media (inst, media); // create media player
#else
	mediaPlayer = libvlc_media_player_new_from_media (media); // create media player
#endif


//--------------------------
//	show video?
//--------------------------

	gtk_widget_hide(drawV);

	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(show_video)) &&
	        (type != MP3 && type != WAV && type != FLAC))  { // must be a video

		gtk_widget_show(video_bg);

		GtkWidget *prior_stack = current_stack;

		video_file = 1;

//--------------------------------------------------------------------------
//		Embed video in video_draw widget - does not work in Wayland
//		First make video stack panel visible. Must be visible when
//		video initialized or seg fault.
//--------------------------------------------------------------------------

		gtk_stack_set_visible_child (GTK_STACK(stack1), movie);
		while (gtk_events_pending ()) gtk_main_iteration ();

		if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(video_panel)) ) {

			int hor, ver;

			gtk_window_get_size (GTK_WINDOW(window), &hor, &ver);

			gint width = ALBUM_IMAGE_MEDIUM_WIDTH * (hor / 1090.0 );
			gint height = ALBUM_IMAGE_MEDIUM_HEIGHT * (ver / 608.0 );

			gtk_widget_show(movie);
			gtk_widget_show(video_draw);
			gtk_widget_set_size_request (video_draw, width, height);
			gtk_widget_queue_draw (video_draw);
			while (gtk_events_pending ()) gtk_main_iteration ();

			gtk_widget_show(movie);
			gtk_widget_show(video_draw);

			int width1, width2, height1, height2;

			gtk_window_get_size (GTK_WINDOW(window), &width1, &height1);

			width2 = width1 - 440;

			height2 = height1 - 20;

			gtk_fixed_move (GTK_FIXED(movie), video_draw, (double) 2, (double) 2 );
			gtk_widget_set_size_request (video_draw, width2, height2);

			while (gtk_events_pending ()) gtk_main_iteration ();

			libvlc_media_player_set_xwindow(mediaPlayer,
			                                GDK_WINDOW_XID(gtk_widget_get_window(GTK_WIDGET(video_draw))));

			gtk_widget_hide(video_bg);
			gtk_widget_hide(drawV);
			}

		else {
			libvlc_media_player_set_xwindow(mediaPlayer,
			                                GDK_WINDOW_XID(gtk_widget_get_window(GTK_WIDGET(drawV))));
			gtk_widget_show(drawV);
			}

//--------------------------------------
//	nvidia driver issue fixer upper
//--------------------------------------

		libvlc_media_add_option(media, ":avcodec-hw=none"); // bad vlc codec

//----------------------------------------------------------------------------------
//		Comment out the following two lines if you want the video panel
//		of the stack to remian visible after initialization. these lines
//		cause the display to revert to the prior stack panel
//----------------------------------------------------------------------------------

		gtk_stack_set_visible_child (GTK_STACK(stack1), prior_stack);
		while (gtk_events_pending ()) gtk_main_iteration ();

		}

//----------------------------------
//	No video - Audio only
//----------------------------------

	else {
//		gtk_widget_hide(movie);
		video_file = 0;
		}

	printf("VLC player created from media\n");

//---------------------------------------
//	No need to keep the media now
//---------------------------------------

	if (media) {
		libvlc_media_release (media);
		media = NULL;
		}

//-----------------------
//	create equalizer
//-----------------------

	printf("Equalizer band count %d\n", libvlc_audio_equalizer_get_band_count());

	if (!equalizer) { // none already exists
		equalizer = libvlc_audio_equalizer_new();
		printf("Primary equalizer created\n");
		Eq_Vol = 0.0; // initial setting
		gtk_adjustment_set_value (GTK_ADJUSTMENT(adjustment10), Eq_Vol);
		}

//-----------------------
//	attach equalizer
//-----------------------

	SetVlcEqualizerPreAmp();

//----------------------------------
//	using a equalizer preset?
//----------------------------------

	if (SP->currentPreset >= 0) { // a preset has been clicked
		printf("Preset equalizer %d used\n", SP->currentPreset);
		getEqSettings(SP->preSet[SP->currentPreset], SP->currentPreset); // load the presets
		libvlc_media_player_set_equalizer(mediaPlayer, SP->preSet[SP->currentPreset]);
		}

//---------------------------------
//	start the media player
//---------------------------------

	int iplay = libvlc_media_player_play (mediaPlayer); // start playing media file

//-----------------------------------
//	master volume level
//-----------------------------------

	libvlc_audio_set_volume(mediaPlayer, 100.0);
	gtk_adjustment_set_value (GTK_ADJUSTMENT(adjustment35), 100.0);
	gtk_label_set_text(GTK_LABEL(masterVolLevel), "100%");

//------------------------
//	set preamp level
//------------------------

	SP->volumeLevel = INIT_VOLUME;
	outVolume(SP->volumeLevel); // preamp level

//------------------------
//	playback speed
//------------------------

	setVlcRate(1.0);

	return EXIT_SUCCESS;
	}

