/* -*- Mode:Text -*- */
/*
 * good.c - see if a word or its root word
 * is in the dictionary.
 *
 * Pace Willisson, 1983
 */

#include <stdio.h>
#include <ctype.h>
#include "ispell.h"

struct dent *lookup();

static int wordok;


good (w)
register char *w;
{
	char nword[100];
	register char *p, *q;
	register n;

	for (p = w, q = nword; *p; p++, q++) {
		if (islower (*p))
			*q = toupper (*p);
		else
			*q = *p;
	}
	*q = 0;

	rootword[0] = 0;

	if (lookup (nword, strlen (nword)) != NULL) {
		return (1);
	}

	/* try stripping off suffixes */

	n = strlen (w);
	if (n == 1)
		return (1);

	if (n < 4)
		return (treelookup (w));

	wordok = 0;

	/* this part from 'check.mid' */
	switch (nword [ strlen (nword) - 1 ]) {
	case 'D': d_ending (nword); break;	/* FOR "CREATED", "IMPLIED", "CROSSED" */
	case 'T': t_ending (nword); break;	/* FOR "LATEST", "DIRTIEST", "BOLDEST" */
	case 'R': r_ending (nword); break;	/* FOR "LATER", "DIRTIER", "BOLDER" */
	case 'G': g_ending (nword); break;	/* FOR "CREATING", "FIXING" */
	case 'H': h_ending (nword); break;	/* FOR "HUNDREDTH", "TWENTIETH" */
	case 'S': s_ending (nword); break;	/* FOR ALL SORTS OF THINGS ENDING IN "S" */
	case 'N': n_ending (nword); break;	/* "TIGHTEN", "CREATION", "MULIPLICATION" */
	case 'E': e_ending (nword); break;	/* FOR "CREATIVE", "PREVENTIVE" */
	case 'Y': y_ending (nword); break;	/* FOR "QUICKLY" */
	default:
		break;
	}
	
	if (wordok) {
		strcpy (rootword, &hashstrings [ (int)(lastdent->word) ]);
	} else {
		wordok = treelookup (w); /* rootword shouldn't be set in this case */
	}
	return (wordok);

}


g_ending (w)
char *w;
{
	char *p;
	struct dent *dent;

	p = w + strlen (w) - 3;	/* if the word ends in 'ing', then *p == 'i' */
	
	if (strcmp (p, "ING") != 0)
		return;

	*p = 'E';	/* change I to E, like in CREATING */
	*(p+1) = 0;

	if (strlen (w) < 2)
		return;

	if ((dent = lookup (w, strlen (w))) != NULL) {
		if (dent->g_flag) 
			wordok = 1;
		return;
	}


	*p = 0;

	if (strlen (w) < 2)
		return;

	if (p[-1] == 'E')
		return;	/* this stops CREATEING */

	if (strlen (w) < 2)
		return;

	if ((dent = lookup (w, strlen (w))) != NULL) {
		if (dent->g_flag)
			wordok = 1;
		return;
	}
	return;
}

d_ending (w)
char *w;
{
	char *p;
	struct dent *dent;

	p = w + strlen (w) - 2;

	if (strcmp (p, "ED") != 0)
		return;

	p[1] = 0;	/* kill 'D' */

	if ((dent = lookup (w, strlen (w))) != NULL) {	/* like CREATED */
		if (dent->d_flag)
			wordok = 1;
		return;
	}

	if (strlen (w) < 3)
		return;

	p[0] = 0;
	p--;

	/* ED is now completely gone */

	if (p[0] == 'I' && !vowel (p[-1])) {
		p[0] = 'Y';
		if ((dent = lookup (w, strlen (w))) != NULL) {
			if (dent->d_flag)
				wordok = 1;
			return;
		}
	}

	if ((p[0] != 'E' && p[0] != 'Y') ||
	    (p[0] == 'Y' && vowel (p[-1]))) {
		if ((dent = lookup (w, strlen (w))) != NULL) {
			if (dent->d_flag)
				wordok = 1;
			return;
		}
	}
}

t_ending (w)
char *w;
{

	char *p;
	struct dent *dent;

	p = w + strlen (w) - 3;

	if (strcmp (p, "EST") != 0)
		return;

	p[1] = 0;	/* kill 'S' */

	if ((dent = lookup (w, strlen (w))) != NULL) {
		if (dent->t_flag)
			wordok = 1;
		return;
	}

	if (strlen (w) < 3)
		return;

	p[0] = 0;
	p--;

	/* EST is now completely gone */

	if (p[0] == 'I' && !vowel (p[-1])) {
		p[0] = 'Y';
		if ((dent = lookup (w, strlen (w))) != NULL) {
			if (dent->t_flag)
				wordok = 1;
			return;
		}
	}

	if ((p[0] != 'E' && p[0] != 'Y') ||
	    (p[0] == 'Y' && vowel (p[-1]))) {
		if ((dent = lookup (w, strlen (w))) != NULL) {
			if (dent->t_flag)
				wordok = 1;
			return;
		}
	}

}


r_ending (w)
char *w;
{
	char *p;
	struct dent *dent;

	p = w + strlen (w) - 2;

	if (strcmp (p, "ER") != 0)
		return;

	p[1] = 0;	/* kill 'R' */

	if ((dent = lookup (w, strlen (w))) != NULL) {
		if (dent->r_flag)
			wordok = 1;
		return;
	}

	if (strlen (w) < 3)
		return;

	p[0] = 0;
	p--;

	/* ER is now completely gone */

	if (p[0] == 'I' && !vowel (p[-1])) {
		p[0] = 'Y';
		if ((dent = lookup (w, strlen (w))) != NULL) {
			if (dent->r_flag)
				wordok = 1;
			return;
		}
	}

	if ((p[0] != 'E' && p[0] != 'Y') ||
	    (p[0] == 'Y' && vowel (p[-1]))) {
		if ((dent = lookup (w, strlen (w))) != NULL) {
			if (dent->r_flag)
				wordok = 1;
			return;
		}
	}

}

h_ending (w)
char *w;
{
	char *p;
	struct dent *dent;

	p = w + strlen (w) - 2;

	if (strcmp (p, "TH") != 0)
		return;

	*p = 0;

	p -= 2;

	if (strcmp (p, "IE") == 0) {
		p[0] = 'Y';
		p[1] = 0;
	}

	if ((dent = lookup (w, strlen (w))) != NULL)
		if (dent->h_flag)
			wordok = 1;

}

/*
 * check for flags: X, J, Z, S, P, M
 *
 * X	-ions or -ications or -ens
 * J	-ings
 * Z	-ers or -iers
 * S	-ies or -es or -s
 * P	-iness or -ness
 * M	-'S
 */

s_ending (w)
char *w;
{
	char *p;
	struct dent *dent;

	p = w + strlen (w);

	p[-1] = 0;

	if (index ("SXZHY", p[-2]) == NULL || (p[-2] == 'Y'  && vowel (p[-3]))) {
		if ((dent = lookup (w, strlen (w))) != NULL) {
			if (dent->s_flag)
				wordok = 1;
			return;
		}
	}


	switch (p[-2]) {	/* letter before S */
	case 'N':	/* X */
		if (strcmp (p-4, "ION") == 0) {
			p[-4] = 'E';
			p[-3] = 0;
			if ((dent = lookup (w, strlen (w))) != NULL) {
				if (dent->x_flag)
					wordok = 1;
				return;
			}
		}
		if (strcmp (p-8, "ICATE") == 0) {
			p[-8] = 'Y';
			p[-7] = 0;
			if ((dent = lookup (w, strlen (w))) != NULL && dent->x_flag)
				wordok = 1;
			return;
		}
		if (strcmp (p-3, "EN") == 0 && p[-4] != 'E' && p[-4] != 'Y') {
			p[-3] = 0;
			if ((dent = lookup (w, strlen (w))) != NULL && dent->x_flag)
				wordok = 1;
			return;
		}
	case 'G':	/* J */
		if (strcmp (p-4, "ING") != 0)
			return;
		p[-4] = 'E';
		p[-3] = 0;
		if ((dent = lookup (w, strlen (w))) != NULL) {
			if (dent->j_flag)
				wordok = 1;
			return;
		}
		p[-4] = 0;
		if (p[-5] == 'E')
			return;
		if ((dent = lookup (w, strlen (w))) != NULL && dent->j_flag)
			wordok = 1;
		return;
	case 'R':	/* Z */
		if (strcmp (p-3, "ER") != 0)
			return;

		p[-2] = 0;
		if ((dent = lookup (w, strlen (w))) != NULL) {
			if (dent->z_flag)
				wordok = 1;
			return;
		}
		if (p[-4] == 'I') {
			p[-4] = 'Y';
			p[-3] = 0;
			if ((dent = lookup (w, strlen (w))) != NULL && dent->z_flag)
				wordok = 1;
			return;
		}
		p[-3] = 0;
		if ((dent = lookup (w, strlen (w))) != NULL && dent->z_flag)
			wordok = 1;
		return;
	case 'E': /* S (except simple adding of an S) */
		p[-2] = 0;	/* drop the ES */
		if ((dent = lookup (w, strlen (w))) != NULL) {
			if (dent->s_flag)
				wordok = 1;;
			return;
		}
		if (p[-3] == 'I') {
			p[-3] = 'Y';
			if ((dent = lookup (w, strlen (w))) != NULL && dent->s_flag)
				wordok = 1;
			return;
		}
		return;

	case 'S':	/* P */
		if (strcmp (p-4, "NES") != 0)
			return;

		p[-4] = 0;	/* kill 'N' */
		if (p[-5] != 'Y' || vowel (p[-6])) {
			if ((dent = lookup (w, strlen (w))) != NULL) {
				if (dent->p_flag)
					wordok = 1;
				return;
			}
		}
		if (p[-5] == 'I') {
			p[-5] = 'Y';
			if ((dent = lookup (w, strlen (w))) != NULL && dent->p_flag)
				wordok = 1;
			return;
		}
		return;
	case '\'':	/* M */
		wordok = 1;
		return;
	}
}

/* only the N flag */
n_ending (w)
char *w;
{
	char *p;
	struct dent *dent;

	p = w + strlen (w);

	if (p[-2] == 'E') {
		if (p[-3] == 'E' || p[-3] == 'Y')
			return;
		p[-2] = 0;
		if ((dent = lookup (w, strlen (w))) != NULL && dent->n_flag)
			wordok = 1;
		return;
	}

	if (strcmp (p-3, "ION") != 0)
		return;

	p[-3] = 'E';
	p[-2] = 0;

	if ((dent = lookup (w, strlen (w))) != NULL) {
		if (dent->n_flag)
			wordok = 1;
		return;
	}

	if (strcmp (p-7, "ICATE") != 0)	/* check is really against "ICATION" */
		return;

	p[-7] = 'Y';
	p[-6] = 0;
	
	if ((dent = lookup (w, strlen (w))) != NULL && dent->n_flag)
		wordok = 1;
	return;
}

/* flags: v */
e_ending (w)
char *w;
{
	char *p;
	struct dent *dent;

	p = w + strlen (w);

	if (strcmp (p-3, "IVE") != 0)
		return;
	p[-3] = 'E';
	p[-2] = 0;

	if ((dent = lookup (w, strlen (w))) != NULL) {
		if (dent->v_flag)
			wordok = 1;
		return;
	}

	if (p[-4] == 'E')
		return;

	p[-3] = 0;

	if ((dent = lookup (w, strlen (w))) != NULL && dent->v_flag)
		wordok = 1;
	return;
}

/* flags: y */
y_ending (w)
char *w;
{
	char *p;
	struct dent *dent;

	p = w + strlen (w);

	if (strcmp (p-2, "LY") != 0)
		return;

	p[-2] = 0;

	if ((dent = lookup (w, strlen (w))) != NULL && dent->y_flag)
		wordok = 1;
	return;
}

vowel (c)
char c;
{
	return (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U');
}
