///       _       _     _ _       _     _
/// __  _(_) __ _| |__ | (_) __ _| |__ | |_
/// \ \/ / |/ _` | '_ \| | |/ _` | '_ \| __|
///  >  <| | (_| | | | | | | (_| | | | | |_
/// /_/\_\_|\__, |_| |_|_|_|\__, |_| |_|\__|
///         |___/           |___/
///
/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
///
/// xolatile@chud.cyou - xighlight - Generic source code terminal highlighter using VT100 escape sequences, very very slow...
///
/// This program is free software, free as in freedom and as in free beer, 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 any later version if you wish...
///
/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
/// for more details, if you dare, it is a lot of text that nobody wants to read...

#include "xtandard.h"
#include "xyntax.h"
#include "xanguage.h"

static procedure conditionally_exit (language_structure * language, syntax_structure * syntax, boolean terminate) {
	syntax   = syntax_deinitialize   (syntax);
	language = language_deinitialize (language);

	if (terminate == true) {
		exit (log_success);
	}
}

static procedure print_common (none) {
	print ("/B/4xighlight/-: /4Terminal syntax highlighter/-\n\n");
	print ("\tAuthor:  /4Ognjen 'xolatile' Milan Robovic/-\n");
	print ("\tLicense: /4GNU//GPLv3/-\n\n");
}

static procedure print_help (none) {
	print_common ();

	print ("Example usage:\n\n");
	print ("\t/6$ cat file.ext | xighlight [flags]/- /0---/- You need to pass language flag in this case.\n");
	print ("\t/6$ xighlight [flags] < file.ext/-     /0---/- You need to pass language flag in this case.\n");
	print ("\t/6$ xighlight file.ext/-               /0---/- Language is automatically detected in this case.\n\n");
	print ("Supported languages:\n\n");

	for (language_enumeration index = 0; index < language_count; ++index) {
		character align [32] = "";

		print ("\t/B/4%s/- /4%s/- /0---/- %s syntax highlighting\n",
		       language_short_option [index],
		       string_align_left (string_copy (align, language_long_option [index]), 9, ' '),
		       language_identifier [index]);
	}
}

static procedure print_version (none) {
	print_common ();

	print ("\tVersion: /40 (Zero)/-\n");
}

integer main (integer argc, character * * argv) {
	natural     select = language_count;
	natural     length = 0;
	character * buffer = null;

	syntax_structure   * syntax   = syntax_initialize   (360);
	language_structure * language = language_initialize (false);

	for (integer argument = 1; argument < argc; ++argument) {
		if (argument_compare (argv [argument], "-h", "--help") == true) {
			print_help         ();
			conditionally_exit (language, syntax, true);
		} else if (argument_compare (argv [argument], "-v", "--version") == true) {
			print_version      ();
			conditionally_exit (language, syntax, true);
		}

		for (natural index = 0; index < language_count; ++index) {
			if (argument_compare (argv [argument], language_short_option [index], language_long_option [index]) == true) {
				(* (language_highlighter [index])) (language, syntax);
				select = index;
				break;
			}
		}

		if (file_exists (argv [argument]) == true) {
			if (select == language_count) {
				select = (natural) file_type (argv [argument]);
			}
			if (buffer == null) {
				buffer = file_import (argv [argument]);
			}
		}
	}

	if (buffer == null) {
		buffer = record ();
	}

	language_conditionally_select (language, syntax, select);

	for (natural offset = 0; buffer [offset] != '\0'; offset += length) {
		select = syntax_select (syntax, & buffer [offset], & length);

		if (select >= syntax->count) {
			echo_colour (colour_white, effect_normal);
		} else {
			echo_colour (syntax->colour [select], syntax->effect [select]);
		}

		output (& buffer [offset], length);

		echo_cancel ();
	}

	conditionally_exit (language, syntax, false);

	buffer = deallocate (buffer);

	return (log_success);
}