
/*
 * 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 "SkDrawMatrix.h"
#include "SkAnimateMaker.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkParse.h"
#include "SkMatrixParts.h"
#include "SkScript.h"
#include "SkTypedArray.h"

enum SkDrawMatrix_Properties {
    SK_PROPERTY(perspectX),
    SK_PROPERTY(perspectY),
    SK_PROPERTY(rotate),
    SK_PROPERTY(scale),
    SK_PROPERTY(scaleX),
    SK_PROPERTY(scaleY),
    SK_PROPERTY(skewX),
    SK_PROPERTY(skewY),
    SK_PROPERTY(translate),
    SK_PROPERTY(translateX),
    SK_PROPERTY(translateY)
};

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkDrawMatrix::fInfo[] = {
    SK_MEMBER_ARRAY(matrix, Float),
    SK_MEMBER_PROPERTY(perspectX, Float),
    SK_MEMBER_PROPERTY(perspectY, Float),
    SK_MEMBER_PROPERTY(rotate, Float),
    SK_MEMBER_PROPERTY(scale, Float),
    SK_MEMBER_PROPERTY(scaleX, Float),
    SK_MEMBER_PROPERTY(scaleY, Float),
    SK_MEMBER_PROPERTY(skewX, Float),
    SK_MEMBER_PROPERTY(skewY, Float),
    SK_MEMBER_PROPERTY(translate, Point),
    SK_MEMBER_PROPERTY(translateX, Float),
    SK_MEMBER_PROPERTY(translateY, Float)
};

#endif

DEFINE_GET_MEMBER(SkDrawMatrix);

SkDrawMatrix::SkDrawMatrix() : fChildHasID(false), fDirty(false) {
    fConcat.reset();
    fMatrix.reset();
}

SkDrawMatrix::~SkDrawMatrix() {
    for (SkMatrixPart** part = fParts.begin(); part < fParts.end();  part++)
        delete *part;
}

bool SkDrawMatrix::addChild(SkAnimateMaker& maker, SkDisplayable* child) {
    SkASSERT(child && child->isMatrixPart());
    SkMatrixPart* part = (SkMatrixPart*) child;
    *fParts.append() = part;
    if (part->add())
        maker.setErrorCode(SkDisplayXMLParserError::kErrorAddingToMatrix);
    return true;
}

bool SkDrawMatrix::childrenNeedDisposing() const {
    return false;
}

SkDisplayable* SkDrawMatrix::deepCopy(SkAnimateMaker* maker) {
    SkDrawMatrix* copy = (SkDrawMatrix*)
        SkDisplayType::CreateInstance(maker, SkType_Matrix);
    SkASSERT(fParts.count() == 0);
    copy->fMatrix = fMatrix;
    copy->fConcat = fConcat;
    return copy;
}

void SkDrawMatrix::dirty() {
    fDirty = true;
}

bool SkDrawMatrix::draw(SkAnimateMaker& maker) {
    SkMatrix& concat = getMatrix();
    maker.fCanvas->concat(concat);
    return false;
}

#ifdef SK_DUMP_ENABLED
void SkDrawMatrix::dump(SkAnimateMaker* maker) {
    dumpBase(maker);
    if (fMatrix.isIdentity()) {
        SkDebugf("matrix=\"identity\"/>\n");
        return;
    }
    SkScalar result;
    result = fMatrix[SkMatrix::kMScaleX];
    if (result != SK_Scalar1)
        SkDebugf("sx=\"%g\" ", SkScalarToFloat(result));
    result = fMatrix.getScaleY();
    if (result != SK_Scalar1)
        SkDebugf("sy=\"%g\" ", SkScalarToFloat(result));
    result = fMatrix.getSkewX();
    if (result)
        SkDebugf("skew-x=\"%g\" ", SkScalarToFloat(result));
    result = fMatrix.getSkewY();
    if (result)
        SkDebugf("skew-y=\"%g\" ", SkScalarToFloat(result));
    result = fMatrix.getTranslateX();
    if (result)
        SkDebugf("tx=\"%g\" ", SkScalarToFloat(result));
    result = fMatrix.getTranslateY();
    if (result)
        SkDebugf("ty=\"%g\" ", SkScalarToFloat(result));
    result = SkPerspToScalar(fMatrix.getPerspX());
    if (result)
        SkDebugf("perspect-x=\"%g\" ", SkScalarToFloat(result));
    result = SkPerspToScalar(fMatrix.getPerspY());
    if (result)
        SkDebugf("perspect-y=\"%g\" ", SkScalarToFloat(result));
    SkDebugf("/>\n");
}
#endif

SkMatrix& SkDrawMatrix::getMatrix() {
    if (fDirty == false)
        return fConcat;
    fMatrix.reset();
    for (SkMatrixPart** part = fParts.begin(); part < fParts.end();  part++) {
        (*part)->add();
        fConcat = fMatrix;
    }
    fDirty = false;
    return fConcat;
}

bool SkDrawMatrix::getProperty(int index, SkScriptValue* value) const {
    value->fType = SkType_Float;
    SkScalar result;
    switch (index) {
        case SK_PROPERTY(perspectX):
            result = fMatrix.getPerspX();
            break;
        case SK_PROPERTY(perspectY):
            result = fMatrix.getPerspY();
            break;
        case SK_PROPERTY(scaleX):
            result = fMatrix.getScaleX();
            break;
        case SK_PROPERTY(scaleY):
            result = fMatrix.getScaleY();
            break;
        case SK_PROPERTY(skewX):
            result = fMatrix.getSkewX();
            break;
        case SK_PROPERTY(skewY):
            result = fMatrix.getSkewY();
            break;
        case SK_PROPERTY(translateX):
            result = fMatrix.getTranslateX();
            break;
        case SK_PROPERTY(translateY):
            result = fMatrix.getTranslateY();
            break;
        default:
//          SkASSERT(0);
            return false;
    }
    value->fOperand.fScalar = result;
    return true;
}

void SkDrawMatrix::initialize() {
    fConcat = fMatrix;
}

void SkDrawMatrix::onEndElement(SkAnimateMaker& ) {
    if (matrix.count() > 0) {
        SkScalar* vals = matrix.begin();
        fMatrix.setScaleX(vals[0]);
        fMatrix.setSkewX(vals[1]);
        fMatrix.setTranslateX(vals[2]);
        fMatrix.setSkewY(vals[3]);
        fMatrix.setScaleY(vals[4]);
        fMatrix.setTranslateY(vals[5]);
        fMatrix.setPerspX(SkScalarToPersp(vals[6]));
        fMatrix.setPerspY(SkScalarToPersp(vals[7]));
//      fMatrix.setPerspW(SkScalarToPersp(vals[8]));
        goto setConcat;
    }
    if (fChildHasID == false) {
        {
            for (SkMatrixPart** part = fParts.begin(); part < fParts.end();  part++)
                delete *part;
        }
        fParts.reset();
setConcat:
        fConcat = fMatrix;
        fDirty = false;
    }
}

void SkDrawMatrix::setChildHasID() {
    fChildHasID = true;
}

bool SkDrawMatrix::setProperty(int index, SkScriptValue& scriptValue) {
    SkScalar number = scriptValue.fOperand.fScalar;
    switch (index) {
        case SK_PROPERTY(translate):
    //      SkScalar xy[2];
            SkASSERT(scriptValue.fType == SkType_Array);
            SkASSERT(scriptValue.fOperand.fArray->getType() == SkType_Float);
            SkASSERT(scriptValue.fOperand.fArray->count() == 2);
    //      SkParse::FindScalars(scriptValue.fOperand.fString->c_str(), xy, 2);
            fMatrix.setTranslateX((*scriptValue.fOperand.fArray)[0].fScalar);
            fMatrix.setTranslateY((*scriptValue.fOperand.fArray)[1].fScalar);
            return true;
        case SK_PROPERTY(perspectX):
            fMatrix.setPerspX(SkScalarToPersp((number)));
            break;
        case SK_PROPERTY(perspectY):
            fMatrix.setPerspY(SkScalarToPersp((number)));
            break;
        case SK_PROPERTY(rotate): {
            SkMatrix temp;
            temp.setRotate(number, 0, 0);
            fMatrix.setScaleX(temp.getScaleX());
            fMatrix.setScaleY(temp.getScaleY());
            fMatrix.setSkewX(temp.getSkewX());
            fMatrix.setSkewY(temp.getSkewY());
            } break;
        case SK_PROPERTY(scale):
            fMatrix.setScaleX(number);
            fMatrix.setScaleY(number);
            break;
        case SK_PROPERTY(scaleX):
            fMatrix.setScaleX(number);
            break;
        case SK_PROPERTY(scaleY):
            fMatrix.setScaleY(number);
            break;
        case SK_PROPERTY(skewX):
            fMatrix.setSkewX(number);
            break;
        case SK_PROPERTY(skewY):
            fMatrix.setSkewY(number);
            break;
        case SK_PROPERTY(translateX):
            fMatrix.setTranslateX(number);
            break;
        case SK_PROPERTY(translateY):
            fMatrix.setTranslateY(number);
            break;
        default:
            SkASSERT(0);
            return false;
    }
    fConcat = fMatrix;
    return true;
}
