/* OTfile.c
 *
 * Copyright (C) 1997-2002 Paul Boersma
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 * pb 2001/08/02
 * pb 2002/07/16 GPL
 */

#include "OTfile.h"

#include "oo_DESTROY.h"
#include "OTfile_def.h"
#include "oo_COPY.h"
#include "OTfile_def.h"
#include "oo_EQUAL.h"
#include "OTfile_def.h"
#include "oo_WRITE_BINARY.h"
#include "OTfile_def.h"
#include "oo_READ_BINARY.h"
#include "OTfile_def.h"
#include "oo_DESCRIPTION.h"
#include "OTfile_def.h"

static int writeAscii (I, FILE *f) {
	iam (OTGrammar_file);
	long i, j;
	if (! inherited (OTGrammar_file) writeAscii (me, f)) return 0;
	ascputi4 (my numberOfConstraints, f, "numberOfConstraints");
	fprintf (f, "\nconstraintNames []: %s\n", my numberOfConstraints >= 1 ? "" : "(empty)");
	for (i = 1; i <= my numberOfConstraints; i ++)
		fprintf (f, "\"%s\"\t", my constraintNames [i] ? my constraintNames [i] : "");
	ascputi4 (my numberOfEvals, f, "numberOfEvals");
	for (i = 1; i <= my numberOfEvals; i ++) {
		fprintf (f, "\nevals [%ld]: \"%s\" \"%s\"", i,
			my inputs [i] ? my inputs [i] : "", my outputs [i] ? my outputs [i] : "");
		for (j = 1; j <= my numberOfConstraints; j ++)
			fprintf (f, "\t%6d", my marks [i] [j]);
	}
	return 1;
}

static int readAscii (I, FILE *f) {
	iam (OTGrammar_file);
	long i, j;
	if (! inherited (OTGrammar_file) readAscii (me, f)) return 0;
	my numberOfConstraints = ascgeti4 (f);
	if (my numberOfConstraints >= 1) {
		if (! (my constraintNames = NUMvector (sizeof (char *), 1, my numberOfConstraints))) return 0;
		for (i = 1; i <= my numberOfConstraints; i ++)
			if (! (my constraintNames [i] = ascgets2 (f))) return 0;
	}
	my numberOfEvals = ascgeti4 (f);
	if (my numberOfEvals >= 1) {
		if (! (my inputs = NUMvector (sizeof (char *), 1, my numberOfEvals))) return 0;
		if (! (my outputs = NUMvector (sizeof (char *), 1, my numberOfEvals))) return 0;
	}
	if (my numberOfEvals >= 1 && my numberOfConstraints >= 1) {
		if (! (my marks = NUMsmatrix (1, my numberOfEvals, 1, my numberOfConstraints))) return 0;
		for (i = 1; i <= my numberOfEvals; i ++) {
			if (! (my inputs [i] = ascgets2 (f))) return 0;
			if (! (my outputs [i] = ascgets2 (f))) return 0;
			for (j = 1; j <= my numberOfConstraints; j ++)
				my marks [i] [j] = ascgeti2 (f);
		}
	}
	return 1;
}

static const char **constraintNames (I) {
	iam (OTGrammar_file);
	return (const char **) & my constraintNames [0];
}

static int evaluate (I, int which, const char *input, const char *output, long icand_hint) {
	iam (OTGrammar_file);
	long i;
	/*
	 * An appreciable OPTIMIZATION:
	 */
	if (input [0] == '\0' && icand_hint <= my numberOfEvals)
		return my marks [icand_hint] [which];
	else
	/* End of optimization */
	for (i = 1; i <= my numberOfEvals; i ++)
		if (strequ (my inputs [i], input) && strequ (my outputs [i], output))
			return my marks [i] [which];
	return 0;
}

static long gen (I, thou, const char *input) {
	iam (OTGrammar_file);
	thouart (OTAnyTableau);
	long ncand = 0, i;
	for (i = 1; i <= my numberOfEvals; i ++)
		if (strequ (my inputs [i], input)) {
			thy candidates [++ ncand] = Melder_strdup (my outputs [i]);
			iferror return 0;
		}
	return ncand;
}

static void generateInput (I, char input []) {
	(void) void_me;
	sprintf (input, "");
}

static int locallyRanked (I, int c1, int c2) {
	(void) void_me;
	(void) c1;
	(void) c2;
	return 0;
}

class_methods (OTGrammar_file, OTAnyGrammar)
	class_method_local (OTGrammar_file, destroy)
	class_method_local (OTGrammar_file, description)
	class_method_local (OTGrammar_file, copy)
	class_method_local (OTGrammar_file, equal)
	class_method (writeAscii)
	class_method (readAscii)
	class_method_local (OTGrammar_file, writeBinary)
	class_method_local (OTGrammar_file, readBinary)
	class_method (constraintNames)
	class_method (evaluate)
	class_method (gen)
	class_method (generateInput)
	class_method (locallyRanked)
class_methods_end

/* End of file OTfile.c */
