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