
/*
 * 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) {
    }

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& ) {}
    virtual Factory getFactory() { return NULL; }

    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) {
}
