#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);
}

