
/*
 * 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 "SkWidgetViews.h"
#include "SkTextBox.h"

#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

SkStaticTextView::SkStaticTextView()
{
	fMargin.set(0, 0);
	fMode = kFixedSize_Mode;
	fSpacingAlign = SkTextBox::kStart_SpacingAlign;
	
//	init_skin_paint(kStaticText_SkinEnum, &fPaint);
}

SkStaticTextView::~SkStaticTextView()
{
}

void SkStaticTextView::computeSize()
{
	if (fMode == kAutoWidth_Mode)
	{
		SkScalar width = fPaint.measureText(fText.c_str(), fText.size());
		this->setWidth(width + fMargin.fX * 2);
	}
	else if (fMode == kAutoHeight_Mode)
	{
		SkScalar width = this->width() - fMargin.fX * 2;
		int lines = width > 0 ? SkTextLineBreaker::CountLines(fText.c_str(), fText.size(), fPaint, width) : 0;

		this->setHeight(lines * fPaint.getFontSpacing() + fMargin.fY * 2);
	}
}

void SkStaticTextView::setMode(Mode mode)
{
	SkASSERT((unsigned)mode < kModeCount);

	if (fMode != mode)
	{
		fMode = SkToU8(mode);
		this->computeSize();
	}
}

void SkStaticTextView::setSpacingAlign(SkTextBox::SpacingAlign align)
{
	fSpacingAlign = SkToU8(align);
	this->inval(NULL);
}

void SkStaticTextView::getMargin(SkPoint* margin) const
{
	if (margin)
		*margin = fMargin;
}

void SkStaticTextView::setMargin(SkScalar dx, SkScalar dy)
{
	if (fMargin.fX != dx || fMargin.fY != dy)
	{
		fMargin.set(dx, dy);
		this->computeSize();
		this->inval(NULL);
	}
}

size_t SkStaticTextView::getText(SkString* text) const
{
	if (text)
		*text = fText;
	return fText.size();
}

size_t SkStaticTextView::getText(char text[]) const
{
	if (text)
		memcpy(text, fText.c_str(), fText.size());
	return fText.size();
}

void SkStaticTextView::setText(const SkString& text)
{
	this->setText(text.c_str(), text.size());
}

void SkStaticTextView::setText(const char text[])
{
	if (text == NULL)
		text = "";
	this->setText(text, strlen(text));
}

void SkStaticTextView::setText(const char text[], size_t len)
{
	if (!fText.equals(text, len))
	{
		fText.set(text, len);
		this->computeSize();
		this->inval(NULL);
	}
}

void SkStaticTextView::getPaint(SkPaint* paint) const
{
	if (paint)
		*paint = fPaint;
}

void SkStaticTextView::setPaint(const SkPaint& paint)
{
	if (fPaint != paint)
	{
		fPaint = paint;
		this->computeSize();
		this->inval(NULL);
	}
}

void SkStaticTextView::onDraw(SkCanvas* canvas)
{
	this->INHERITED::onDraw(canvas);

	if (fText.isEmpty())
		return;

	SkTextBox	box;

	box.setMode(fMode == kAutoWidth_Mode ? SkTextBox::kOneLine_Mode : SkTextBox::kLineBreak_Mode);
	box.setSpacingAlign(this->getSpacingAlign());
	box.setBox(fMargin.fX, fMargin.fY, this->width() - fMargin.fX, this->height() - fMargin.fY);
	box.draw(canvas, fText.c_str(), fText.size(), fPaint);
}

void SkStaticTextView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
#if 0
	this->INHERITED::onInflate(dom, node);

	int	index;
	if ((index = dom.findList(node, "mode", "fixed,auto-width,auto-height")) >= 0)
		this->setMode((Mode)index);
	else
		assert_no_attr(dom, node, "mode");

	if ((index = dom.findList(node, "spacing-align", "start,center,end")) >= 0)
		this->setSpacingAlign((SkTextBox::SpacingAlign)index);
	else
		assert_no_attr(dom, node, "spacing-align");

	SkScalar s[2];
	if (dom.findScalars(node, "margin", s, 2))
		this->setMargin(s[0], s[1]);
	else
		assert_no_attr(dom, node, "margin");

	const char* text = dom.findAttr(node, "text");
	if (text)
		this->setText(text);

	if ((node = dom.getFirstChild(node, "paint")) != NULL &&
		(node = dom.getFirstChild(node, "screenplay")) != NULL)
	{
		inflate_paint(dom, node, &fPaint);
	}
#endif
}

