/*
 *
 * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
 *
 */

#ifndef __GLYPHPOSITIONADJUSTMENTS_H
#define __GLYPHPOSITIONADJUSTMENTS_H

/**
 * \file
 * \internal
 */

#include "LETypes.h"
#include "OpenTypeTables.h"

U_NAMESPACE_BEGIN

class LEGlyphStorage;
class LEFontInstance;

class GlyphPositionAdjustments : public UMemory
{
private:
    class Adjustment : public UMemory {
    public:

        inline Adjustment();
        inline Adjustment(float xPlace, float yPlace, float xAdv, float yAdv, le_int32 baseOff = -1);
        inline ~Adjustment();

        inline float    getXPlacement() const;
        inline float    getYPlacement() const;
        inline float    getXAdvance() const;
        inline float    getYAdvance() const;

        inline le_int32 getBaseOffset() const;

        inline void     setXPlacement(float newXPlacement);
        inline void     setYPlacement(float newYPlacement);
        inline void     setXAdvance(float newXAdvance);
        inline void     setYAdvance(float newYAdvance);

        inline void     setBaseOffset(le_int32 newBaseOffset);

        inline void    adjustXPlacement(float xAdjustment);
        inline void    adjustYPlacement(float yAdjustment);
        inline void    adjustXAdvance(float xAdjustment);
        inline void    adjustYAdvance(float yAdjustment);

    private:
        float xPlacement;
        float yPlacement;
        float xAdvance;
        float yAdvance;

        le_int32 baseOffset;

        // allow copying of this class because all of its fields are simple types
    };

    class EntryExitPoint : public UMemory
    {
    public:
        inline EntryExitPoint();
        inline ~EntryExitPoint();

        inline le_bool isCursiveGlyph() const;
        inline le_bool baselineIsLogicalEnd() const;

        LEPoint *getEntryPoint(LEPoint &entryPoint) const;
        LEPoint *getExitPoint(LEPoint &exitPoint) const;

        inline void setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
        inline void setExitPoint(LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
        inline void setCursiveGlyph(le_bool baselineIsLogicalEnd);

    private:
        enum EntryExitFlags
        {
            EEF_HAS_ENTRY_POINT         = 0x80000000L,
            EEF_HAS_EXIT_POINT          = 0x40000000L,
            EEF_IS_CURSIVE_GLYPH        = 0x20000000L,
            EEF_BASELINE_IS_LOGICAL_END = 0x10000000L
        };

        le_uint32 fFlags;
        LEPoint fEntryPoint;
        LEPoint fExitPoint;
    };

    le_int32 fGlyphCount;
    EntryExitPoint *fEntryExitPoints;
    Adjustment *fAdjustments;

    GlyphPositionAdjustments();

public:
    GlyphPositionAdjustments(le_int32 glyphCount);
    ~GlyphPositionAdjustments();

    inline le_bool hasCursiveGlyphs() const;
    inline le_bool isCursiveGlyph(le_int32 index) const;
    inline le_bool baselineIsLogicalEnd(le_int32 index) const;

    const LEPoint *getEntryPoint(le_int32 index, LEPoint &entryPoint) const;
    const LEPoint *getExitPoint(le_int32 index, LEPoint &exitPoint) const;

    inline float getXPlacement(le_int32 index) const;
    inline float getYPlacement(le_int32 index) const;
    inline float getXAdvance(le_int32 index) const;
    inline float getYAdvance(le_int32 index) const;

    inline le_int32 getBaseOffset(le_int32 index) const;

    inline void setXPlacement(le_int32 index, float newXPlacement);
    inline void setYPlacement(le_int32 index, float newYPlacement);
    inline void setXAdvance(le_int32 index, float newXAdvance);
    inline void setYAdvance(le_int32 index, float newYAdvance);

    inline void setBaseOffset(le_int32 index, le_int32 newBaseOffset);

    inline void adjustXPlacement(le_int32 index, float xAdjustment);
    inline void adjustYPlacement(le_int32 index, float yAdjustment);
    inline void adjustXAdvance(le_int32 index, float xAdjustment);
    inline void adjustYAdvance(le_int32 index, float yAdjustment);
   
    void setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
    void setExitPoint(le_int32 index, LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
    void setCursiveGlyph(le_int32 index, le_bool baselineIsLogicalEnd);

    void applyCursiveAdjustments(LEGlyphStorage &glyphStorage, le_bool rightToLeft, const LEFontInstance *fontInstance);
};

inline GlyphPositionAdjustments::Adjustment::Adjustment()
  : xPlacement(0), yPlacement(0), xAdvance(0), yAdvance(0), baseOffset(-1)
{
    // nothing else to do!
}

inline GlyphPositionAdjustments::Adjustment::Adjustment(float xPlace, float yPlace, float xAdv, float yAdv, le_int32 baseOff)
  : xPlacement(xPlace), yPlacement(yPlace), xAdvance(xAdv), yAdvance(yAdv), baseOffset(baseOff)
{
    // nothing else to do!
}

inline GlyphPositionAdjustments::Adjustment::~Adjustment()
{
    // nothing to do!
}

inline float GlyphPositionAdjustments::Adjustment::getXPlacement() const
{
    return xPlacement;
}

inline float GlyphPositionAdjustments::Adjustment::getYPlacement() const
{
    return yPlacement;
}

inline float GlyphPositionAdjustments::Adjustment::getXAdvance() const
{
    return xAdvance;
}

inline float GlyphPositionAdjustments::Adjustment::getYAdvance() const
{
    return yAdvance;
}

inline le_int32 GlyphPositionAdjustments::Adjustment::getBaseOffset() const
{
    return baseOffset;
}

inline void GlyphPositionAdjustments::Adjustment::setXPlacement(float newXPlacement)
{
    xPlacement = newXPlacement;
}

inline void GlyphPositionAdjustments::Adjustment::setYPlacement(float newYPlacement)
{
    yPlacement = newYPlacement;
}

inline void GlyphPositionAdjustments::Adjustment::setXAdvance(float newXAdvance)
{
    xAdvance = newXAdvance;
}

inline void GlyphPositionAdjustments::Adjustment::setYAdvance(float newYAdvance)
{
    yAdvance = newYAdvance;
}

inline void GlyphPositionAdjustments::Adjustment::setBaseOffset(le_int32 newBaseOffset)
{
    baseOffset = newBaseOffset;
}

inline void GlyphPositionAdjustments::Adjustment::adjustXPlacement(float xAdjustment)
{
    xPlacement += xAdjustment;
}

inline void GlyphPositionAdjustments::Adjustment::adjustYPlacement(float yAdjustment)
{
    yPlacement += yAdjustment;
}

inline void GlyphPositionAdjustments::Adjustment::adjustXAdvance(float xAdjustment)
{
    xAdvance += xAdjustment;
}

inline void GlyphPositionAdjustments::Adjustment::adjustYAdvance(float yAdjustment)
{
    yAdvance += yAdjustment;
}

inline GlyphPositionAdjustments::EntryExitPoint::EntryExitPoint()
    : fFlags(0)
{
    fEntryPoint.fX = fEntryPoint.fY = fExitPoint.fX = fExitPoint.fY = 0;
}

inline GlyphPositionAdjustments::EntryExitPoint::~EntryExitPoint()
{
    // nothing special to do
}

inline le_bool GlyphPositionAdjustments::EntryExitPoint::isCursiveGlyph() const
{
    return (fFlags & EEF_IS_CURSIVE_GLYPH) != 0;
}

inline le_bool GlyphPositionAdjustments::EntryExitPoint::baselineIsLogicalEnd() const
{
    return (fFlags & EEF_BASELINE_IS_LOGICAL_END) != 0;
}

inline void GlyphPositionAdjustments::EntryExitPoint::setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd)
{
    if (baselineIsLogicalEnd) {
        fFlags |= (EEF_HAS_ENTRY_POINT | EEF_IS_CURSIVE_GLYPH | EEF_BASELINE_IS_LOGICAL_END);
    } else {
        fFlags |= (EEF_HAS_ENTRY_POINT | EEF_IS_CURSIVE_GLYPH);
    }

    fEntryPoint = newEntryPoint;
}

inline void GlyphPositionAdjustments::EntryExitPoint::setExitPoint(LEPoint &newExitPoint, le_bool baselineIsLogicalEnd)
{
    if (baselineIsLogicalEnd) {
        fFlags |= (EEF_HAS_EXIT_POINT | EEF_IS_CURSIVE_GLYPH | EEF_BASELINE_IS_LOGICAL_END);
    } else {
        fFlags |= (EEF_HAS_EXIT_POINT | EEF_IS_CURSIVE_GLYPH);
    }

    fExitPoint  = newExitPoint;
}

inline void GlyphPositionAdjustments::EntryExitPoint::setCursiveGlyph(le_bool baselineIsLogicalEnd)
{
    if (baselineIsLogicalEnd) {
        fFlags |= (EEF_IS_CURSIVE_GLYPH | EEF_BASELINE_IS_LOGICAL_END);
    } else {
        fFlags |= EEF_IS_CURSIVE_GLYPH;
    }
}

inline le_bool GlyphPositionAdjustments::isCursiveGlyph(le_int32 index) const
{
    return fEntryExitPoints != NULL && fEntryExitPoints[index].isCursiveGlyph();
}

inline le_bool GlyphPositionAdjustments::baselineIsLogicalEnd(le_int32 index) const
{
    return fEntryExitPoints != NULL && fEntryExitPoints[index].baselineIsLogicalEnd();
}

inline float GlyphPositionAdjustments::getXPlacement(le_int32 index) const
{
    return fAdjustments[index].getXPlacement();
}

inline float GlyphPositionAdjustments::getYPlacement(le_int32 index) const
{
    return fAdjustments[index].getYPlacement();
}

inline float GlyphPositionAdjustments::getXAdvance(le_int32 index) const
{
    return fAdjustments[index].getXAdvance();
}

inline float GlyphPositionAdjustments::getYAdvance(le_int32 index) const
{
    return fAdjustments[index].getYAdvance();
}


inline le_int32 GlyphPositionAdjustments::getBaseOffset(le_int32 index) const
{
    return fAdjustments[index].getBaseOffset();
}

inline void GlyphPositionAdjustments::setXPlacement(le_int32 index, float newXPlacement)
{
    fAdjustments[index].setXPlacement(newXPlacement);
}

inline void GlyphPositionAdjustments::setYPlacement(le_int32 index, float newYPlacement)
{
    fAdjustments[index].setYPlacement(newYPlacement);
}

inline void GlyphPositionAdjustments::setXAdvance(le_int32 index, float newXAdvance)
{
    fAdjustments[index].setXAdvance(newXAdvance);
}

inline void GlyphPositionAdjustments::setYAdvance(le_int32 index, float newYAdvance)
{
    fAdjustments[index].setYAdvance(newYAdvance);
}

inline void GlyphPositionAdjustments::setBaseOffset(le_int32 index, le_int32 newBaseOffset)
{
    fAdjustments[index].setBaseOffset(newBaseOffset);
}

inline void GlyphPositionAdjustments::adjustXPlacement(le_int32 index, float xAdjustment)
{
    fAdjustments[index].adjustXPlacement(xAdjustment);
}

inline void GlyphPositionAdjustments::adjustYPlacement(le_int32 index, float yAdjustment)
{
    fAdjustments[index].adjustYPlacement(yAdjustment);
}

inline void GlyphPositionAdjustments::adjustXAdvance(le_int32 index, float xAdjustment)
{
    fAdjustments[index].adjustXAdvance(xAdjustment);
}

inline void GlyphPositionAdjustments::adjustYAdvance(le_int32 index, float yAdjustment)
{
    fAdjustments[index].adjustYAdvance(yAdjustment);
}

inline le_bool GlyphPositionAdjustments::hasCursiveGlyphs() const
{
    return fEntryExitPoints != NULL;
}

U_NAMESPACE_END
#endif
