/*
 * GraphApp - Cross-Platform Graphics Programming Library.
 *
 * File: drawtext.c -- cross-platform portable drawing functions.
 * Platform: Neutral  Version: 2.30  Date: 1998/01/01
 *
 * Version: 1.00  Changes: Original version by Lachlan Patrick.
 * Version: 1.50  Changes: gprintf now has internal state.
 * Version: 1.60  Changes: Major bugfixes!
 * Version: 2.00  Changes: Update to version 2.
 * Version: 2.01  Changes: Changed unnecessary longs to ints.
 * Version: 2.20  Changes: Added underlining ability.
 * Version: 2.30  Changes: Now uses getheight, getdescent.
 */

/* Copyright (C) 1993-1998 Lachlan Patrick

   This file is part of GraphApp, a cross-platform C graphics library.

   GraphApp is free software; you can redistribute it and/or modify it
   under the terms of the GNU Library General Public License.
   GraphApp is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY.

   See the file COPYLIB.TXT for details.
*/

#include "internal.h"
#include <stdarg.h>

#define COMPRESS_WHITESPACE 0

static const char *get_next_line(char *line, int width, const char *s)
{
    const char *t; char  *k;
    int	word_width, line_width;
    int	sp, tab, nl;

    line_width  = 0;

    for (t=s, k=line; *t!='\0'; line=k, s=t)
    {
	for (nl=tab=sp=0; (*t!='\0') && isspace(*t) && !nl; t++)
	{
#if COMPRESS_WHITESPACE
	    if (*t == '\n') nl++;
	    else if (*t == '\t') tab++;
	    else sp++;
#else
	    if (*t == '\n') nl++;
	    else if (*t == '\t') { /* expand tabs */
		for (tab=4; tab; tab--)
		    *k++ = ' ';
	    }
	    else
		*k++ = *t;
#endif
	}

	s = t;

	if (nl)	{ *k++ = '\n'; break; }
	else if (tab)	{ *k++ = ' '; *k++ = ' '; }
	else if (sp)	{ *k++ = ' ';  }

	/* fetch the next word to draw */

	for (*k='\0'; (*t!='\0') && !isspace(*t); *k='\0') {
	    if (*t == '-') {
		*k++ = *t++;
		*k = '\0';
		break;
	    }
	    *k++ = *t++;
	}

	/* determine where the word should be drawn */

	while (((word_width = strwidth(current->fnt,line)) > width)
	       && (k>line))
	{
	    *(--k) = '\0';
	    --t;
	}

	if (word_width > (width - line_width)) {
	    k = line;
	    break;
	} else
	    line_width += word_width;
    }

    *k = '\0';

    return (*s == '\0') ? NULL : s;
}

int textheight(int width, const char *s)
{
    int y;
    char line[256];
    int height;

    height = getheight(current->fnt);

    for(y=0; s; y+=height)
    {
	s = get_next_line(line, width, s);
    }

    return y;
}

static const char *draw_text_left(char *line, rect r, int line_height,
				  int underline, const char *s)
{
    char *k;
    point p;
    int width, height;
    font f;

    f = current->fnt;

    for(p=pt(r.x,r.y); (p.y<=r.y+r.height) && (s); p.y+=line_height)
    {
	s = get_next_line(line, r.width, s);

	for (k=line; *k!='\0'; k++)
	    continue;
	for (--k; (k>=line) && isspace(*k); k--)
	    *k = '\0';

	drawstr(p, line);

	if (underline) {
	    width = strwidth(f, line);
	    height = p.y+getheight(f)-getdescent(f)+2;
	    drawline(pt(p.x+1, height), pt(p.x+width-1, height));
	}
    }

    return s;
}

static const char *draw_text_right(char *line, rect r, int line_height,
			     int underline, const char *s)
{
    char *k;
    int w;
    point p;
    int width, height;
    font f;

    f = current->fnt;

    for(p=pt(r.x,r.y); (p.y<=r.y+r.height) && (s); p.y+=line_height)
    {
	s = get_next_line(line, r.width, s);

	for (k=line; *k!='\0'; k++)
	    continue;
	for (--k; (k>=line) && isspace(*k); k--)
	    *k = '\0';
	for (k=line; (*k!='\0') && isspace(*k); k++)
	    continue;

	w = strwidth(current->fnt, k);
	p.x = r.x+r.width - w;

	drawstr(p, k);

	if (underline) {
	    width = strwidth(f, k);
	    height = p.y+getheight(f)-getdescent(f)+2;
	    drawline(pt(p.x+1, height), pt(p.x+width-1, height));
	}
    }

    return s;
}

static const char *draw_text_centered(char *line, rect r, int line_height,
				      int underline, const char *s)
{
    char *k;
    int w;
    point p;
    int width, height;
    font f;

    f = current->fnt;

    for(p=pt(r.x,r.y); (p.y<=r.y+r.height) && (s); p.y+=line_height)
    {
	s = get_next_line(line, r.width, s);

	for (k=line; *k!='\0'; k++)
	    continue;
	for (--k; (k>=line) && isspace(*k); k--)
	    *k = '\0';
	for(k=line; (*k!='\0') && isspace(*k); k++)
	    continue;

	w = strwidth(current->fnt, k);
	p.x = r.x + (r.width-w)/2;

	drawstr(p, k);

	if (underline) {
	    width = strwidth(f, k);
	    height = p.y+getheight(f)-getdescent(f)+2;
	    drawline(pt(p.x+1, height), pt(p.x+width-1, height));
	}
    }

    return s;
}

static const char *draw_text_justified(char *line, rect r, int line_height,
				       int underline, const char *s)
{
    char *j, *k;
    int w, xw, nl, sc, sw, space_width;
    point p;
    int width, height;
    font f;

    space_width = strwidth(current->fnt, " ");
    f = current->fnt;

    for(p=pt(r.x,r.y); (p.y<=r.y+r.height) && (s); p.y+=line_height)
    {
	s = get_next_line(line, r.width, s);

	p.x = r.x;

	for(j=line; (*j!='\0') && isspace(*j); j++)
	    p.x += space_width;
	for (sc=0, k=j; *k!='\0'; k++)
	    if (isspace(*k))
		sc++;
	for (nl=0, --k; (k>=j) && isspace(*k); k--) {
	    if (*k == '\n')
		nl++;
	    *k = '\0';
	    sc--;
	}

	if ((sc==0) || nl || (! s)) {
	    drawstr(p, j);
	    width = strwidth(f, j);
	}
	else {
	    w = strwidth(f, j);
	    sw = space_width + (r.x+r.width-p.x-w)/sc;
	    xw = (r.x+r.width-p.x-w)%sc;

	    for(j=strtok(j," "); j; j=strtok(NULL," "))
	    {
		drawstr(p, j);
		p.x += sw + strwidth(f, j);
		if (xw) {
		    p.x++;
		    xw--;
		}
	    }
	    width = r.width;
	}
	if (underline) {
	    height = p.y+getheight(f)-getdescent(f)+2;
	    drawline(pt(p.x+1, height), pt(p.x+width-1, height));
	}
    }

    return s;
}

const char *drawtext(rect r, int alignment, const char *s)
{
    int h;
    int nlines;
    int line_height;
    int u = 0;
    rect clip;
    const char *remains;
    char line[256];

    initapp(0,0);
    if (! s) return (char *) NULL;
    if (! current->fnt)
	current->fnt = SystemFont;

    clip = getcliprect();
    setcliprect(r);

    line_height = getheight(current->fnt);

    if ((alignment & VCenter) == VCenter) {
	h = textheight(r.width, s);
	if (h < r.height)
	    r.y += (r.height-h)/2;
    }
    else if ((alignment & VJustify) == VJustify) {
	h = textheight(r.width, s);
	if (h < r.height) {
	    nlines = h / line_height;
	    if (nlines > 1)
		line_height += ((r.height-h) / (nlines-1));
	}
    }
    else if ((alignment & AlignBottom) == AlignBottom) {
	h = textheight(r.width, s);
	if (h < r.height)
	    r.y += (r.height-h);
    }

    u = (alignment & Underline);

    if ((alignment & Center) == Center)
	remains = draw_text_centered(line, r, line_height, u, s);
    else if ((alignment & Justify) == Justify)
	remains = draw_text_justified(line, r, line_height, u, s);
    else if ((alignment & AlignRight) == AlignRight)
	remains = draw_text_right(line, r, line_height, u, s);
    else
	remains = draw_text_left(line, r, line_height, u, s);

    setcliprect(clip);
    return remains;
}

int gprintf(const char *fmt, ...)
{
    static point p = {0,0};
    int count;
    int line_height;
    char *s, *t;
    va_list argptr;
    char str[256];

    va_start(argptr, fmt);
    count = vsprintf(str, fmt, argptr);

    initapp(0,0);
    if (! current->fnt)
	current->fnt = SystemFont;
    line_height = getheight(current->fnt);

    for (s=t=str; *s!='\0'; t++) {
	if (current->p.y != p.y) {
	    /* typewriter ping! */
	    p = current->p;
	}
	if (*t == '\n') {
	    /* print everything from s to t and move point down */
	    *t = '\0';
	    drawstr(p, s);
	    current->p.y += line_height;
	    /* go past the substring just printed */
	    s = t+1;
	}
	else if (*t == '\0') {
	    /* print final string without newline */
	    p.x += drawstr(p, s);
	    /* go to end of string, signal termination */
	    s = t;
	}
    }

    va_end(argptr);

    return count;
}
