/*
 * %W% %E%
 *
 * (C) Copyright IBM Corp. 1998, 1999, 2000, 2001 - All Rights Reserved
 *
 */

#include "LETypes.h"
#include "OpenTypeTables.h"
#include "GlyphDefinitionTables.h"
#include "GlyphPositionAdjustments.h"
#include "GlyphIterator.h"
#include "Lookups.h"
#include "LESwaps.h"

U_NAMESPACE_BEGIN

GlyphIterator::GlyphIterator(LEGlyphID *theGlyphs, GlyphPositionAdjustment *theGlyphPositionAdjustments, le_int32 theGlyphCount,
    le_bool rightToLeft, le_uint16 theLookupFlags, LETag theFeatureTag, const LETag *theGlyphTags[],
    const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader)
  : direction(1), position(-1), nextLimit(theGlyphCount), prevLimit(-1),
    cursiveFirstPosition(-1), cursiveLastPosition(-1), cursiveBaselineAdjustment(0),
    glyphs(theGlyphs), glyphPositionAdjustments(theGlyphPositionAdjustments), lookupFlags(theLookupFlags),
    featureTag(theFeatureTag), glyphTags(theGlyphTags),
    glyphClassDefinitionTable(NULL),
    markAttachClassDefinitionTable(NULL)

{
    if (theGlyphDefinitionTableHeader != NULL) {
        glyphClassDefinitionTable = theGlyphDefinitionTableHeader->getGlyphClassDefinitionTable();
        markAttachClassDefinitionTable = theGlyphDefinitionTableHeader->getMarkAttachClassDefinitionTable();
    }

    if (rightToLeft) {
        direction = -1;
        position = theGlyphCount;
        nextLimit = -1;
        prevLimit = theGlyphCount;
    }
}

GlyphIterator::GlyphIterator(GlyphIterator &that)
{
    direction    = that.direction;
    position     = that.position;
    nextLimit    = that.nextLimit;
    prevLimit    = that.prevLimit;

    cursiveFirstPosition = that.cursiveFirstPosition;
    cursiveLastPosition  = that.cursiveLastPosition;

    glyphs = that.glyphs;
    glyphPositionAdjustments = that.glyphPositionAdjustments;
    lookupFlags = that.lookupFlags;
    featureTag = that.featureTag;
    glyphTags = that.glyphTags;
    glyphClassDefinitionTable = that.glyphClassDefinitionTable;
    markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
}

GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags)
{
    direction    = that.direction;
    position     = that.position;
    nextLimit    = that.nextLimit;
    prevLimit    = that.prevLimit;


    cursiveFirstPosition = that.cursiveFirstPosition;
    cursiveLastPosition  = that.cursiveLastPosition;

    glyphs = that.glyphs;
    glyphPositionAdjustments = that.glyphPositionAdjustments;
    lookupFlags = newLookupFlags;
    featureTag = that.featureTag;
    glyphTags = that.glyphTags;
    glyphClassDefinitionTable = that.glyphClassDefinitionTable;
    markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
}

GlyphIterator::GlyphIterator()
{
};

GlyphIterator::~GlyphIterator()
{
}

le_int32 GlyphIterator::getCurrStreamPosition() const
{
    return position;
}

le_bool GlyphIterator::isRightToLeft() const
{
    return direction < 0;
}

le_bool GlyphIterator::ignoresMarks() const
{
    return (lookupFlags & lfIgnoreMarks) != 0;
}

le_bool GlyphIterator::baselineIsLogicalEnd() const
{
    return (lookupFlags & lfBaselineIsLogicalEnd) != 0;
}

le_bool GlyphIterator::hasCursiveFirstExitPoint() const
{
    return cursiveFirstPosition >= 0;
}

le_bool GlyphIterator::hasCursiveLastExitPoint() const
{
    return cursiveLastPosition >= 0;
}

LEGlyphID GlyphIterator::getCurrGlyphID() const
{
    if (direction < 0) {
        if (position <= nextLimit || position >= prevLimit) {
            return 0xFFFF;
        }
    } else {
        if (position <= prevLimit || position >= nextLimit) {
            return 0xFFFF;
        }
    }

    return glyphs[position];
}

LEGlyphID GlyphIterator::getCursiveLastGlyphID() const
{
    if (direction < 0) {
        if (cursiveLastPosition <= nextLimit || cursiveLastPosition >= prevLimit) {
            return 0xFFFF;
        }
    } else {
        if (cursiveLastPosition <= prevLimit || cursiveLastPosition >= nextLimit) {
            return 0xFFFF;
        }
    }

    return glyphs[cursiveLastPosition];
}

void GlyphIterator::getCursiveLastExitPoint(LEPoint &exitPoint) const
{
    if (cursiveLastPosition >= 0) {
        exitPoint = cursiveLastExitPoint;
    }
}

float GlyphIterator::getCursiveBaselineAdjustment() const
{
    return cursiveBaselineAdjustment;
}

void GlyphIterator::getCurrGlyphPositionAdjustment(GlyphPositionAdjustment &adjustment) const
{
    if (direction < 0)
    {
        if (position <= nextLimit || position >= prevLimit)
        {
            return;
        }
    } else {
        if (position <= prevLimit || position >= nextLimit) {
            return;
        }
    }

    adjustment = glyphPositionAdjustments[position];
}

void GlyphIterator::getCursiveLastPositionAdjustment(GlyphPositionAdjustment &adjustment) const
{
    if (direction < 0)
    {
        if (cursiveLastPosition <= nextLimit || cursiveLastPosition >= prevLimit)
        {
            return;
        }
    } else {
        if (cursiveLastPosition <= prevLimit || cursiveLastPosition >= nextLimit) {
            return;
        }
    }

    adjustment = glyphPositionAdjustments[cursiveLastPosition];
}

void GlyphIterator::setCurrGlyphID(LEGlyphID glyphID)
{
    glyphs[position] = glyphID;
}

void GlyphIterator::setCurrStreamPosition(le_int32 newPosition)
{
    cursiveFirstPosition      = -1;
    cursiveLastPosition       = -1;
    cursiveBaselineAdjustment =  0;

    if (direction < 0) {
        if (newPosition >= prevLimit) {
            position = prevLimit;
            return;
        }

        if (newPosition <= nextLimit) {
            position = nextLimit;
            return;
        }
    } else {
        if (newPosition <= prevLimit) {
            position = prevLimit;
            return;
        }

        if (newPosition >= nextLimit) {
            position = nextLimit;
            return;
        }
    }

    position = newPosition - direction;
    next();
}

void GlyphIterator::setCurrGlyphPositionAdjustment(const GlyphPositionAdjustment *adjustment)
{
    if (direction < 0) {
        if (position <= nextLimit || position >= prevLimit) {
            return;
        }
    } else {
        if (position <= prevLimit || position >= nextLimit) {
            return;
        }
    }

    glyphPositionAdjustments[position] = *adjustment;
}

void GlyphIterator::setCurrGlyphBaseOffset(le_int32 baseOffset)
{
    if (direction < 0) {
        if (position <= nextLimit || position >= prevLimit) {
            return;
        }
    } else {
        if (position <= prevLimit || position >= nextLimit) {
            return;
        }
    }

    glyphPositionAdjustments[position].setBaseOffset(baseOffset);
}

void GlyphIterator::adjustCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
                                                      float xAdvanceAdjust, float yAdvanceAdjust)
{
    if (direction < 0) {
        if (position <= nextLimit || position >= prevLimit) {
            return;
        }
    } else {
        if (position <= prevLimit || position >= nextLimit) {
            return;
        }
    }

    glyphPositionAdjustments[position].adjustXPlacement(xPlacementAdjust);
    glyphPositionAdjustments[position].adjustYPlacement(yPlacementAdjust);
    glyphPositionAdjustments[position].adjustXAdvance(xAdvanceAdjust);
    glyphPositionAdjustments[position].adjustYAdvance(yAdvanceAdjust);
}

void GlyphIterator::setCursiveFirstExitPoint()
{
    if (direction < 0) {
        if (position <= nextLimit || position >= prevLimit) {
            return;
        }
    } else {
        if (position <= prevLimit || position >= nextLimit) {
            return;
        }
    }

    cursiveFirstPosition = position;
}

#if 0
void GlyphIterator::resetCursiveLastExitPoint()
{
    cursiveLastPosition = -1;
}
#else
void GlyphIterator::resetCursiveLastExitPoint()
{
    if ((lookupFlags & lfBaselineIsLogicalEnd) != 0 && cursiveFirstPosition >= 0 && cursiveLastPosition >= 0) {
        le_int32 savePosition = position, saveLimit = nextLimit;

        position  = cursiveFirstPosition - direction;
        nextLimit = cursiveLastPosition  + direction;

        while (nextInternal()) {
            glyphPositionAdjustments[position].adjustYPlacement(-cursiveBaselineAdjustment);
        }

        position  = savePosition;
        nextLimit = saveLimit;
    }

    cursiveLastPosition       = -1;
    cursiveFirstPosition      = -1;
    cursiveBaselineAdjustment =  0;
}
#endif

void GlyphIterator::setCursiveLastExitPoint(LEPoint &exitPoint)
{
    if (direction < 0) {
        if (position <= nextLimit || position >= prevLimit) {
            return;
        }
    } else {
        if (position <= prevLimit || position >= nextLimit) {
            return;
        }
    }

    cursiveLastPosition  = position;
    cursiveLastExitPoint = exitPoint;

}

void GlyphIterator::setCursiveBaselineAdjustment(float adjustment)
{
    cursiveBaselineAdjustment = adjustment;
}

void GlyphIterator::adjustCursiveLastGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
                                              float xAdvanceAdjust, float yAdvanceAdjust)
{
    if (direction < 0) {
        if (cursiveLastPosition <= nextLimit || cursiveLastPosition >= prevLimit) {
            return;
        }
    } else {
        if (cursiveLastPosition <= prevLimit || cursiveLastPosition >= nextLimit) {
            return;
        }
    }

    glyphPositionAdjustments[cursiveLastPosition].adjustXPlacement(xPlacementAdjust);
    glyphPositionAdjustments[cursiveLastPosition].adjustYPlacement(yPlacementAdjust);
    glyphPositionAdjustments[cursiveLastPosition].adjustXAdvance(xAdvanceAdjust);
    glyphPositionAdjustments[cursiveLastPosition].adjustYAdvance(yAdvanceAdjust);
}

le_bool GlyphIterator::filterGlyph(le_uint32 index) const
{
    LEGlyphID glyphID = (LEGlyphID) glyphs[index];
    le_int32 glyphClass = gcdNoGlyphClass;

    // FIXME: is this test really safe?
    if (glyphID >= 0xFFFE) {
        return true;
    }

    if (glyphClassDefinitionTable != NULL) {
        glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphID);
    }

    switch (glyphClass)
    {
    case gcdNoGlyphClass:
        return false;

    case gcdSimpleGlyph:
        return (lookupFlags & lfIgnoreBaseGlyphs) != 0;

    case gcdLigatureGlyph:
        return (lookupFlags & lfIgnoreLigatures) != 0;

    case gcdMarkGlyph:
    {
        if ((lookupFlags & lfIgnoreMarks) != 0) {
            return true;
        }

        le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;

        if ((markAttachType != 0) && (markAttachClassDefinitionTable != NULL)) {
            return markAttachClassDefinitionTable->getGlyphClass(glyphID) != markAttachType;
        }

        return false;
    }

    case gcdComponentGlyph:
        return (lookupFlags & lfIgnoreBaseGlyphs) != 0;

    default:
        return false;
    }
}

const LETag emptyTag = 0;
const LETag defaultTag = 0xFFFFFFFF;

le_bool GlyphIterator::hasFeatureTag() const
{
    if (featureTag == defaultTag || featureTag == emptyTag) {
        return true;
    }

    if (glyphTags != NULL) {
        const LETag *tagList = glyphTags[position];

        for (le_int32 tag = 0; tagList[tag] != emptyTag; tag += 1) {
            if (tagList[tag] == featureTag) {
                return true;
            }
        }
    }

    return false;
}

le_bool GlyphIterator::findFeatureTag()
{
    while (nextInternal()) {
        if (hasFeatureTag()) {
            prevInternal();
            return true;
        }
    }

    return false;
}


le_bool GlyphIterator::nextInternal(le_uint32 delta)
{
    le_int32 newPosition = position;

    while (newPosition != nextLimit && delta > 0) {
        do {
            newPosition += direction;
        } while (newPosition != nextLimit && filterGlyph(newPosition));

        delta -= 1;
    }

    position = newPosition;

    return position != nextLimit;
}

le_bool GlyphIterator::next(le_uint32 delta)
{
    return nextInternal(delta) && hasFeatureTag();
}

le_bool GlyphIterator::prevInternal(le_uint32 delta)
{
    le_int32 newPosition = position;

    while (newPosition != prevLimit && delta > 0) {
        do {
            newPosition -= direction;
        } while (newPosition != prevLimit && filterGlyph(newPosition));

        delta -= 1;
    }

    position = newPosition;

    return position != prevLimit;
}

le_bool GlyphIterator::prev(le_uint32 delta)
{
    return prevInternal(delta) && hasFeatureTag();
}

// FIXME: Why in the world did I write the code that's #if 0'd out?
le_int32 GlyphIterator::getMarkComponent(le_int32 markPosition) const
{
    le_int32 component = 0;
#if 0
    le_int32 posn, start = position, end = markPosition;

    if (markPosition < position) {
        start = markPosition;
        end = position;
    }

    for (posn = start; posn <= end; posn += 1) {
        if (glyphs[posn] == 0xFFFE) {
            component += 1;
		}
    }
#else
    le_int32 posn;

    for (posn = position; posn != markPosition; posn += direction) {
        if (glyphs[posn] == 0xFFFE) {
            component += 1;
        }
    }
#endif

    return component;
}

// This is basically prevInternal except that it
// doesn't take a delta argument, and it doesn't
// filter out 0xFFFE glyphs.
le_bool GlyphIterator::findMark2Glyph()
{
    le_int32 newPosition = position;

    do {
        newPosition -= direction;
    } while (newPosition != prevLimit && glyphs[newPosition] != 0xFFFE && filterGlyph(newPosition));

    position = newPosition;

    return position != prevLimit;
}

U_NAMESPACE_END
