/*
 *******************************************************************************
 *
 *   Copyright (C) 1999-2000, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
 *   file name:  letest.cpp
 *
 *   created on: 11/06/2000
 *   created by: Eric R. Mader
 */

#include "math.h"

#include "unicode/utypes.h"
#include "unicode/uscript.h"
#include "unicode/locid.h"

#include "unicode/loengine.h"

#include "PortableFontInstance.h"

#include "letest.h"

U_NAMESPACE_USE

UBool compareResults(int32_t testNumber, TestResult *expected, TestResult *actual)
{
	/* NOTE: we'll stop on the first failure 'cause once there's one error, it may cascade... */
	if (actual->glyphCount != expected->glyphCount) {
		printf("incorrect glyph count: exptected %d, got %d\n", expected->glyphCount, actual->glyphCount);
		return false;
	}

	int32_t i;

	for (i = 0; i < actual->glyphCount; i += 1) {
		if (actual->glyphs[i] != expected->glyphs[i]) {
			printf("incorrect id for glyph %d: expected %4X, got %4X\n", i, expected->glyphs[i], actual->glyphs[i]);
			return false;
		}
	}

	for (i = 0; i < actual->glyphCount; i += 1) {
		if (actual->indices[i] != expected->indices[i]) {
			printf("incorrect index for glyph %d: expected %8X, got %8X\n", i, expected->indices[i], actual->indices[i]);
			return false;
		}
	}

	for (i = 0; i <= actual->glyphCount; i += 1) {
		double xError = fabs(actual->positions[i * 2] - expected->positions[i * 2]);

		if (xError > 0.0001) {
			printf("incorrect x position for glyph %d: expected %f, got %f\n", i, expected->positions[i * 2], actual->positions[i * 2]);
			return false;
		}

		double yError = fabs(actual->positions[i * 2 + 1] - expected->positions[i * 2 + 1]);

		if (yError < 0) {
			yError = -yError;
		}

		if (yError > 0.0001) {
			printf("incorrect y position for glyph %d: expected %f, got %f\n", i, expected->positions[i * 2 + 1], actual->positions[i * 2 + 1]);
			return false;
		}
	}

	return true;
}

int main(int argc, char *argv[])
{
	Locale dummyLocale;
	int failures = 0;

	for (int test = 0; test < testCount; test += 1) {
        PFIErrorCode fontStatus = PFI_NO_ERROR;

        printf("Test %d, font = %s... ", test, testInputs[test].fontName);

		PortableFontInstance fontInstance(testInputs[test].fontName, 12, fontStatus);

        if (LE_FAILURE(fontStatus)) {
            printf("could not open font.\n");
            continue;
        }

		UErrorCode success = U_ZERO_ERROR;
		ICULayoutEngine *engine = ICULayoutEngine::createInstance(&fontInstance, testInputs[test].scriptCode, dummyLocale, success);
		int32_t textLength = testInputs[test].textLength;
		UBool result;
		TestResult actual;

        if (LE_FAILURE(success)) {
            // would be nice to print the script name here, but
            // don't know if it's worth the trouble to maintian
            // the table; better to wait for that fuctionality
            // to appear in ICU...
            printf("could not create a LayoutEngine.\n");
            continue;
        }

        actual.glyphCount = engine->layoutChars(testInputs[test].text, 0, textLength, textLength, testInputs[test].rightToLeft, 0, 0, success);

		actual.glyphs = new uint16_t[actual.glyphCount];
		actual.indices = new int32_t[actual.glyphCount];
		actual.positions = new float[actual.glyphCount * 2 + 2];

		engine->getGlyphs(actual.glyphs, success);
		engine->getCharIndices(actual.indices, success);
		engine->getGlyphPositions(actual.positions, success);

		result = compareResults(test, &testResults[test], &actual);

		if (result) {
			printf("passed.\n");
		} else {
			failures += 1;
			printf("failed.\n");
		}

		delete[] actual.positions;
		delete[] actual.indices;
		delete[] actual.glyphs;
		delete engine;
	}

	return failures;
}
