/*
 * @(#)loengine.h	1.0 00/12/11
 *
 * (C) Copyright IBM Corp. 1998, 1999, 2000 - All Rights Reserved
 *
 */

#ifndef __LOENGINE_H
#define __LOENGINE_H

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

#include "layout/LETypes.h"
#include "layout/LayoutEngine.h"

U_NAMESPACE_BEGIN

/**
 * This is a wrapper class designed to allow ICU clients to
 * use LayoutEngine in a way that is consistent with the rest
 * of ICU.
 *
 * (LayoutEngine was developed seperately from ICU and
 * the same source is used in non-ICU environments, so it cannot
 * be changed to match ICU coding conventions).
 *
 * This class is designed for clients who wish to use LayoutEngine
 * to layout complex text. If you need to subclass LayoutEngine,
 * you'll need to use the LayoutEngine interfaces directly.
 *
 * Basically, it creates an instance of LayoutEngine, stashes
 * it in fLayoutEngine, and uses it to implement the layout
 * functionality.
 *
 * Use the createInstance method to create an ICULayoutEngine. Use
 * delete to destroy it. The layoutChars method computes the glyphs
 * and positions, and saves them in the ICULayoutEngine object.
 * Use getGlyphs, getPositions and getCharIndices to retreive this
 * data.
 *
 * You'll also need an implementation of LEFontInstance for your platform.
 *
 * @see LayoutEngine.h
 * @see LEFontInstance.h
 */
class U_LAYOUT_API ICULayoutEngine
{
private:
	/**
	 * This holds the instance of LayoutEngine that does all
	 * the work.
	 */
	LayoutEngine *fLayoutEngine;

	/**
	 * This no argument constructor is private so that clients
	 * can't envoke it. Clients should use createInstance.
	 *
	 * @see createInstance
	 */
	ICULayoutEngine();

	/**
	 * The main constructor. It is defined as private to
	 * stop clients from invoking it. Clients should use
	 * createInstance.
	 *
	 * @param layoutEngine - the LayoutEngine that this instance wraps.
	 *
	 * @see createInstance
	 */
	ICULayoutEngine(LayoutEngine *layoutEngine);

public:

	/**
	 * The destructor. At least on Windows it needs to be
	 * virtual to ensure that it deletes the object from the
	 * same heap that createInstance will allocate it from. We
	 * don't know why this is...
	 *
	 * @see createInstance
	 */
	virtual ~ICULayoutEngine();

	/**
	 * This method computes the glyph, character index and position arrays
	 * for the input characters.
	 *
	 * @param chars - the input character context
	 * @param startOffset - the starting offset of the characters to process
	 * @param endOffset - the ending offset of the characters to process
	 * @param max - the number of characters in the input context
	 * @param rightToLeft - true if the characers are in a right to left directional run
	 * @param x - the initial X position
	 * @param y - the initial Y position
	 * @param success - output parameter set to an error code if the operation fails
	 *
	 * @return the number of glyphs in the glyph array
	 *
	 * Note; the glyph, character index and position array can be accessed
	 * using the getter method below.
	 */
    int32_t layoutChars(const UChar chars[],
						int32_t startOffset,
						int32_t endOffset,
						int32_t maxOffset,
						UBool rightToLeft,
						float x, float y,
						UErrorCode &success);


	/**
	 * This method computes the glyph, character index and position arrays
	 * for the input characters.
	 *
	 * @param str - the input character context
	 * @param startOffset - the starting offset of the characters to process
	 * @param endOffset - the ending offset of the characters to process
	 * @param rightToLeft - true if the characers are in a right to left directional run
	 * @param x - the initial X position
	 * @param y - the initial Y position
	 * @param success - output parameter set to an error code if the operation fails
	 *
	 * @return the number of glyphs in the glyph array
	 *
	 * Note; the glyph, character index and position array can be accessed
	 * using the getter method below.
	 */
	int32_t layoutString(const UnicodeString &str,
						 int32_t startOffset,
						 int32_t endOffset,
						 UBool rightToLeft,
						 float x, float y,
						 UErrorCode &success);

	/**
	 * This method returns the number of glyphs in the glyph array. Note
	 * that the number of glyphs will be greater than or equal to the number
	 * of characters used to create the LayoutEngine.
	 *
	 * @return the number of glyphs in the glyph array
	 */
	int32_t countGlyphs() const;

	/**
	 * This method copies the glyph array into a caller supplied array.
	 * The caller must ensure that the array is large enough to hold all
	 * the glyphs.
	 *
	 * @param glyphs - the destiniation glyph array
	 * @param success - output parameter set to an error code if the operation fails
	 */
    void getGlyphs(uint16_t glyphs[], UErrorCode &success);

	/**
	 * This method copies the character index array into a caller supplied array.
	 * The caller must ensure that the array is large enough to hold a character
	 * index for each glyph.
	 *
	 * @param charIndices - the destiniation character index array
	 * @param success - output parameter set to an error code if the operation fails
	 */
    void getCharIndices(int32_t charIndices[], UErrorCode &success);

	/**
	 * This method copies the character index array into a caller supplied array.
	 * The caller must ensure that the array is large enough to hold a character
	 * index for each glyph.
	 *
	 * @param charIndices - the destiniation character index array
	 * @param indexBase - an offset which will be added to each index
	 * @param success - output parameter set to an error code if the operation fails
	 */
    void getCharIndices(int32_t charIndices[], int32_t indexBase, UErrorCode &success);

	/**
	 * This method copies the position array into a caller supplied array.
	 * The caller must ensure that the array is large enough to hold an
	 * X and Y position for each glyph, plus an extra X and Y for the
	 * advance of the last glyph.
	 *
	 * @param glyphs - the destiniation position array
	 * @param success - output parameter set to an error code if the operation fails
	 */
    void getGlyphPositions(float positions[], UErrorCode &success);

	/**
	 * This method returns the X and Y position of the glyph at the
	 * given index.
	 *
	 * Input parameters:
	 * @param glyphIndex - the index of the glyph
	 *
	 * Output parameters:
	 * @param x - the glyph's X position
	 * @param y - the glyph's Y position
	 * @param success - output parameter set to an error code if the operation fails
	 *
	 */
    void getGlyphPosition(int32_t glyphIndex, float &x, float &y, UErrorCode &success);

	/**
	 * This method returns an ICULayoutEngine capable of laying out text
	 * in the given font, script and langauge.
	 *
	 * @param fontInstance - the font of the text
	 * @param scriptCode - the script of the text
	 * @param locale - used to determine the language of the text
	 * @param success - output parameter set to an error code if the operation fails
	 *
	 * @return an ICULayoutEngine which can layout text in the given font.
	 *
	 * NOTE: currently, locale is ignored...
	 *
	 * @see LEFontInstance
	 */
    static ICULayoutEngine *createInstance(const LEFontInstance *fontInstance,
										   UScriptCode script, Locale &locale,
										   UErrorCode &success);
};

inline ICULayoutEngine::ICULayoutEngine()
{
	// nothing at all...
}

inline ICULayoutEngine::ICULayoutEngine(LayoutEngine *layoutEngine)
	: fLayoutEngine(layoutEngine)
{
	// nothing else to do
}

inline ICULayoutEngine::~ICULayoutEngine()
{
	delete fLayoutEngine;
	fLayoutEngine = 0;
}

inline int32_t ICULayoutEngine::layoutChars(const UChar chars[],
											int32_t startOffset,
											int32_t endOffset,
											int32_t maxOffset,
											UBool rightToLeft,
											float x, float y,
											UErrorCode &success)
{
	// NOTE: call reset() so that clients can safely reuse
	fLayoutEngine->reset();
	return fLayoutEngine->layoutChars(chars,
									  startOffset,
									  endOffset - startOffset,
									  maxOffset,
									  rightToLeft,
									  x, y,
									  (LEErrorCode &) success);
}

inline int32_t ICULayoutEngine::layoutString(const UnicodeString &str,
											int32_t startOffset,
											int32_t endOffset,
											UBool rightToLeft,
											float x, float y,
											UErrorCode &success)
{
	int32_t glyphCount = 0;
	int32_t max = str.length();
	UChar *chars = new UChar[max];

	str.extract(0, max, chars);

	// NOTE: call reset() so that clients can safely reuse
	fLayoutEngine->reset();
	glyphCount = fLayoutEngine->layoutChars(chars,
									  startOffset,
									  endOffset - startOffset,
									  max,
									  rightToLeft,
									  x, y,
									  (LEErrorCode &) success);

	delete[] chars;

	return glyphCount;
}

inline int32_t ICULayoutEngine::countGlyphs() const
{
	return fLayoutEngine->getGlyphCount();
}

inline void ICULayoutEngine::getGlyphs(uint16_t glyphs[], UErrorCode &success)
{
	fLayoutEngine->getGlyphs(glyphs, (LEErrorCode &) success);
}

inline void ICULayoutEngine::getCharIndices(int32_t charIndices[], UErrorCode &success)
{
    fLayoutEngine->getCharIndices(charIndices, (LEErrorCode &) success);
}

inline void ICULayoutEngine::getCharIndices(int32_t charIndices[], int32_t indexBase, UErrorCode &success)
{
	fLayoutEngine->getCharIndices(charIndices, indexBase, (LEErrorCode &) success);
}

inline void ICULayoutEngine::getGlyphPositions(float positions[], UErrorCode &success)
{
    fLayoutEngine->getGlyphPositions(positions, (LEErrorCode &) success);
}

inline void ICULayoutEngine::getGlyphPosition(int32_t glyphIndex, float &x, float &y, UErrorCode &success)
{
    fLayoutEngine->getGlyphPosition(glyphIndex, x, y, (LEErrorCode &) success);
}

inline ICULayoutEngine *ICULayoutEngine::createInstance(const LEFontInstance *fontInstance,
														UScriptCode script,
														Locale &locale, UErrorCode &success)
{
	LayoutEngine *engine = LayoutEngine::layoutEngineFactory(fontInstance,
															 (le_int32) script,
															 0,
															 (LEErrorCode &) success);
	
	return new ICULayoutEngine(engine);
}

U_NAMESPACE_END
#endif
