/*
 * Copyright (C) 2016 Sami Kerola <kerolasa@iki.fi>
 * Copyright (C) 2016 Karel Zak <kzak@redhat.com>
 *
 * Copyright (c) 1980, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * 1999-02-22 Arkadiusz Miśkiewicz <misiek@pld.ORG.PL>
 *	added Native Language Support
 * 1999-09-19 Bruno Haible <haible@clisp.cons.org>
 *	modified to work correctly in multi-byte locales
 */

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

#include "nls.h"
#include "c.h"
#include "widechar.h"
#include "closestream.h"

/*
 * colcrt - replaces col for crts with new nroff esp. when using tbl.
 * Bill Joy UCB July 14, 1977
 *
 * This filter uses the up and down sequences generated by the new
 * nroff when used with tbl and by \u \d and \r.
 * General overstriking doesn't work correctly.
 * Underlining is split onto multiple lines, etc.
 *
 * Option - suppresses all underlining.
 * Option -2 forces printing of all half lines.
 */

enum { OUTPUT_COLS = 132 };

struct colcrt_control {
	FILE		*f;
	wchar_t		line[OUTPUT_COLS + 1];
	wchar_t		line_under[OUTPUT_COLS + 1];
	unsigned int	print_nl:1,
			need_line_under:1,
			no_underlining:1,
			half_lines:1;
};

static void __attribute__((__noreturn__)) usage(void)
{
	FILE *out = stdout;
	fputs(USAGE_HEADER, out);
	fprintf(out, _(" %s [options] [<file>...]\n"), program_invocation_short_name);

	fputs(USAGE_SEPARATOR, out);
	fputs(_("Filter nroff output for CRT previewing.\n"), out);

	fputs(USAGE_OPTIONS, out);
	fputs(_(" -,  --no-underlining    suppress all underlining\n"), out);
	fputs(_(" -2, --half-lines        print all half-lines\n"), out);

	fputs(USAGE_SEPARATOR, out);
	printf(USAGE_HELP_OPTIONS(25));

	printf(USAGE_MAN_TAIL("colcrt(1)"));

	exit(EXIT_SUCCESS);
}

static void trim_trailing_spaces(wchar_t *s)
{
	size_t size;
	wchar_t *end;

	size = wcslen(s);
	if (!size)
		return;
	end = s + size - 1;
	while (s <= end && iswspace(*end))
		end--;
	*(end + 1) = L'\0';
}


static void output_lines(struct colcrt_control *ctl, int col)
{
	/* first line */
	trim_trailing_spaces(ctl->line);
	fputws(ctl->line, stdout);

	if (ctl->print_nl)
		fputwc(L'\n', stdout);
	if (!ctl->half_lines && !ctl->no_underlining)
		ctl->print_nl = 0;

	wmemset(ctl->line, L'\0', OUTPUT_COLS);

	/* second line */
	if (ctl->need_line_under) {
		ctl->need_line_under = 0;
		ctl->line_under[col] = L'\0';
		trim_trailing_spaces(ctl->line_under);
		fputws(ctl->line_under, stdout);
		fputwc(L'\n', stdout);
		wmemset(ctl->line_under, L' ', OUTPUT_COLS);

	} else if (ctl->half_lines && 0 < col)
		fputwc(L'\n', stdout);
}

static int rubchars(struct colcrt_control *ctl, int col, int n)
{
	while (0 < n && 0 < col) {
		ctl->line[col] = L'\0';
		ctl->line_under[col] = L' ';
		n--;
		col--;
	}
	return col;
}

static void colcrt(struct colcrt_control *ctl)
{
	int col;
	wint_t c;
	long old_pos;

	ctl->print_nl = 1;
	if (ctl->half_lines)
		fputwc(L'\n', stdout);

	for (col = 0; /* nothing */; col++) {
		if (OUTPUT_COLS - 1 < col) {
			output_lines(ctl, col);
			errno = 0;
			old_pos = ftell(ctl->f);
			while ((c = getwc(ctl->f)) != L'\n') {
				long new_pos = ftell(ctl->f);
				if (old_pos == new_pos)
					fseek(ctl->f, 1, SEEK_CUR);
				else
					old_pos = new_pos;
				if (errno == 0 && c == WEOF)
					return;
				else
					errno = 0;
			}
			col = -1;
			continue;
		}
		c = getwc(ctl->f);
		switch (c) {
		case 033:	/* ESC */
			c = getwc(ctl->f);
			if (c == L'8') {
				col = rubchars(ctl, col, 1);
				continue;
			}
			if (c == L'7') {
				col = rubchars(ctl, col, 2);
				continue;
			}
			continue;
		case WEOF:
			ctl->print_nl = 0;
			output_lines(ctl, col);
			return;
		case L'\n':
			output_lines(ctl, col);
			col = -1;
			continue;
		case L'\t':
			for (/* nothing */; col % 8 && col < OUTPUT_COLS; col++) {
				ctl->line[col] = L' ';
			}
			col--;
			continue;
		case L'_':
			ctl->line[col] = L' ';
			if (!ctl->no_underlining) {
				ctl->need_line_under = 1;
				ctl->line_under[col] = L'-';
			}
			continue;
		default:
			if (!iswprint(c)) {
				col--;
				continue;
			}
			ctl->print_nl = 1;
			ctl->line[col] = c;
		}
	}
}

int main(int argc, char **argv)
{
	struct colcrt_control ctl = { NULL };
	int opt;
	enum { NO_UL_OPTION = CHAR_MAX + 1 };

	static const struct option longopts[] = {
		{"no-underlining", no_argument, NULL, NO_UL_OPTION},
		{"half-lines", no_argument, NULL, '2'},
		{"version", no_argument, NULL, 'V'},
		{"help", no_argument, NULL, 'h'},
		{NULL, 0, NULL, 0}
	};

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	/* Take care of lonely hyphen option. */
	for (opt = 0; opt < argc; opt++) {
		if (argv[opt][0] == '-' && argv[opt][1] == '\0') {
			ctl.no_underlining = 1;
			argc--;
			memmove(argv + opt, argv + opt + 1,
				sizeof(char *) * (argc - opt));
			opt--;
		}
	}

	while ((opt = getopt_long(argc, argv, "2Vh", longopts, NULL)) != -1) {
		switch (opt) {
		case NO_UL_OPTION:
			ctl.no_underlining = 1;
			break;
		case '2':
			ctl.half_lines = 1;
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			return EXIT_SUCCESS;
		case 'h':
			usage();
		default:
			errtryhelp(EXIT_FAILURE);
		}
	}

	argc -= optind;
	argv += optind;

	do {
		wmemset(ctl.line, L'\0', OUTPUT_COLS);
		wmemset(ctl.line_under, L' ', OUTPUT_COLS);

		if (argc > 0) {
			if (!(ctl.f = fopen(*argv, "r")))
				err(EXIT_FAILURE, _("cannot open %s"), *argv);
			argc--;
			argv++;
		} else
			ctl.f = stdin;

		colcrt(&ctl);
		if (ctl.f != stdin)
			fclose(ctl.f);
	} while (argc > 0);

	return EXIT_SUCCESS;
}
