/*
	Copyright (C) 2024-2025 Mark Tyler

	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 3 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 in the file COPYING.
*/

#include "wasp_qt.h"



MainWindow::MainWindow ( CommandLine & cline )
	:
	m_uprefs	( cline.userprefs() ),
	m_mprefs	( cline.get_memprefs() ),
	m_recent_files	( cline.recent_files() ),
	m_gin		( SDL_INIT_AUDIO ),
	m_volume_view	( new ShapeSplineView ( *this, m_project ) )
{
	setWindowTitle ( VERSION );

	std::string path;
	mtKit::get_data_dir ( path, DATA_INSTALL "/icons/hicolor/scalable/apps/"
		BIN_NAME ".svg" );
	setWindowIcon ( QIcon ( path.c_str () ) );

	QWidget * w = new QWidget;
	setCentralWidget ( w );

	create_menu ();

	QVBoxLayout * vbox_main = new QVBoxLayout;
	w->setLayout ( vbox_main );

	QTabWidget * tabWidget = new QTabWidget;
	vbox_main->addWidget ( tabWidget );

	create_shape_edit ( tabWidget );
//	create_wave_edit ( tabWidget );

/// ----------------------------------------------------------------------------

//	setMinimumSize ( 160, 160 );
	setGeometry ( m_mprefs.window_x, m_mprefs.window_y,
		m_mprefs.window_w, m_mprefs.window_h );

	if ( 1 == m_mprefs.window_maximized )
	{
		showMaximized ();
	}
	else
	{
		show ();
	}

	create_statusbar ();
	create_prefs_callbacks ();

	update_statusbar ();
	update_recent_files ();

	std::vector< char const * > const & fnames = cline.get_cline_files ();
	if ( fnames.size() > 0
		&& 0 == project_load ( fnames[0] )
		)
	{
		// Load a file from the command line if it's been set
	}
	else
	{
		update_titlebar ();
	}

	m_project.set_audio_device ( m_mprefs.audio_output_device );

	setAcceptDrops ( true );
}

void MainWindow::store_window_geometry ()
{
	if ( isMaximized () )
	{
		m_uprefs.set ( PREFS_WINDOW_MAXIMIZED, 1 );
	}
	else
	{
		m_uprefs.set ( PREFS_WINDOW_MAXIMIZED, 0 );

		m_uprefs.set ( PREFS_WINDOW_X, geometry().x () );
		m_uprefs.set ( PREFS_WINDOW_Y, geometry().y () );
		m_uprefs.set ( PREFS_WINDOW_W, geometry().width () );
		m_uprefs.set ( PREFS_WINDOW_H, geometry().height () );
	}
}

void MainWindow::update_titlebar ()
{
	std::string const txt ( m_project.get_titlebar_text () );

	setWindowTitle ( mtQEX::qstringFromC ( txt.c_str() ) );
}

void MainWindow::update_inputs ()
{
	m_text_wave_function->blockSignals ( true );
	m_text_wave_function->setText ( m_project.get_wave_function () );
	m_text_wave_function->blockSignals ( false );

	m_volume_view->load_values_from_project ();
	m_function_view->update ();
}

void MainWindow::closeEvent ( QCloseEvent * const ev )
{
	if ( isEnabled () == false )
	{
		// Main window is currently disabled so ignore all requests
		ev->ignore ();

		return;
	}

	if ( ok_to_lose_changes () )
	{
		// No changes, or user happy to lose them
		ev->accept ();
		store_window_geometry ();
	}
	else
	{
		// Changes have occured, user not consenting to lose them
		ev->ignore ();
	}
}

void MainWindow::dragEnterEvent ( QDragEnterEvent * const event )
{
	if ( event->mimeData ()->hasUrls () )
	{
		event->acceptProposedAction ();
	}
}

void MainWindow::dropEvent ( QDropEvent * const event )
{
	QList<QUrl> const list = event->mimeData ()->urls ();

	for ( int i = 0; i < list.size(); i++ )
	{
		QString const &filename = list.at ( i ).toLocalFile ();

		if ( filename.isEmpty () )
		{
			continue;
		}

		if ( 0 == project_load ( filename.toUtf8 ().data () ) )
		{
			break;
		}
	}

	event->acceptProposedAction ();
}

void MainWindow::create_prefs_callbacks ()
{
	m_uprefs.set_callback ( PREFS_FILE_RECENT_MAXLEN, [this]()
		{
			update_recent_files ();
		} );
	m_uprefs.set_callback ( PREFS_AUDIO_OUTPUT_DEVICE, [this]()
		{
			update_statusbar ();
			m_project.set_audio_device (
				m_mprefs.audio_output_device );
		} );
}

void MainWindow::press_audio_play ()
{
	double const secs = m_spin_wave_duration->value ();
	int const octave = m_spin_wave_octave->value ();

	if (	m_project.prepare_wave_audio ( secs, octave )
		|| m_project.play_audio ()
		)
	{
		QMessageBox::critical ( this, "Error", "Unable to play audio.");
	}
}

void MainWindow::press_audio_stop ()
{
	if ( m_project.stop_audio () )
	{
		QMessageBox::critical ( this, "Error", "Unable to stop audio.");
	}
}

void MainWindow::press_audio_set_audio_device ()
{
	DialogAudioDevicePicker ( *this, m_uprefs, m_mprefs );
}

void MainWindow::changed_text_wave_function ()
{
	m_project.set_wave_function ( m_text_wave_function->toPlainText ()
		.toUtf8 ().data () );

	m_function_view->update ();
	update_titlebar ();
}

