
/*
 * 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, SkCanvas::kBW_EdgeType)) {
                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)
{
	if (x < 0 || y < 0 || x >= fWidth || y >= fHeight) {
		return NULL;
    }

    if (this->onSendClickToChildren(x, y)) {
        F2BIter	iter(this);
        SkView*	child;
        
        while ((child = iter.next()) != NULL)
        {
            SkPoint p;
            child->globalToLocal(x, y, &p);
            
            Click* click = child->findClickHandler(p.fX, p.fY);
            
            if (click) {
                return click;
            }
        }
    }
	return this->onFindClickHandler(x, y);
}

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

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

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

	click->fOrig.iset(x, y);
	target->globalToLocal(&click->fOrig);
	click->fPrev = click->fCurr = click->fOrig;

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

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

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

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

	click->fPrev = click->fCurr;
	click->fCurr.iset(x, y);
	target->globalToLocal(&click->fCurr);

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

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

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

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

	click->fPrev = click->fCurr;
	click->fCurr.iset(x, y);
	target->globalToLocal(&click->fCurr);

	click->fState = Click::kUp_State;
	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) {
    return true;
}

SkView::Click* SkView::onFindClickHandler(SkScalar x, SkScalar y) {
	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()
{
	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->unref();
}

void SkView::detachFromParent()
{
	SkView* parent = fParent;

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

SkView* SkView::attachChildToBack(SkView* child)
{
	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->invokeLayout();
DONE:
	return child;
}

SkView* SkView::attachChildToFront(SkView* child)
{
	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->invokeLayout();
DONE:
	return child;
}

void SkView::detachAllChildren()
{
	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;
        }
    }
}
void SkView::globalToLocal(SkScalar x, SkScalar y, SkPoint* local) const
{
	SkASSERT(this);
	if (local)
	{
        SkMatrix m;
        this->localToGlobal(&m);
        SkPoint p;
        m.invert(&m);
        m.mapXY(x, y, &p);
		local->set(p.fX, p.fY);
	}
}

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

/*	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

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
