
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "SkDrawExtraPathEffect.h"
#include "SkDrawPath.h"
#include "Sk1DPathEffect.h"
#include "Sk2DPathEffect.h"
#include "SkMemberInfo.h"
#include "SkPaintParts.h"
#include "SkPathEffect.h"
#include "SkCornerPathEffect.h"

#include "SkDashPathEffect.h"

class SkDrawShapePathEffect : public SkDrawPathEffect {
    DECLARE_PRIVATE_MEMBER_INFO(DrawShapePathEffect);
    SkDrawShapePathEffect();
    virtual ~SkDrawShapePathEffect();
    virtual bool add(SkAnimateMaker& , SkDisplayable* );
    virtual SkPathEffect* getPathEffect();
protected:
    SkDrawable* addPath;
    SkDrawable* addMatrix;
    SkDrawPath* path;
    SkPathEffect* fPathEffect;
    friend class SkShape1DPathEffect;
    friend class SkShape2DPathEffect;
};

class SkDrawShape1DPathEffect : public SkDrawShapePathEffect {
    DECLARE_EXTRAS_MEMBER_INFO(SkDrawShape1DPathEffect);
    SkDrawShape1DPathEffect(SkDisplayTypes );
    virtual ~SkDrawShape1DPathEffect();
    virtual void onEndElement(SkAnimateMaker& );
private:
    SkString phase;
    SkString spacing;
    friend class SkShape1DPathEffect;
    typedef SkDrawShapePathEffect INHERITED;
};

class SkDrawShape2DPathEffect : public SkDrawShapePathEffect {
    DECLARE_EXTRAS_MEMBER_INFO(SkDrawShape2DPathEffect);
    SkDrawShape2DPathEffect(SkDisplayTypes );
    virtual ~SkDrawShape2DPathEffect();
    virtual void onEndElement(SkAnimateMaker& );
private:
    SkDrawMatrix* matrix;
    friend class SkShape2DPathEffect;
    typedef SkDrawShapePathEffect INHERITED;
};

class SkDrawComposePathEffect : public SkDrawPathEffect {
    DECLARE_EXTRAS_MEMBER_INFO(SkDrawComposePathEffect);
    SkDrawComposePathEffect(SkDisplayTypes );
    virtual ~SkDrawComposePathEffect();
    virtual bool add(SkAnimateMaker& , SkDisplayable* );
    virtual SkPathEffect* getPathEffect();
    virtual bool isPaint() const;
private:
    SkDrawPathEffect* effect1;
    SkDrawPathEffect* effect2;
};

class SkDrawCornerPathEffect : public SkDrawPathEffect {
    DECLARE_EXTRAS_MEMBER_INFO(SkDrawCornerPathEffect);
    SkDrawCornerPathEffect(SkDisplayTypes );
    virtual ~SkDrawCornerPathEffect();
    virtual SkPathEffect* getPathEffect();
private:
    SkScalar radius;
};

//////////// SkShape1DPathEffect

#include "SkAnimateMaker.h"
#include "SkAnimatorScript.h"
#include "SkDisplayApply.h"
#include "SkDrawMatrix.h"
#include "SkPaint.h"

class SkShape1DPathEffect : public Sk1DPathEffect {
public:
    SkShape1DPathEffect(SkDrawShape1DPathEffect* draw, SkAnimateMaker* maker) :
        fDraw(draw), fMaker(maker) {
    }

    SK_DECLARE_UNFLATTENABLE_OBJECT()

protected:
    virtual SkScalar begin(SkScalar contourLength)
    {
        SkScriptValue value;
        SkAnimatorScript engine(*fMaker, NULL, SkType_Float);
        engine.propertyCallBack(GetContourLength, &contourLength);
        value.fOperand.fScalar = 0;
        engine.evaluate(fDraw->phase.c_str(), &value, SkType_Float);
        return value.fOperand.fScalar;
    }

    virtual SkScalar next(SkPath* dst, SkScalar distance, SkPathMeasure& )
    {
        fMaker->setExtraPropertyCallBack(fDraw->fType, GetDistance, &distance);
        SkDrawPath* drawPath = NULL;
        if (fDraw->addPath->isPath()) {
            drawPath = (SkDrawPath*) fDraw->addPath;
        } else {
            SkApply* apply = (SkApply*) fDraw->addPath;
            apply->refresh(*fMaker);
            apply->activate(*fMaker);
            apply->interpolate(*fMaker, SkScalarMulRound(distance, 1000));
            drawPath = (SkDrawPath*) apply->getScope();
        }
        SkMatrix m;
        m.reset();
        if (fDraw->addMatrix) {
            SkDrawMatrix* matrix;
            if (fDraw->addMatrix->getType() == SkType_Matrix)
                matrix = (SkDrawMatrix*) fDraw->addMatrix;
            else {
                SkApply* apply = (SkApply*) fDraw->addMatrix;
                apply->refresh(*fMaker);
                apply->activate(*fMaker);
                apply->interpolate(*fMaker, SkScalarMulRound(distance, 1000));
                matrix = (SkDrawMatrix*) apply->getScope();
            }
        }
        SkScalar result = 0;
        SkAnimatorScript::EvaluateFloat(*fMaker, NULL, fDraw->spacing.c_str(), &result);
        if (drawPath)
            dst->addPath(drawPath->getPath(), m);
        fMaker->clearExtraPropertyCallBack(fDraw->fType);
        return result;
    }

private:
    virtual void flatten(SkFlattenableWriteBuffer& ) {}

    static bool GetContourLength(const char* token, size_t len, void* clen, SkScriptValue* value) {
        if (SK_LITERAL_STR_EQUAL("contourLength", token, len)) {
            value->fOperand.fScalar = *(SkScalar*) clen;
            value->fType = SkType_Float;
            return true;
        }
        return false;
    }

    static bool GetDistance(const char* token, size_t len, void* dist, SkScriptValue* value) {
        if (SK_LITERAL_STR_EQUAL("distance", token, len)) {
            value->fOperand.fScalar = *(SkScalar*) dist;
            value->fType = SkType_Float;
            return true;
        }
        return false;
    }

    SkDrawShape1DPathEffect* fDraw;
    SkAnimateMaker* fMaker;
};

//////////// SkDrawShapePathEffect

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkDrawShapePathEffect::fInfo[] = {
    SK_MEMBER(addMatrix, Drawable), // either matrix or apply
    SK_MEMBER(addPath, Drawable),   // either path or apply
    SK_MEMBER(path, Path),
};

#endif

DEFINE_GET_MEMBER(SkDrawShapePathEffect);

SkDrawShapePathEffect::SkDrawShapePathEffect() :
    addPath(NULL), addMatrix(NULL), path(NULL), fPathEffect(NULL) {
}

SkDrawShapePathEffect::~SkDrawShapePathEffect() {
    SkSafeUnref(fPathEffect);
}

bool SkDrawShapePathEffect::add(SkAnimateMaker& , SkDisplayable* child) {
    path = (SkDrawPath*) child;
    return true;
}

SkPathEffect* SkDrawShapePathEffect::getPathEffect() {
    fPathEffect->ref();
    return fPathEffect;
}

//////////// SkDrawShape1DPathEffect

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkDrawShape1DPathEffect::fInfo[] = {
    SK_MEMBER_INHERITED,
    SK_MEMBER(phase, String),
    SK_MEMBER(spacing, String),
};

#endif

DEFINE_GET_MEMBER(SkDrawShape1DPathEffect);

SkDrawShape1DPathEffect::SkDrawShape1DPathEffect(SkDisplayTypes type) : fType(type) {
}

SkDrawShape1DPathEffect::~SkDrawShape1DPathEffect() {
}

void SkDrawShape1DPathEffect::onEndElement(SkAnimateMaker& maker) {
    if (addPath == NULL || (addPath->isPath() == false && addPath->isApply() == false))
        maker.setErrorCode(SkDisplayXMLParserError::kUnknownError); // !!! add error
    else
        fPathEffect = new SkShape1DPathEffect(this, &maker);
}

////////// SkShape2DPathEffect

class SkShape2DPathEffect : public Sk2DPathEffect {
public:
    SkShape2DPathEffect(SkDrawShape2DPathEffect* draw, SkAnimateMaker* maker,
        const SkMatrix& matrix) : Sk2DPathEffect(matrix), fDraw(draw), fMaker(maker) {
    }

protected:
    virtual void begin(const SkIRect& uvBounds, SkPath* )
    {
        fUVBounds.set(SkIntToScalar(uvBounds.fLeft), SkIntToScalar(uvBounds.fTop),
            SkIntToScalar(uvBounds.fRight), SkIntToScalar(uvBounds.fBottom));
    }

    virtual void next(const SkPoint& loc, int u, int v, SkPath* dst)
    {
        fLoc = loc;
        fU = u;
        fV = v;
        SkDrawPath* drawPath;
        fMaker->setExtraPropertyCallBack(fDraw->fType, Get2D, this);
        if (fDraw->addPath->isPath()) {
            drawPath = (SkDrawPath*) fDraw->addPath;
        } else {
            SkApply* apply = (SkApply*) fDraw->addPath;
            apply->refresh(*fMaker);
            apply->activate(*fMaker);
            apply->interpolate(*fMaker, v);
            drawPath = (SkDrawPath*) apply->getScope();
        }
        if (drawPath == NULL)
            goto clearCallBack;
        if (fDraw->matrix) {
            SkDrawMatrix* matrix;
            if (fDraw->matrix->getType() == SkType_Matrix)
                matrix = (SkDrawMatrix*) fDraw->matrix;
            else {
                SkApply* apply = (SkApply*) fDraw->matrix;
                apply->activate(*fMaker);
                apply->interpolate(*fMaker, v);
                matrix = (SkDrawMatrix*) apply->getScope();
            }
            if (matrix) {
                dst->addPath(drawPath->getPath(), matrix->getMatrix());
                goto clearCallBack;
            }
        }
        dst->addPath(drawPath->getPath());
clearCallBack:
        fMaker->clearExtraPropertyCallBack(fDraw->fType);
    }

private:

    static bool Get2D(const char* token, size_t len, void* s2D, SkScriptValue* value) {
        static const char match[] = "locX|locY|left|top|right|bottom|u|v" ;
        SkShape2DPathEffect* shape2D = (SkShape2DPathEffect*) s2D;
        int index;
        if (SkAnimatorScript::MapEnums(match, token, len, &index) == false)
            return false;
        SkASSERT((sizeof(SkPoint) +     sizeof(SkRect)) / sizeof(SkScalar) == 6);
        if (index < 6) {
            value->fType = SkType_Float;
            value->fOperand.fScalar = (&shape2D->fLoc.fX)[index];
        } else {
            value->fType = SkType_Int;
            value->fOperand.fS32 = (&shape2D->fU)[index - 6];
        }
        return true;
    }

    SkPoint fLoc;
    SkRect fUVBounds;
    int32_t fU;
    int32_t fV;
    SkDrawShape2DPathEffect* fDraw;
    SkAnimateMaker* fMaker;

    // illegal
    SkShape2DPathEffect(const SkShape2DPathEffect&);
    SkShape2DPathEffect& operator=(const SkShape2DPathEffect&);
};

////////// SkDrawShape2DPathEffect

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkDrawShape2DPathEffect::fInfo[] = {
    SK_MEMBER_INHERITED,
    SK_MEMBER(matrix, Matrix)
};

#endif

DEFINE_GET_MEMBER(SkDrawShape2DPathEffect);

SkDrawShape2DPathEffect::SkDrawShape2DPathEffect(SkDisplayTypes type) : fType(type) {
}

SkDrawShape2DPathEffect::~SkDrawShape2DPathEffect() {
}

void SkDrawShape2DPathEffect::onEndElement(SkAnimateMaker& maker) {
    if (addPath == NULL || (addPath->isPath() == false && addPath->isApply() == false) ||
            matrix == NULL)
        maker.setErrorCode(SkDisplayXMLParserError::kUnknownError); // !!! add error
    else
        fPathEffect = new SkShape2DPathEffect(this, &maker, matrix->getMatrix());
}

////////// SkDrawComposePathEffect

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkDrawComposePathEffect::fInfo[] = {
    SK_MEMBER(effect1, PathEffect),
    SK_MEMBER(effect2, PathEffect)
};

#endif

DEFINE_GET_MEMBER(SkDrawComposePathEffect);

SkDrawComposePathEffect::SkDrawComposePathEffect(SkDisplayTypes type) : fType(type),
    effect1(NULL), effect2(NULL) {
}

SkDrawComposePathEffect::~SkDrawComposePathEffect() {
    delete effect1;
    delete effect2;
}

bool SkDrawComposePathEffect::add(SkAnimateMaker& , SkDisplayable* child) {
    if (effect1 == NULL)
        effect1 = (SkDrawPathEffect*) child;
    else
        effect2 = (SkDrawPathEffect*) child;
    return true;
}

SkPathEffect* SkDrawComposePathEffect::getPathEffect() {
    SkPathEffect* e1 = effect1->getPathEffect();
    SkPathEffect* e2 = effect2->getPathEffect();
    SkPathEffect* composite = new SkComposePathEffect(e1, e2);
    e1->unref();
    e2->unref();
    return composite;
}

bool SkDrawComposePathEffect::isPaint() const {
    return true;
}

//////////// SkDrawCornerPathEffect

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkDrawCornerPathEffect::fInfo[] = {
    SK_MEMBER(radius, Float)
};

#endif

DEFINE_GET_MEMBER(SkDrawCornerPathEffect);

SkDrawCornerPathEffect::SkDrawCornerPathEffect(SkDisplayTypes type):
    fType(type), radius(0) {
}

SkDrawCornerPathEffect::~SkDrawCornerPathEffect() {
}

SkPathEffect* SkDrawCornerPathEffect::getPathEffect() {
    return new SkCornerPathEffect(radius);
}

/////////

#include "SkExtras.h"

const char kDrawShape1DPathEffectName[] = "pathEffect:shape1D";
const char kDrawShape2DPathEffectName[] = "pathEffect:shape2D";
const char kDrawComposePathEffectName[] = "pathEffect:compose";
const char kDrawCornerPathEffectName[]  = "pathEffect:corner";

class SkExtraPathEffects : public SkExtras {
public:
    SkExtraPathEffects(SkAnimator* animator) :
            skDrawShape1DPathEffectType(SkType_Unknown),
            skDrawShape2DPathEffectType(SkType_Unknown),
            skDrawComposePathEffectType(SkType_Unknown),
            skDrawCornerPathEffectType(SkType_Unknown) {
    }

    virtual SkDisplayable* createInstance(SkDisplayTypes type) {
        SkDisplayable* result = NULL;
        if (skDrawShape1DPathEffectType == type)
            result = new SkDrawShape1DPathEffect(type);
        else if (skDrawShape2DPathEffectType == type)
            result = new SkDrawShape2DPathEffect(type);
        else if (skDrawComposePathEffectType == type)
            result = new SkDrawComposePathEffect(type);
        else if (skDrawCornerPathEffectType == type)
            result = new SkDrawCornerPathEffect(type);
        return result;
    }

    virtual bool definesType(SkDisplayTypes type) {
        return type == skDrawShape1DPathEffectType ||
            type == skDrawShape2DPathEffectType ||
            type == skDrawComposePathEffectType ||
            type == skDrawCornerPathEffectType;
    }

#if SK_USE_CONDENSED_INFO == 0
    virtual const SkMemberInfo* getMembers(SkDisplayTypes type, int* infoCountPtr) {
        const SkMemberInfo* info = NULL;
        int infoCount = 0;
        if (skDrawShape1DPathEffectType == type) {
            info = SkDrawShape1DPathEffect::fInfo;
            infoCount = SkDrawShape1DPathEffect::fInfoCount;
        } else if (skDrawShape2DPathEffectType == type) {
            info = SkDrawShape2DPathEffect::fInfo;
            infoCount = SkDrawShape2DPathEffect::fInfoCount;
        } else if (skDrawComposePathEffectType == type) {
            info = SkDrawComposePathEffect::fInfo;
            infoCount = SkDrawShape1DPathEffect::fInfoCount;
        } else if (skDrawCornerPathEffectType == type) {
            info = SkDrawCornerPathEffect::fInfo;
            infoCount = SkDrawCornerPathEffect::fInfoCount;
        }
        if (infoCountPtr)
            *infoCountPtr = infoCount;
        return info;
    }
#endif

#ifdef SK_DEBUG
    virtual const char* getName(SkDisplayTypes type) {
        if (skDrawShape1DPathEffectType == type)
            return kDrawShape1DPathEffectName;
        else if (skDrawShape2DPathEffectType == type)
            return kDrawShape2DPathEffectName;
        else if (skDrawComposePathEffectType == type)
            return kDrawComposePathEffectName;
        else if (skDrawCornerPathEffectType == type)
            return kDrawCornerPathEffectName;
        return NULL;
    }
#endif

    virtual SkDisplayTypes getType(const char name[], size_t len ) {
        SkDisplayTypes* type = NULL;
        if (SK_LITERAL_STR_EQUAL(kDrawShape1DPathEffectName, name, len))
            type = &skDrawShape1DPathEffectType;
        else if (SK_LITERAL_STR_EQUAL(kDrawShape2DPathEffectName, name, len))
            type = &skDrawShape2DPathEffectType;
        else if (SK_LITERAL_STR_EQUAL(kDrawComposePathEffectName, name, len))
            type = &skDrawComposePathEffectType;
        else if (SK_LITERAL_STR_EQUAL(kDrawCornerPathEffectName, name, len))
            type = &skDrawCornerPathEffectType;
        if (type) {
            if (*type == SkType_Unknown)
                *type = SkDisplayType::RegisterNewType();
            return *type;
        }
        return SkType_Unknown;
    }

private:
    SkDisplayTypes skDrawShape1DPathEffectType;
    SkDisplayTypes skDrawShape2DPathEffectType;
    SkDisplayTypes skDrawComposePathEffectType;
    SkDisplayTypes skDrawCornerPathEffectType;
};


void InitializeSkExtraPathEffects(SkAnimator* animator) {
    animator->addExtras(new SkExtraPathEffects(animator));
}

////////////////


SkExtras::SkExtras() : fExtraCallBack(NULL), fExtraStorage(NULL) {
}
