/*
 * Copyright (c) 1997 Hong Hunsoo of (KAIST)
 * The Korea Advanced Institute of Science and Technology
 * 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. Neither the name of the KAIST 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 AUTHOR 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 AUTHOR 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.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "defs.h"
#include "common.h"

#define OFFSET 20
#define PATT_LEN 1024

struct fontset	*fset;
char	patterns[32][PATT_LEN];
int	columns;
struct character *chars[80];

void	final_output(struct character **chars);
void	put_patterns(void);
void	cleanbuf(void);
void	usage(const int should_I_die);
void	convert_string(char *str, const int len);


void
usage(const int should_I_die)
{
	fprintf(stderr, "usage: banner [-size howmany.columns] some.bdf\n");
	fprintf(stderr, "\t\tsize -0 means that columns no is about 1000\n");
	if (should_I_die)
		exit(should_I_die);
}

int
main(int argc, char *argv[])
{
	char	*fname= NULL, **app, *p;
	int	totcnt, sized;
	int	tmp0, tmp1;

	sized = 1;
	for (app = (argv + 1); *app != NULL; app++) {
		p = *app;
		if (strcmp(p, "-size") == 0) {
			columns = atoi(*++app);
			sized = 0;
			if (columns < -1)
				usage(1);
			if (columns == 0)
				columns = 1000;
		} else
			fname = p;
	}
	if (sized) {
		get_winsize(&tmp0, &tmp1);
		columns = tmp1;
	}
	if (fname == NULL)
		usage(1);

	fset = initial(fname);

	while (fgets(inbuf, LINE, stdin)) {
		totcnt = strlen(inbuf) - 1;
		inbuf[totcnt] = 0;

		convert_string(inbuf, totcnt);
		final_output(chars);
	}
				
	return 0;
}

void
clean_patterns(void)
{
	int	i;

	for (i=0; i<32;i++)
		memset(patterns[i], '.', PATT_LEN);
	return;
}

void
final_output(struct character **chars)
{
	struct character *cp;
	char	*p;
	int	i, j, printed, accum;
	int	height, offset;
	int	start, end;
	unsigned int *bits;
	struct bbox *bp, *fbp;

	fbp = &fset->f_boundingbox;
	height = fbp->bb_height;

	offset = 0; /* XXX */
	clean_patterns();
	accum = 0;
	while ((cp = *chars)) {

		bp = &cp->c_bbox;
		if (offset + bp->bb_offx + bp->bb_width > columns) {
			printed = accum;
			put_patterns();
			clean_patterns();
			offset = 0;
		}

		start = bp->bb_offx - fbp->bb_offx;
		end   = bp->bb_offx - fbp->bb_offx + bp->bb_width;

		for (i=0; i < height; i++) {
			bits = &(cp->c_rows[i]);
			p = &patterns[i][offset];
			for (j= start; j < end; j++) 
				if (step_mask[j] & *bits)
					p[j] = 'X';
		}
		offset += cp->c_dwidth[0];
		chars++;
		accum++;
	}
	if (accum != printed)
		put_patterns();
	return;
}

void
put_patterns(void)
{
	int	i, j, height, indx;
	char	*p;

	height = fset->f_boundingbox.bb_height;
	indx = 0;
	for (j=0; j < 10; j++)
		for (i=0; i <height; i++)
			if (patterns[i][j] != '.') {
				indx = j;
				j = 100; /* to double break */
				break;
			}
	for (i=0; i<height; i++) {
		p = &patterns[i][columns+20];
		while (*--p == '.')
			*p = 0;
		printf("%s\n", &patterns[i][indx]);
	}
	return;
}


void
convert_string(char *str, int len)
{
	char   *p, *lastp;
	struct character **charpp;

	charpp = &chars[0];
	lastp  = &str[len];
	for (p = str; p < lastp;) {
		if (p[0] != '\\') {
			*charpp++ = bsearch4char(fset, p[0]);
			p++;
		} else if (p[1] == 0) {
			*charpp++ = bsearch4char(fset, '\\');
			p++;
		} else if (isalpha(p[1])) {
			p = get_engcode(fset, &p[1], charpp);
			if (charpp[0]) /* found no code */
				charpp++;
		} else {
			*charpp++ = bsearch4char(fset, p[1]);
			p += 2;
		}
	}
	*charpp++ = NULL;
	return;
}
