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

enum SkRectangle_Properties {
    SK_PROPERTY(height),
    SK_PROPERTY(needsRedraw),
    SK_PROPERTY(width)
};

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkDrawRect::fInfo[] = {
    SK_MEMBER_ALIAS(bottom, fRect.fBottom, Float),
    SK_MEMBER_PROPERTY(height, Float),
    SK_MEMBER_ALIAS(left, fRect.fLeft, Float),
    SK_MEMBER_PROPERTY(needsRedraw, Boolean),
    SK_MEMBER_ALIAS(right, fRect.fRight, Float),
    SK_MEMBER_ALIAS(top, fRect.fTop, Float),
    SK_MEMBER_PROPERTY(width, Float)
};

#endif

DEFINE_GET_MEMBER(SkDrawRect);

SkDrawRect::SkDrawRect() : fParent(NULL) {
    fRect.setEmpty();
}

void SkDrawRect::dirty() {
    if (fParent)
        fParent->dirty();
}

bool SkDrawRect::draw(SkAnimateMaker& maker) {
    SkBoundableAuto boundable(this, maker);
    maker.fCanvas->drawRect(fRect, *maker.fPaint);
    return false;
}

#ifdef SK_DUMP_ENABLED
void SkDrawRect::dump(SkAnimateMaker* maker) {
    dumpBase(maker);
    SkDebugf("left=\"%g\" top=\"%g\" right=\"%g\" bottom=\"%g\" />\n",
        SkScalarToFloat(fRect.fLeft), SkScalarToFloat(fRect.fTop), SkScalarToFloat(fRect.fRight),
        SkScalarToFloat(fRect.fBottom));
}
#endif

SkDisplayable* SkDrawRect::getParent() const {
    return fParent;
}

bool SkDrawRect::getProperty(int index, SkScriptValue* value) const {
    SkScalar result;
    switch (index) {
        case SK_PROPERTY(height):
            result = fRect.height();
            break;
        case SK_PROPERTY(needsRedraw):
            value->fType = SkType_Boolean;
            value->fOperand.fS32 = fBounds.isEmpty() == false;
            return true;
        case SK_PROPERTY(width):
            result = fRect.width();
            break;
        default:
            SkASSERT(0);
            return false;
    }
    value->fType = SkType_Float;
    value->fOperand.fScalar = result;
    return true;
}


bool SkDrawRect::setParent(SkDisplayable* parent) {
    fParent = parent;
    return false;
}

bool SkDrawRect::setProperty(int index, SkScriptValue& value) {
    SkScalar scalar = value.fOperand.fScalar;
    switch (index) {
        case SK_PROPERTY(height):
            SkASSERT(value.fType == SkType_Float);
            fRect.fBottom = scalar + fRect.fTop;
            return true;
        case SK_PROPERTY(needsRedraw):
            return false;
        case SK_PROPERTY(width):
            SkASSERT(value.fType == SkType_Float);
            fRect.fRight = scalar + fRect.fLeft;
            return true;
        default:
            SkASSERT(0);
    }
    return false;
}

#if SK_USE_CONDENSED_INFO == 0

const SkMemberInfo SkRoundRect::fInfo[] = {
    SK_MEMBER_INHERITED,
    SK_MEMBER(rx, Float),
    SK_MEMBER(ry, Float),
};

#endif

DEFINE_GET_MEMBER(SkRoundRect);

SkRoundRect::SkRoundRect() : rx(0), ry(0) {
}

bool SkRoundRect::draw(SkAnimateMaker& maker) {
    SkBoundableAuto boundable(this, maker);
    maker.fCanvas->drawRoundRect(fRect, rx, ry, *maker.fPaint);
    return false;
}

#ifdef SK_DUMP_ENABLED
void SkRoundRect::dump(SkAnimateMaker* maker) {
    dumpBase(maker);
    SkDebugf("left=\"%g\" top=\"%g\" right=\"%g\" bottom=\"%g\" rx=\"%g\" ry=\"%g\" />\n",
            SkScalarToFloat(fRect.fLeft), SkScalarToFloat(fRect.fTop), SkScalarToFloat(fRect.fRight),
            SkScalarToFloat(fRect.fBottom), SkScalarToFloat(rx), SkScalarToFloat(ry));
}
#endif
