
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkView.h"
#include "SkCanvas.h"

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

SkView::SkView(uint32_t flags) : fFlags(SkToU8(flags))
{
    fWidth = fHeight = 0;
    fLoc.set(0, 0);
    fParent = fFirstChild = fNextSibling = fPrevSibling = NULL;
    fMatrix.setIdentity();
    fContainsFocus = 0;
}

SkView::~SkView()
{
    this->detachAllChildren();
}

void SkView::setFlags(uint32_t flags)
{
    SkASSERT((flags & ~kAllFlagMasks) == 0);

    uint32_t diff = fFlags ^ flags;

    if (diff & kVisible_Mask)
        this->inval(NULL);

    fFlags = SkToU8(flags);

    if (diff & kVisible_Mask)
    {
        this->inval(NULL);
    }
}

void SkView::setVisibleP(bool pred)
{
    this->setFlags(SkSetClearShift(fFlags, pred, kVisible_Shift));
}

void SkView::setEnabledP(bool pred)
{
    this->setFlags(SkSetClearShift(fFlags, pred, kEnabled_Shift));
}

void SkView::setFocusableP(bool pred)
{
    this->setFlags(SkSetClearShift(fFlags, pred, kFocusable_Shift));
}

void SkView::setClipToBounds(bool pred) {
    this->setFlags(SkSetClearShift(fFlags, !pred, kNoClip_Shift));
}

void SkView::setSize(SkScalar width, SkScalar height)
{
    width = SkMaxScalar(0, width);
    height = SkMaxScalar(0, height);

    if (fWidth != width || fHeight != height)
    {
        this->inval(NULL);
        fWidth = width;
        fHeight = height;
        this->inval(NULL);
        this->onSizeChange();
        this->invokeLayout();
    }
}

void SkView::setLoc(SkScalar x, SkScalar y)
{
    if (fLoc.fX != x || fLoc.fY != y)
    {
        this->inval(NULL);
        fLoc.set(x, y);
        this->inval(NULL);
    }
}

void SkView::offset(SkScalar dx, SkScalar dy)
{
    if (dx || dy)
        this->setLoc(fLoc.fX + dx, fLoc.fY + dy);
}

void SkView::setLocalMatrix(const SkMatrix& matrix)
{
    this->inval(NULL);
    fMatrix = matrix;
    this->inval(NULL);
}

void SkView::draw(SkCanvas* canvas)
{
    if (fWidth && fHeight && this->isVisible())
    {
        SkRect    r;
        r.set(fLoc.fX, fLoc.fY, fLoc.fX + fWidth, fLoc.fY + fHeight);
        if (this->isClipToBounds() &&
            canvas->quickReject(r)) {
                return;
        }

        SkAutoCanvasRestore    as(canvas, true);

        if (this->isClipToBounds()) {
            canvas->clipRect(r);
        }

        canvas->translate(fLoc.fX, fLoc.fY);
        canvas->concat(fMatrix);

        if (fParent) {
            fParent->beforeChild(this, canvas);
        }

        int sc = canvas->save();
        this->onDraw(canvas);
        canvas->restoreToCount(sc);

        if (fParent) {
            fParent->afterChild(this, canvas);
        }

        B2FIter    iter(this);
        SkView*    child;

        SkCanvas* childCanvas = this->beforeChildren(canvas);

        while ((child = iter.next()) != NULL)
            child->draw(childCanvas);

        this->afterChildren(canvas);
    }
}

void SkView::inval(SkRect* rect) {
    SkView*    view = this;
    SkRect storage;

    for (;;) {
        if (!view->isVisible()) {
            return;
        }
        if (view->isClipToBounds()) {
            SkRect bounds;
            view->getLocalBounds(&bounds);
            if (rect && !bounds.intersect(*rect)) {
                return;
            }
            storage = bounds;
            rect = &storage;
        }
        if (view->handleInval(rect)) {
            return;
        }

        SkView* parent = view->fParent;
        if (parent == NULL) {
            return;
        }

        if (rect) {
            rect->offset(view->fLoc.fX, view->fLoc.fY);
        }
        view = parent;
    }
}

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

bool SkView::setFocusView(SkView* fv)
{
    SkView* view = this;

    do {
        if (view->onSetFocusView(fv))
            return true;
    } while ((view = view->fParent) != NULL);
    return false;
}

SkView* SkView::getFocusView() const
{
    SkView*            focus = NULL;
    const SkView*    view = this;
    do {
        if (view->onGetFocusView(&focus))
            break;
    } while ((view = view->fParent) != NULL);
    return focus;
}

bool SkView::hasFocus() const
{
    return this == this->getFocusView();
}

bool SkView::acceptFocus()
{
    return this->isFocusable() && this->setFocusView(this);
}

/*
    Try to give focus to this view, or its children
*/
SkView* SkView::acceptFocus(FocusDirection dir)
{
    if (dir == kNext_FocusDirection)
    {
        if (this->acceptFocus())
            return this;

        B2FIter    iter(this);
        SkView*    child, *focus;
        while ((child = iter.next()) != NULL)
            if ((focus = child->acceptFocus(dir)) != NULL)
                return focus;
    }
    else // prev
    {
        F2BIter    iter(this);
        SkView*    child, *focus;
        while ((child = iter.next()) != NULL)
            if ((focus = child->acceptFocus(dir)) != NULL)
                return focus;

        if (this->acceptFocus())
            return this;
    }

    return NULL;
}

SkView* SkView::moveFocus(FocusDirection dir)
{
    SkView* focus = this->getFocusView();

    if (focus == NULL)
    {    // start with the root
        focus = this;
        while (focus->fParent)
            focus = focus->fParent;
    }

    SkView*    child, *parent;

    if (dir == kNext_FocusDirection)
    {
        parent = focus;
        child = focus->fFirstChild;
        if (child)
            goto FIRST_CHILD;
        else
            goto NEXT_SIB;

        do {
            while (child != parent->fFirstChild)
            {
    FIRST_CHILD:
                if ((focus = child->acceptFocus(dir)) != NULL)
                    return focus;
                child = child->fNextSibling;
            }
    NEXT_SIB:
            child = parent->fNextSibling;
            parent = parent->fParent;
        } while (parent != NULL);
    }
    else    // prevfocus
    {
        parent = focus->fParent;
        if (parent == NULL)    // we're the root
            return focus->acceptFocus(dir);
        else
        {
            child = focus;
            while (parent)
            {
                while (child != parent->fFirstChild)
                {
                    child = child->fPrevSibling;
                    if ((focus = child->acceptFocus(dir)) != NULL)
                        return focus;
                }
                if (parent->acceptFocus())
                    return parent;

                child = parent;
                parent = parent->fParent;
            }
        }
    }
    return NULL;
}

void SkView::onFocusChange(bool gainFocusP)
{
    this->inval(NULL);
}

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

SkView::Click::Click(SkView* target)
{
    SkASSERT(target);
    fTargetID = target->getSinkID();
    fType = NULL;
    fWeOwnTheType = false;
    fOwner = NULL;
}

SkView::Click::~Click()
{
    this->resetType();
}

void SkView::Click::resetType()
{
    if (fWeOwnTheType)
    {
        sk_free(fType);
        fWeOwnTheType = false;
    }
    fType = NULL;
}

bool SkView::Click::isType(const char type[]) const
{
    const char* t = fType;

    if (type == t)
        return true;

    if (type == NULL)
        type = "";
    if (t == NULL)
        t = "";
    return !strcmp(t, type);
}

void SkView::Click::setType(const char type[])
{
    this->resetType();
    fType = (char*)type;
}

void SkView::Click::copyType(const char type[])
{
    if (fType != type)
    {
        this->resetType();
        if (type)
        {
            size_t    len = strlen(type) + 1;
            fType = (char*)sk_malloc_throw(len);
            memcpy(fType, type, len);
            fWeOwnTheType = true;
        }
    }
}

SkView::Click* SkView::findClickHandler(SkScalar x, SkScalar y, unsigned modi) {
    if (x < 0 || y < 0 || x >= fWidth || y >= fHeight) {
        return NULL;
    }

    if (this->onSendClickToChildren(x, y, modi)) {
        F2BIter    iter(this);
        SkView*    child;

        while ((child = iter.next()) != NULL)
        {
            SkPoint p;
            if (!child->globalToLocal(x, y, &p)) {
                continue;
            }

            Click* click = child->findClickHandler(p.fX, p.fY, modi);

            if (click) {
                return click;
            }
        }
    }

    return this->onFindClickHandler(x, y, modi);
}

void SkView::DoClickDown(Click* click, int x, int y, unsigned modi)
{
    SkASSERT(click);

    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
    if (NULL == target) {
        return;
    }

    click->fIOrig.set(x, y);
    click->fICurr = click->fIPrev = click->fIOrig;

    click->fOrig.iset(x, y);
    if (!target->globalToLocal(&click->fOrig)) {
        // no history to let us recover from this failure
        return;
    }
    click->fPrev = click->fCurr = click->fOrig;

    click->fState = Click::kDown_State;
    click->fModifierKeys = modi;
    target->onClick(click);
}

void SkView::DoClickMoved(Click* click, int x, int y, unsigned modi)
{
    SkASSERT(click);

    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
    if (NULL == target) {
        return;
    }

    click->fIPrev = click->fICurr;
    click->fICurr.set(x, y);

    click->fPrev = click->fCurr;
    click->fCurr.iset(x, y);
    if (!target->globalToLocal(&click->fCurr)) {
        // on failure pretend the mouse didn't move
        click->fCurr = click->fPrev;
    }

    click->fState = Click::kMoved_State;
    click->fModifierKeys = modi;
    target->onClick(click);
}

void SkView::DoClickUp(Click* click, int x, int y, unsigned modi)
{
    SkASSERT(click);

    SkView* target = (SkView*)SkEventSink::FindSink(click->fTargetID);
    if (NULL == target) {
        return;
    }

    click->fIPrev = click->fICurr;
    click->fICurr.set(x, y);

    click->fPrev = click->fCurr;
    click->fCurr.iset(x, y);
    if (!target->globalToLocal(&click->fCurr)) {
        // on failure pretend the mouse didn't move
        click->fCurr = click->fPrev;
    }

    click->fState = Click::kUp_State;
    click->fModifierKeys = modi;
    target->onClick(click);
}

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

void SkView::invokeLayout() {
    SkView::Layout* layout = this->getLayout();

    if (layout) {
        layout->layoutChildren(this);
    }
}

void SkView::onDraw(SkCanvas* canvas) {
    Artist* artist = this->getArtist();

    if (artist) {
        artist->draw(this, canvas);
    }
}

void SkView::onSizeChange() {}

bool SkView::onSendClickToChildren(SkScalar x, SkScalar y, unsigned modi) {
    return true;
}

SkView::Click* SkView::onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
    return NULL;
}

bool SkView::onClick(Click*) {
    return false;
}

bool SkView::handleInval(const SkRect*) {
    return false;
}

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

void SkView::getLocalBounds(SkRect* bounds) const {
    if (bounds) {
        bounds->set(0, 0, fWidth, fHeight);
    }
}

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

void SkView::detachFromParent_NoLayout() {
    this->validate();
    if (fParent == NULL) {
        return;
    }

    if (fContainsFocus) {
        (void)this->setFocusView(NULL);
    }

    this->inval(NULL);

    SkView* next = NULL;

    if (fNextSibling != this) {   // do we have any siblings
        fNextSibling->fPrevSibling = fPrevSibling;
        fPrevSibling->fNextSibling = fNextSibling;
        next = fNextSibling;
    }

    if (fParent->fFirstChild == this) {
        fParent->fFirstChild = next;
    }

    fParent = fNextSibling = fPrevSibling = NULL;

    this->validate();
    this->unref();
}

void SkView::detachFromParent() {
    this->validate();
    SkView* parent = fParent;

    if (parent) {
        this->detachFromParent_NoLayout();
        parent->invokeLayout();
    }
}

SkView* SkView::attachChildToBack(SkView* child) {
    this->validate();
    SkASSERT(child != this);

    if (child == NULL || fFirstChild == child)
        goto DONE;

    child->ref();
    child->detachFromParent_NoLayout();

    if (fFirstChild == NULL) {
        child->fNextSibling = child;
        child->fPrevSibling = child;
    } else {
        child->fNextSibling = fFirstChild;
        child->fPrevSibling = fFirstChild->fPrevSibling;
        fFirstChild->fPrevSibling->fNextSibling = child;
        fFirstChild->fPrevSibling = child;
    }

    fFirstChild = child;
    child->fParent = this;
    child->inval(NULL);

    this->validate();
    this->invokeLayout();
DONE:
    return child;
}

SkView* SkView::attachChildToFront(SkView* child) {
    this->validate();
    SkASSERT(child != this);

    if (child == NULL || (fFirstChild && fFirstChild->fPrevSibling == child))
        goto DONE;

    child->ref();
    child->detachFromParent_NoLayout();

    if (fFirstChild == NULL) {
        fFirstChild = child;
        child->fNextSibling = child;
        child->fPrevSibling = child;
    } else {
        child->fNextSibling = fFirstChild;
        child->fPrevSibling = fFirstChild->fPrevSibling;
        fFirstChild->fPrevSibling->fNextSibling = child;
        fFirstChild->fPrevSibling = child;
    }

    child->fParent = this;
    child->inval(NULL);

    this->validate();
    this->invokeLayout();
DONE:
    return child;
}

void SkView::detachAllChildren() {
    this->validate();
    while (fFirstChild)
        fFirstChild->detachFromParent_NoLayout();
}

void SkView::localToGlobal(SkMatrix* matrix) const {
    if (matrix) {
        matrix->reset();
        const SkView* view = this;
        while (view)
        {
            matrix->preConcat(view->getLocalMatrix());
            matrix->preTranslate(-view->fLoc.fX, -view->fLoc.fY);
            view = view->fParent;
        }
    }
}
bool SkView::globalToLocal(SkScalar x, SkScalar y, SkPoint* local) const
{
    SkASSERT(this);

    if (local) {
        SkMatrix m;
        this->localToGlobal(&m);
        if (!m.invert(&m)) {
            return false;
        }
        SkPoint p;
        m.mapXY(x, y, &p);
        local->set(p.fX, p.fY);
    }

    return true;
}

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

/*    Even if the subclass overrides onInflate, they should always be
    sure to call the inherited method, so that we get called.
*/
void SkView::onInflate(const SkDOM& dom, const SkDOM::Node* node) {
    SkScalar x, y;

    x = this->locX();
    y = this->locY();
    (void)dom.findScalar(node, "x", &x);
    (void)dom.findScalar(node, "y", &y);
    this->setLoc(x, y);

    x = this->width();
    y = this->height();
    (void)dom.findScalar(node, "width", &x);
    (void)dom.findScalar(node, "height", &y);
    this->setSize(x, y);

    // inflate the flags

    static const char* gFlagNames[] = {
        "visible", "enabled", "focusable", "flexH", "flexV"
    };
    SkASSERT(SK_ARRAY_COUNT(gFlagNames) == kFlagShiftCount);

    bool     b;
    uint32_t flags = this->getFlags();
    for (unsigned i = 0; i < SK_ARRAY_COUNT(gFlagNames); i++)
        if (dom.findBool(node, gFlagNames[i], &b))
            flags = SkSetClearShift(flags, b, i);
    this->setFlags(flags);
}

void SkView::inflate(const SkDOM& dom, const SkDOM::Node* node) {
    this->onInflate(dom, node);
}

void SkView::onPostInflate(const SkTDict<SkView*>&) {
    // override in subclass as needed
}

void SkView::postInflate(const SkTDict<SkView*>& dict) {
    this->onPostInflate(dict);

    B2FIter    iter(this);
    SkView*    child;
    while ((child = iter.next()) != NULL)
        child->postInflate(dict);
}

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

SkView* SkView::sendEventToParents(const SkEvent& evt) {
    SkView* parent = fParent;

    while (parent) {
        if (parent->doEvent(evt)) {
            return parent;
        }
        parent = parent->fParent;
    }
    return NULL;
}

SkView* SkView::sendQueryToParents(SkEvent* evt) {
    SkView* parent = fParent;

    while (parent) {
        if (parent->doQuery(evt)) {
            return parent;
        }
        parent = parent->fParent;
    }
    return NULL;
}

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

SkView::F2BIter::F2BIter(const SkView* parent) {
    fFirstChild = parent ? parent->fFirstChild : NULL;
    fChild = fFirstChild ? fFirstChild->fPrevSibling : NULL;
}

SkView* SkView::F2BIter::next() {
    SkView* curr = fChild;

    if (fChild) {
        if (fChild == fFirstChild) {
            fChild = NULL;
        } else {
            fChild = fChild->fPrevSibling;
        }
    }
    return curr;
}

SkView::B2FIter::B2FIter(const SkView* parent) {
    fFirstChild = parent ? parent->fFirstChild : NULL;
    fChild = fFirstChild;
}

SkView* SkView::B2FIter::next() {
    SkView* curr = fChild;

    if (fChild) {
        SkView* next = fChild->fNextSibling;
        if (next == fFirstChild)
            next = NULL;
        fChild = next;
    }
    return curr;
}

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

#ifdef SK_DEBUG

void SkView::validate() const {
//    SkASSERT(this->getRefCnt() > 0 && this->getRefCnt() < 100);
    if (fParent) {
        SkASSERT(fNextSibling);
        SkASSERT(fPrevSibling);
    } else {
        bool nextNull = NULL == fNextSibling;
        bool prevNull = NULL == fNextSibling;
        SkASSERT(nextNull == prevNull);
    }
}

static inline void show_if_nonzero(const char name[], SkScalar value)
{
    if (value)
        SkDebugf("%s=\"%g\"", name, value/65536.);
}

static void tab(int level)
{
    for (int i = 0; i < level; i++)
        SkDebugf("    ");
}

static void dumpview(const SkView* view, int level, bool recurse)
{
    tab(level);

    SkDebugf("<view");
    show_if_nonzero(" x", view->locX());
    show_if_nonzero(" y", view->locY());
    show_if_nonzero(" width", view->width());
    show_if_nonzero(" height", view->height());

    if (recurse)
    {
        SkView::B2FIter    iter(view);
        SkView*            child;
        bool            noChildren = true;

        while ((child = iter.next()) != NULL)
        {
            if (noChildren)
                SkDebugf(">\n");
            noChildren = false;
            dumpview(child, level + 1, true);
        }

        if (!noChildren)
        {
            tab(level);
            SkDebugf("</view>\n");
        }
        else
            goto ONELINER;
    }
    else
    {
    ONELINER:
        SkDebugf(" />\n");
    }
}

void SkView::dump(bool recurse) const
{
    dumpview(this, 0, recurse);
}

#endif
