/*
 * dml - Dialog Markup Language
 *
 * $Id: main.c,v 1.10 2003/08/23 14:15:50 malekith Exp $
 * Author: Michal Moskal <malekith@pld-linux.org>
 * include COPYING-GNU
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "pi.h"
#include "phash.h"
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

static char *progie;
static int out_fd;

static void usage(int err, char *name)
{
	fprintf(err ? stderr : stdout,
"USAGE: %s\n"
"		[ -e /* force stderr */ ]\n"
"		[ -c /* clobber */ ]\n"
"		[ -p /* poor man frames */\n"
"		[ -f input_file ]\n"
"		[ -o output_file ]\n"
"		[ -t title_string ]\n"
"		[ -C conf_file ]\n"
"		[ program ]\n", name);
}

static char *read_prog(int argc, char **argv, char *in)
{
	int len;
	char *r;
	
	if (optind < argc) {
		int i;
		
		if (in) {
			fprintf(stderr, "%s: inputfile and arguments "
				"specified\n", argv[0]);
			exit(1);
		} 

		len = 0;
		for (i = optind; i < argc; i++)
			len += strlen(argv[i]);
		r = xmalloc(len + 1);
		len = 0;
		for (i = optind; i < argc; i++) {
			strcpy(r + len, argv[i]);
			len += strlen(argv[i]);
		}
	} else {
		int fd = 0;
		char buf[512];
		struct dbuf *db;
		
		if (in && (fd = open(in, O_RDONLY)) == -1) {
			perror(in);
			exit(1);
		}

		db = db_new();

		while ((len = read(fd, buf, sizeof(buf))) > 0)
			memcpy(db_alloc(db, len), buf, len);
		db_addc(db, 0);
		r = db_finish(db, 0);
	}

	return r;
}

static void parse_options(int argc, char **argv)
{
	int c;
	int open_tty = 0, clobber = 0;
	char *out = 0, *in = 0;
	
	while ((c = getopt(argc, argv, "pehct:o:f:n:d:C:")) != -1)
		switch (c) {
		case 'c':
			clobber++;
			break;
		case 'e':
			open_tty++;
			break;
		case 't':
			pi_title_string = optarg;
			break;
		case 'C':
			pi_conf_file = optarg;
			break;
		case 'p':
			pi_poor_man_frames = 1;
			break;
		case 'o':
			out = optarg;
			break;
		case 'f':
			in = optarg;
			break;
		case 'h':
			usage(0, argv[0]);
			exit(0);
		case '?':
			usage(1, argv[0]);
			fprintf(stderr, "%s: unknown option -%c\n", 
				argv[0], optopt);
			exit(1);
		}


	progie = read_prog(argc, argv, in);
	
	if (open_tty || (in == 0 && optind == argc)) {
		close(0);
		dup(2);
	}

	if (out) {
		out_fd = open(out, O_WRONLY|O_CREAT|(clobber ? 0 : O_EXCL), 
			      0600);
		if (out_fd == -1) {
			perror(out);
			exit(1);
		}
	} else {
		out_fd = dup(1);
	}

	if (open_tty || out == 0) {
		close(1);
		dup(2);
	}
}

int main(int argc, char **argv)
{
	struct pi_window *p;
	int r, i;
	char *tmp;

	parse_options(argc, argv);

	/* this is to allow Shift+PgUp to look at displayed error
	 * messsages, but don't do it for xterm-like terminals */
	tmp = getenv("TERM");
	if (tmp == NULL || strstr(tmp, "xterm") == NULL) {
		r = getenv("LINES") ? atoi(getenv("LINES")) : 25;
		r++;
		tmp = (char*)malloc(r + 1);
		for (i = 0; i < r; i++)
			tmp[i] = '\n';
		tmp[i] = 0;
		printf(tmp);
		free(tmp);
	}
		
	pi_init();
	p = pi_make_ml_window(progie);
	r = pi_exec(p) - 1;
	pi_fini();

	pi_output(p, out_fd);

	return r;
}
