/**
 * main.c - main for SciteProj
 *
 *  Copyright 2006 Roy Wood, 2009-2018 Andreas Rönnquist
 *
 * This file is part of SciteProj.
 *
 * SciteProj 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.
 *
 * SciteProj 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 SciteProj.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <stdlib.h>

#include <gtk/gtk.h>
#include <glib.h>
#include <string.h>
#include <glib/gi18n.h>

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

#include <locale.h>

#include "clicked_node.h"
#include "gui.h"
#include "tree_manipulation.h"
#include "prefs.h"
#include "graphics.h"
#include "scite_utils.h"
#include "about.h"
#include "file_utils.h"
#include "string_utils.h"
#include "load_folder.h"
#include "script.h"

static struct CommandLineIndata {
	const gchar *scite_filename;
} cmd;


/*
 *		Program main entry
 */
int main(int argc, char *argv[])
{
	int returnCode = EXIT_FAILURE;
	GError *err = NULL;
	GOptionContext *context = NULL;

	static gboolean version = FALSE;
	static gchar *scite_instance = NULL;
	static gboolean load_a_folder = FALSE;
	static gboolean start_scite = FALSE;

	static const GOptionEntry options[] = {
		{	"version",		'v',	0, G_OPTION_ARG_NONE,		&version,
			N_("Show program version and quit")
		},
		{	"scite",			's',	0, G_OPTION_ARG_STRING,		&scite_instance,
			N_("Set a filename for the instance of SciTE to open"),	N_("SCITE_FILENAME")
		},
		{	"load_folder",	'l',	0,	G_OPTION_ARG_NONE,		&load_a_folder,
			N_("Load a folder")
		},
		{	"start_scite",	't',	0,	G_OPTION_ARG_NONE,		&start_scite,
			N_("Start SciTE automatically with SciteProj")
		},
		{ NULL }
	};

	// Init gettext stuff
	setlocale(LC_ALL, "");

	bindtextdomain(PACKAGE, LOCALEDIR);
	bind_textdomain_codeset(PACKAGE, "");
	textdomain(PACKAGE);

	gchar *sciteproj_description = g_strdup_printf(_("SciTE Project Manager"));

	gchar *full_desc_string = g_strdup_printf("- %s",sciteproj_description);

	context = g_option_context_new(full_desc_string);
	g_option_context_add_main_entries(context, options, NULL);
	if (!g_option_context_parse(context, &argc, &argv, &err)) {
		g_print(_("option parsing failed: %s"), err->message);
		printf("\n");
		exit(EXIT_FAILURE);
	}

	g_free(sciteproj_description);
	g_free(full_desc_string);

	/*
		Interpret the options
	 */
	/*
		set instance of SciTE to run
	*/
	if (scite_instance) {
		cmd.scite_filename = scite_instance;
	}

	init_version_string();

	/*
		Show SciteProj version
	*/
	if (version) {
		show_version();
		printf("\n");
		done_version_string();
		exit(EXIT_SUCCESS);
	}

	// Init gtk
	gtk_init(&argc, &argv);

	// Since glib 2.36, this isn't needed
	/*
#if GLIB_MAJOR_VERSION<=2 && GLIB_MINOR_VERSION<36
	g_type_init();
#endif
*/

	init_file_utils();

	gchar *current_dir = g_get_current_dir();

	if (argc > 2) {
		printf(_("A folder is expected as parameter to sciteproj..."));
		printf("\n");
		return EXIT_FAILURE;
	}

	gchar *dir_to_load;
	if (argc == 1) { // only "sciteproj" on the command-line
		dir_to_load = current_dir;

	} else { // "sciteproj <folder_name>" on the command-line
		dir_to_load = argv[1];

		gchar *newpath;

		if (relative_path_to_abs_path(dir_to_load, &newpath, current_dir, NULL)) {
			dir_to_load = newpath;
		}
	}

	// Init preferences
	if (!init_prefs(dir_to_load, &err)) {
		/*
		g_print(_("Error initing preferences: %s"), err->message);
		done_version_string();
		return EXIT_FAILURE;
		*/
	}

	// check environment variable
	gchar *scite_path_env = getenv("SciTE_HOME");

	// test for scite
	if (scite_path_env != NULL) {
		gchar *env_filename = g_build_filename(scite_path_env, "scite", NULL);
		if (g_file_test(env_filename, G_FILE_TEST_EXISTS)) {
			if (cmd.scite_filename == NULL) {
				cmd.scite_filename = g_strdup(env_filename);
			}
		} else {
			g_warning(_("Environment variable exists, but doesn't point to a folder containing scite."));
		}

		if (env_filename != NULL) g_free(env_filename);
		env_filename = g_build_filename(scite_path_env, "SciTE", NULL);
		if (g_file_test(env_filename, G_FILE_TEST_EXISTS)) {
			if (cmd.scite_filename == NULL) {
				cmd.scite_filename = g_strdup(env_filename);
			}
		} else {
			g_warning(_("Environment variable exists, but doesn't point to a folder containing scite."));
		}
	}

	// do we have a custom scite executable string as command line option?
	if (cmd.scite_filename != NULL) {

		// Does SciTE exist at that location?
		if (g_file_test(cmd.scite_filename, G_FILE_TEST_IS_REGULAR)) {

			// If we have already allocated memory for scite path, free it
			if (prefs.scite_path != NULL) g_free(prefs.scite_path);

			// Set the new one
			prefs.scite_path = g_strdup(cmd.scite_filename);

		} else {
			g_print(_("Couldn't find a SciTE executable named '%s'!\n"), cmd.scite_filename);
			g_print(_("Checking for SciTE in the standard locations instead.\n"));
		}
	}

	//g_option_context_free(context);

	/*
	 * Any "used" options has been removed from the argv/argc array here.
	 */

	// Check for SciTE
	if (!check_if_scite_exists()) {
		GtkWidget *warningDialog = gtk_message_dialog_new(get_main_window(), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
		                           _("Warning! Couldn't locate SciTE!\n"
		                             "Program will start, but you won't be able to open SciTE to edit files."));
		gtk_dialog_run(GTK_DIALOG(warningDialog));
		gtk_widget_destroy(warningDialog);
	}

	// Set up the GUI
	if (!setup_gui(&err)) {
		g_print(_("Could not setup the gui: %s"), err->message);
		g_print("\n");
		goto EXITPOINT;
	}

	if (!is_string_folder(dir_to_load)) {
		printf(_("Not a valid folder!"));
		printf("\n");
		return EXIT_FAILURE;
	}

	// Should we load a folder?
	set_project_filepath(dir_to_load, NULL);

	load_folder(dir_to_load, NULL);

	init_scite_connection();

	// open scite, if prefs says we should
	if (prefs.start_scite == TRUE || start_scite) {
		launch_scite("", NULL);
	}

	// Run the app

	gtk_main();

	returnCode = EXIT_SUCCESS;

EXITPOINT:

	gui_close();

	done_prefs();

	done_version_string();

	g_free(current_dir);

	if (err) g_error_free(err);

	return returnCode;
}
