
/*
 * 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 "SkStackViewLayout.h"

SkStackViewLayout::SkStackViewLayout()
{
	fMargin.set(0, 0, 0, 0);
	fSpacer	= 0;
	fOrient	= kHorizontal_Orient;
	fPack	= kStart_Pack;
	fAlign	= kStart_Align;
	fRound	= false;
}

void SkStackViewLayout::setOrient(Orient ori)
{
	SkASSERT((unsigned)ori < kOrientCount);
	fOrient = SkToU8(ori);
}

void SkStackViewLayout::getMargin(SkRect* margin) const
{
	if (margin)
		*margin = fMargin;
}

void SkStackViewLayout::setMargin(const SkRect& margin)
{
	fMargin = margin;
}

void SkStackViewLayout::setSpacer(SkScalar spacer)
{
	fSpacer = spacer;
}

void SkStackViewLayout::setPack(Pack pack)
{
	SkASSERT((unsigned)pack < kPackCount);
	fPack = SkToU8(pack);
}

void SkStackViewLayout::setAlign(Align align)
{
	SkASSERT((unsigned)align < kAlignCount);
	fAlign = SkToU8(align);
}

void SkStackViewLayout::setRound(bool r)
{
	fRound = SkToU8(r);
}

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

typedef SkScalar (*AlignProc)(SkScalar childLimit, SkScalar parentLimit);
typedef SkScalar (SkView::*GetSizeProc)() const;
typedef void (SkView::*SetLocProc)(SkScalar coord);
typedef void (SkView::*SetSizeProc)(SkScalar coord);

static SkScalar left_align_proc(SkScalar childLimit, SkScalar parentLimit) { return 0; }
static SkScalar center_align_proc(SkScalar childLimit, SkScalar parentLimit) { return SkScalarHalf(parentLimit - childLimit); }
static SkScalar right_align_proc(SkScalar childLimit, SkScalar parentLimit) { return parentLimit - childLimit; }
static SkScalar fill_align_proc(SkScalar childLimit, SkScalar parentLimit) { return 0; }

/*	Measure the main-dimension for all the children. If a child is marked flex in that direction
	ignore its current value but increment the counter for flexChildren
*/
static SkScalar compute_children_limit(SkView* parent, GetSizeProc sizeProc, int* count,
									   uint32_t flexMask, int* flexCount)
{
	SkView::B2FIter	iter(parent);
	SkView*			child;
	SkScalar		limit = 0;
	int				n = 0, flex = 0;

	while ((child = iter.next()) != NULL)
	{
		n += 1;
		if (child->getFlags() & flexMask)
			flex += 1;
		else
			limit += (child->*sizeProc)();
	}
	if (count)
		*count = n;
	if (flexCount)
		*flexCount = flex;
	return limit;
}

void SkStackViewLayout::onLayoutChildren(SkView* parent)
{
	static AlignProc gAlignProcs[] = {
		left_align_proc,
		center_align_proc,
		right_align_proc,
		fill_align_proc
	};

	SkScalar			startM, endM, crossStartM, crossLimit;
	GetSizeProc			mainGetSizeP, crossGetSizeP;
	SetLocProc			mainLocP, crossLocP;
	SetSizeProc			mainSetSizeP, crossSetSizeP;
	SkView::Flag_Mask	flexMask;

	if (fOrient == kHorizontal_Orient)
	{
		startM		= fMargin.fLeft;
		endM		= fMargin.fRight;
		crossStartM	= fMargin.fTop;
		crossLimit	= -fMargin.fTop - fMargin.fBottom;

		mainGetSizeP	= &SkView::width;
		crossGetSizeP	= &SkView::height;
		mainLocP	= &SkView::setLocX;
		crossLocP	= &SkView::setLocY;

		mainSetSizeP  = &SkView::setWidth;
		crossSetSizeP = &SkView::setHeight;

		flexMask	= SkView::kFlexH_Mask;
	}
	else
	{
		startM		= fMargin.fTop;
		endM		= fMargin.fBottom;
		crossStartM	= fMargin.fLeft;
		crossLimit	= -fMargin.fLeft - fMargin.fRight;

		mainGetSizeP	= &SkView::height;
		crossGetSizeP	= &SkView::width;
		mainLocP	= &SkView::setLocY;
		crossLocP	= &SkView::setLocX;

		mainSetSizeP  = &SkView::setHeight;
		crossSetSizeP = &SkView::setWidth;

		flexMask	= SkView::kFlexV_Mask;
	}
	crossLimit += (parent->*crossGetSizeP)();
	if (fAlign != kStretch_Align)
		crossSetSizeP = NULL;

	int			childCount, flexCount;
	SkScalar	childLimit = compute_children_limit(parent, mainGetSizeP, &childCount, flexMask, &flexCount);

	if (childCount == 0)
		return;

	childLimit += (childCount - 1) * fSpacer;

	SkScalar		parentLimit = (parent->*mainGetSizeP)() - startM - endM;
	SkScalar		pos = startM + gAlignProcs[fPack](childLimit, parentLimit);
	SkScalar		flexAmount = 0;
	SkView::B2FIter	iter(parent);
	SkView*			child;

	if (flexCount > 0 && parentLimit > childLimit)
		flexAmount = (parentLimit - childLimit) / flexCount;

	while ((child = iter.next()) != NULL)
	{
		if (fRound)
			pos = SkIntToScalar(SkScalarRound(pos));
		(child->*mainLocP)(pos);
		SkScalar crossLoc = crossStartM + gAlignProcs[fAlign]((child->*crossGetSizeP)(), crossLimit);
		if (fRound)
			crossLoc = SkIntToScalar(SkScalarRound(crossLoc));
		(child->*crossLocP)(crossLoc);

		if (crossSetSizeP)
			(child->*crossSetSizeP)(crossLimit);
		if (child->getFlags() & flexMask)
			(child->*mainSetSizeP)(flexAmount);
		pos += (child->*mainGetSizeP)() + fSpacer;
	}
}

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

#ifdef SK_DEBUG
	static void assert_no_attr(const SkDOM& dom, const SkDOM::Node* node, const char attr[])
	{
		const char* value = dom.findAttr(node, attr);
		if (value)
			SkDebugf("unknown attribute %s=\"%s\"\n", attr, value);
	}
#else
	#define assert_no_attr(dom, node, attr)
#endif

void SkStackViewLayout::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
	int			index;
	SkScalar	value[4];

	if ((index = dom.findList(node, "orient", "horizontal,vertical")) >= 0)
		this->setOrient((Orient)index);
	else {
		assert_no_attr(dom, node, "orient");
        }

	if (dom.findScalars(node, "margin", value, 4))
	{
		SkRect	margin;
		margin.set(value[0], value[1], value[2], value[3]);
		this->setMargin(margin);
	}
	else {
		assert_no_attr(dom, node, "margin");
        }

	if (dom.findScalar(node, "spacer", value))
		this->setSpacer(value[0]);
	else {
		assert_no_attr(dom, node, "spacer");
        }

	if ((index = dom.findList(node, "pack", "start,center,end")) >= 0)
		this->setPack((Pack)index);
	else {
		assert_no_attr(dom, node, "pack");
        }

	if ((index = dom.findList(node, "align", "start,center,end,stretch")) >= 0)
		this->setAlign((Align)index);
	else {
		assert_no_attr(dom, node, "align");
        }
}

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

SkFillViewLayout::SkFillViewLayout()
{
	fMargin.setEmpty();
}

void SkFillViewLayout::getMargin(SkRect* r) const
{
	if (r)
		*r = fMargin;
}

void SkFillViewLayout::setMargin(const SkRect& margin)
{
	fMargin = margin;
}

void SkFillViewLayout::onLayoutChildren(SkView* parent)
{
	SkView::B2FIter	iter(parent);
	SkView*			child;

	while ((child = iter.next()) != NULL)
	{
		child->setLoc(fMargin.fLeft, fMargin.fTop);
		child->setSize(	parent->width() - fMargin.fRight - fMargin.fLeft,
						parent->height() - fMargin.fBottom - fMargin.fTop);
	}
}

void SkFillViewLayout::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
	this->INHERITED::onInflate(dom, node);
	(void)dom.findScalars(node, "margin", (SkScalar*)&fMargin, 4);
}

