#include "SkWidgetViews.h"

#include "SkAnimator.h"
#include "SkScrollBarView.h"

extern void init_skin_anim(const char name[], SkAnimator*);

struct SkListView::BindingRec {
	SkString	fSlotName;
	int			fFieldIndex;
};

SkListView::SkListView()
{
	fSource = NULL;				// our list-source
	fScrollBar = NULL;
	fAnims = NULL;				// array of animators[fVisibleRowCount]
	fBindings = NULL;			// our fields->slot array
	fBindingCount = 0;			// number of entries in fSlots array
	fScrollIndex = 0;			// number of cells to skip before first visible cell
	fCurrIndex = -1;			// index of "selected" cell
	fVisibleRowCount = 0;		// number of cells that can fit in our bounds
	fAnimContentDirty = true;	// true if fAnims[] have their correct content
	fAnimFocusDirty = true;

	fHeights[kNormal_Height] = SkIntToScalar(16);
	fHeights[kSelected_Height] = SkIntToScalar(16);
	
	this->setFlags(this->getFlags() | kFocusable_Mask);
}

SkListView::~SkListView()
{
	SkSafeUnref(fScrollBar);
	SkSafeUnref(fSource);
	delete[] fAnims;
	delete[] fBindings;
}

void SkListView::setHasScrollBar(bool hasSB)
{
	if (hasSB != this->hasScrollBar())
	{
		if (hasSB)
		{
			SkASSERT(fScrollBar == NULL);
			fScrollBar = (SkScrollBarView*)SkWidgetFactory(kScroll_WidgetEnum);
			fScrollBar->setVisibleP(true);
			this->attachChildToFront(fScrollBar);
			fScrollBar->setHeight(this->height());	// assume it auto-sets its width
		//	fScrollBar->setLoc(this->getContentWidth(), 0);
			fScrollBar->setLoc(this->width()-SkIntToScalar(10), 0);
		}
		else
		{
			SkASSERT(fScrollBar);
			fScrollBar->detachFromParent();
			fScrollBar->unref();
			fScrollBar = NULL;
		}
		this->dirtyCache(kAnimContent_DirtyFlag);
	}
}

void SkListView::setSelection(int index)
{
	if (fCurrIndex != index)
	{
		fAnimFocusDirty = true;
		this->inval(NULL);

		this->invalSelection();
		fCurrIndex = index;
		this->invalSelection();
		this->ensureSelectionIsVisible();
	}
}

bool SkListView::moveSelectionUp()
{
	if (fSource)
	{
		int	index = fCurrIndex;
		if (index < 0)	// no selection
			index = fSource->countRecords() - 1;
		else
			index = SkMax32(index - 1, 0);
		
		if (fCurrIndex != index)
		{
			this->setSelection(index);
			return true;
		}
	}
	return false;
}

bool SkListView::moveSelectionDown()
{
	if (fSource)
	{
		int	index = fCurrIndex;
		if (index < 0)	// no selection
			index = 0;
		else
			index = SkMin32(index + 1, fSource->countRecords() - 1);
		
		if (fCurrIndex != index)
		{
			this->setSelection(index);
			return true;
		}
	}
	return false;
}

void SkListView::invalSelection()
{
	SkRect	r;
	if (this->getRowRect(fCurrIndex, &r))
		this->inval(&r);
}

void SkListView::ensureSelectionIsVisible()
{
	if (fSource && (unsigned)fCurrIndex < (unsigned)fSource->countRecords())
	{
		int index = this->logicalToVisualIndex(fCurrIndex);

		if ((unsigned)index >= (unsigned)fVisibleRowCount)	// need to scroll
		{
			int newIndex;
			
			if (index < 0)	// too high
				newIndex = fCurrIndex;
			else
				newIndex = fCurrIndex - fVisibleRowCount + 1;
			SkASSERT((unsigned)newIndex < (unsigned)fSource->countRecords());
			this->inval(NULL);
			
			if (fScrollIndex != newIndex)
			{
				fScrollIndex = newIndex;
				if (fScrollBar)
					fScrollBar->setStart(newIndex);
				this->dirtyCache(kAnimContent_DirtyFlag);
			}
		}
	}
}

SkScalar SkListView::getContentWidth() const
{
	SkScalar width = this->width();
	
	if (fScrollBar)
	{
		width -= fScrollBar->width();
		if (width < 0)
			width = 0;
	}
	return width;
}

bool SkListView::getRowRect(int index, SkRect* r) const
{
	SkASSERT(r);

	index = this->logicalToVisualIndex(index);
	if (index >= 0)
	{
		int	selection = this->logicalToVisualIndex(fCurrIndex);
		
		SkScalar height = fHeights[index == selection ? kSelected_Height : kNormal_Height];
		SkScalar top = index * fHeights[kNormal_Height];

		if (index > selection && selection >= 0)
			top += fHeights[kSelected_Height] - fHeights[kNormal_Height];	

		if (top < this->height())
		{
			if (r)
				r->set(0, top, this->getContentWidth(), top + height);
			return true;
		}
	}
	return false;
}

SkListSource* SkListView::setListSource(SkListSource* src)
{
	if (fSource != src)
	{
		SkRefCnt_SafeAssign(fSource, src);
		this->ensureSelectionIsVisible();
		this->inval(NULL);
		
		if (fScrollBar)
			fScrollBar->setTotal(fSource->countRecords());
	}
	return src;
}

void SkListView::dirtyCache(unsigned dirtyFlags)
{
	if (dirtyFlags & kAnimCount_DirtyFlag)
	{
		delete fAnims;
		fAnims = NULL;
		fAnimContentDirty = true;
		fAnimFocusDirty = true;
	}
	if (dirtyFlags & kAnimContent_DirtyFlag)
	{
		if (!fAnimContentDirty)
		{
			this->inval(NULL);
			fAnimContentDirty = true;
		}
		fAnimFocusDirty = true;
	}
}

bool SkListView::ensureCache()
{
	if (fSkinName.size() == 0)
		return false;

	if (fAnims == NULL)
	{
		int n = SkMax32(1, fVisibleRowCount);

		SkASSERT(fAnimContentDirty);
		fAnims = new SkAnimator[n];
		for (int i = 0; i < n; i++)
		{
			fAnims[i].setHostEventSink(this);
			init_skin_anim(fSkinName.c_str(), &fAnims[i]);
		}
		
		fHeights[kNormal_Height] = fAnims[0].getScalar("idleHeight", "value");
		fHeights[kSelected_Height] = fAnims[0].getScalar("focusedHeight", "value");

		fAnimFocusDirty = true;
	}

	if (fAnimContentDirty && fSource)
	{
		fAnimContentDirty = false;

		SkString	str;
		SkEvent		evt("user");
		evt.setString("id", "setFields");
		evt.setS32("rowCount", fVisibleRowCount);
		
		SkEvent	dimEvt("user");
		dimEvt.setString("id", "setDim");
		dimEvt.setScalar("dimX", this->getContentWidth());
		dimEvt.setScalar("dimY", this->height());

		for (int i = fScrollIndex; i < fScrollIndex + fVisibleRowCount; i++)
		{
			evt.setS32("relativeIndex", i - fScrollIndex);
			for (int j = 0; j < fBindingCount; j++)
			{
				fSource->getRecord(i, fBindings[j].fFieldIndex, &str);
//SkDEBUGF(("getRecord(%d,%d,%s) slot(%s)\n", i, fBindings[j].fFieldIndex, str.c_str(), fBindings[j].fSlotName.c_str()));
				evt.setString(fBindings[j].fSlotName.c_str(), str.c_str());
			}
			(void)fAnims[i % fVisibleRowCount].doUserEvent(evt);
			(void)fAnims[i % fVisibleRowCount].doUserEvent(dimEvt);
		}
		fAnimFocusDirty = true;
	}

	if (fAnimFocusDirty)
	{
//SkDEBUGF(("service fAnimFocusDirty\n"));
		fAnimFocusDirty = false;

		SkEvent		focusEvt("user");
		focusEvt.setString("id", "setFocus");

		for (int i = fScrollIndex; i < fScrollIndex + fVisibleRowCount; i++)
		{
			focusEvt.setS32("FOCUS", i == fCurrIndex);
			(void)fAnims[i % fVisibleRowCount].doUserEvent(focusEvt);
		}
	}

	return true;
}

void SkListView::ensureVisibleRowCount()
{
	SkScalar	height = this->height();
	int			n = 0;
	
	if (height > 0)
	{
		n = 1;
		height -= fHeights[kSelected_Height];
		if (height > 0)
		{
			SkScalar count = SkScalarDiv(height, fHeights[kNormal_Height]);
			n += SkScalarFloor(count);
			if (count - SkIntToScalar(n) > SK_Scalar1*3/4)
				n += 1;
				
		//	SkDebugf("count %g, n %d\n", count/65536., n);
		}
	}

	if (fVisibleRowCount != n)
	{
		if (fScrollBar)
			fScrollBar->setShown(n);

		fVisibleRowCount = n;
		this->ensureSelectionIsVisible();
		this->dirtyCache(kAnimCount_DirtyFlag | kAnimContent_DirtyFlag);
	}
}

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

#include "SkSystemEventTypes.h"
#include "SkTime.h"

void SkListView::onSizeChange()
{
	this->INHERITED::onSizeChange();

	if (fScrollBar)
		fScrollBar->setLoc(this->width()-SkIntToScalar(10), 0);

	this->ensureVisibleRowCount();
}

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

	this->ensureVisibleRowCount();

	int	visibleCount = SkMin32(fVisibleRowCount, fSource->countRecords() - fScrollIndex);
	if (visibleCount == 0 || !this->ensureCache())
		return;

//SkDebugf("visibleCount %d scrollIndex %d currIndex %d\n", visibleCount, fScrollIndex, fCurrIndex);

	SkAutoCanvasRestore	ar(canvas, true);
	SkMSec				now = SkTime::GetMSecs();
	SkRect				bounds;

	bounds.fLeft	= 0;
	bounds.fRight	= this->getContentWidth();
	bounds.fBottom	= 0;
	// assign bounds.fTop inside the loop

	// hack to reveal our bounds for debugging
	if (this->hasFocus())
		canvas->drawARGB(0x11, 0, 0, 0xFF);
	else
		canvas->drawARGB(0x11, 0x88, 0x88, 0x88);

	for (int i = fScrollIndex; i < fScrollIndex + visibleCount; i++)
	{
		SkPaint	 paint;
		SkScalar height = fHeights[i == fCurrIndex ? kSelected_Height : kNormal_Height];

		bounds.fTop = bounds.fBottom;
		bounds.fBottom += height;
		
		canvas->save();
		if (fAnims[i % fVisibleRowCount].draw(canvas, &paint, now) != SkAnimator::kNotDifferent)
			this->inval(&bounds);
		canvas->restore();

		canvas->translate(0, height);
	}
}

bool SkListView::onEvent(const SkEvent& evt)
{
	if (evt.isType(SK_EventType_Key))
	{
		switch (evt.getFast32()) {
		case kUp_SkKey:
			return this->moveSelectionUp();
		case kDown_SkKey:
			return this->moveSelectionDown();
		case kRight_SkKey:
		case kOK_SkKey:
			this->postWidgetEvent();
			return true;
		default:
			break;
		}
	}
	return this->INHERITED::onEvent(evt);
}

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

static const char gListViewEventSlot[] = "sk-listview-slot-name";

/*virtual*/ bool SkListView::onPrepareWidgetEvent(SkEvent* evt)
{
	if (fSource && fCurrIndex >= 0 && this->INHERITED::onPrepareWidgetEvent(evt) &&
		fSource->prepareWidgetEvent(evt, fCurrIndex))
	{
		evt->setS32(gListViewEventSlot, fCurrIndex);
		return true;
	}
	return false;
}

int SkListView::GetWidgetEventListIndex(const SkEvent& evt)
{
	int32_t	index;

	return evt.findS32(gListViewEventSlot, &index) ? index : -1;
}

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

void SkListView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
	this->INHERITED::onInflate(dom, node);
	
	{
		bool hasScrollBar;
		if (dom.findBool(node, "scrollBar", &hasScrollBar))
			this->setHasScrollBar(hasScrollBar);
	}

	const SkDOM::Node*	child;

	if ((child = dom.getFirstChild(node, "bindings")) != NULL)
	{
		delete[] fBindings;
		fBindings = NULL;
		fBindingCount = 0;

		SkListSource* listSrc = SkListSource::Factory(dom.findAttr(child, "data-fields"));
		SkASSERT(listSrc);
		fSkinName.set(dom.findAttr(child, "skin-slots"));
		SkASSERT(fSkinName.size());

		this->setListSource(listSrc)->unref();
			
		int count = dom.countChildren(child, "bind");
		if (count > 0)
		{
			fBindings = new BindingRec[count];
			count = 0;	// reuse this to count up to the number of valid bindings

			child = dom.getFirstChild(child, "bind");
			SkASSERT(child);
			do {
				const char* fieldName = dom.findAttr(child, "field");
				const char* slotName = dom.findAttr(child, "slot");
				if (fieldName && slotName)
				{
					fBindings[count].fFieldIndex = listSrc->findFieldIndex(fieldName);
					if (fBindings[count].fFieldIndex >= 0)
						fBindings[count++].fSlotName.set(slotName);
				}
			} while ((child = dom.getNextSibling(child, "bind")) != NULL);

			fBindingCount = SkToU16(count);
			if (count == 0)
			{
				SkDEBUGF(("SkListView::onInflate: no valid <bind> elements in <listsource>\n"));
				delete[] fBindings;
			}
		}
		this->dirtyCache(kAnimCount_DirtyFlag);
		this->setSelection(0);
	}
}

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

class SkXMLListSource : public SkListSource {
public:
	SkXMLListSource(const char doc[], size_t len);
	virtual ~SkXMLListSource()
	{
		delete[] fFields;
		delete[] fRecords;
	}

	virtual int countFields() { return fFieldCount; }
	virtual void getFieldName(int index, SkString* field)
	{
		SkASSERT((unsigned)index < (unsigned)fFieldCount);
		if (field)
			*field = fFields[index];
	}
	virtual int findFieldIndex(const char field[])
	{
		for (int i = 0; i < fFieldCount; i++)
			if (fFields[i].equals(field))
				return i;
		return -1;
	}

	virtual int	countRecords() { return fRecordCount; }
	virtual void getRecord(int rowIndex, int fieldIndex, SkString* data)
	{
		SkASSERT((unsigned)rowIndex < (unsigned)fRecordCount);
		SkASSERT((unsigned)fieldIndex < (unsigned)fFieldCount);
		if (data)
			*data = fRecords[rowIndex * fFieldCount + fieldIndex];
	}

	virtual bool prepareWidgetEvent(SkEvent* evt, int rowIndex)
	{
		// hack, for testing right now. Need the xml to tell us what to jam in and where
		SkString	data;
		
		this->getRecord(rowIndex, 0, &data);
		evt->setString("xml-listsource", data.c_str());
		return true;
	}
	
private:
	SkString*	fFields;	// [fFieldCount]
	SkString*	fRecords;	// [fRecordCount][fFieldCount]
	int			fFieldCount, fRecordCount;
};

#include "SkDOM.h"

SkXMLListSource::SkXMLListSource(const char doc[], size_t len)
{
	fFieldCount = fRecordCount = 0;
	fFields = fRecords = NULL;

	SkDOM	dom;

	const SkDOM::Node* node = dom.build(doc, len);
	SkASSERT(node);
	const SkDOM::Node*	child;	

	child = dom.getFirstChild(node, "fields");
	if (child)
	{
		fFieldCount = dom.countChildren(child, "field");
		fFields = new SkString[fFieldCount];

		int n = 0;
		child = dom.getFirstChild(child, "field");
		while (child)
		{
			fFields[n].set(dom.findAttr(child, "name"));
			child = dom.getNextSibling(child, "field");
			n += 1;
		}
		SkASSERT(n == fFieldCount);
	}
	
	child = dom.getFirstChild(node, "records");
	if (child)
	{
		fRecordCount = dom.countChildren(child, "record");
		fRecords = new SkString[fRecordCount * fFieldCount];

		int n = 0;
		child = dom.getFirstChild(child, "record");
		while (child)
		{
			for (int i = 0; i < fFieldCount; i++)
				fRecords[n * fFieldCount + i].set(dom.findAttr(child, fFields[i].c_str()));
			child = dom.getNextSibling(child, "record");
			n += 1;
		}
		SkASSERT(n == fRecordCount);
	}
}

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

SkListSource* SkListSource::Factory(const char name[])
{
	static const char gDoc[] =
		"<db name='contacts.db'>"
			"<fields>"
				"<field name='name'/>"
				"<field name='work-num'/>"
				"<field name='home-num'/>"
				"<field name='type'/>"
			"</fields>"
			"<records>"
				"<record name='Andy McFadden' work-num='919 357-1234' home-num='919 123-4567' type='0'/>"
				"<record name='Brian Swetland' work-num='919 123-1234' home-num='929 123-4567' type='1' />"
				"<record name='Chris Desalvo' work-num='919 345-1234' home-num='949 123-4567' type='1' />"
				"<record name='Chris White' work-num='919 234-1234' home-num='939 123-4567' type='2' />"
				"<record name='Dan Bornstein' work-num='919 357-1234' home-num='919 123-4567' type='0' />"
				"<record name='Don Cung' work-num='919 123-1234' home-num='929 123-4567' type='2' />"
				"<record name='Eric Fischer' work-num='919 345-1234' home-num='949 123-4567' type='2' />"
				"<record name='Ficus Kirkpatric' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
				"<record name='Jack Veenstra' work-num='919 234-1234' home-num='939 123-4567' type='2' />"
				"<record name='Jeff Yaksick' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
				"<record name='Joe Onorato' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
				"<record name='Mathias Agopian' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
				"<record name='Mike Fleming' work-num='919 234-1234' home-num='939 123-4567' type='2' />"
				"<record name='Nick Sears' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
				"<record name='Rich Miner' work-num='919 234-1234' home-num='939 123-4567' type='1' />"
				"<record name='Tracey Cole' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
				"<record name='Wei Huang' work-num='919 234-1234' home-num='939 123-4567' type='0' />"
			"</records>"
		"</db>";
		
//SkDebugf("doc size %d\n", sizeof(gDoc)-1);
	return new SkXMLListSource(gDoc, sizeof(gDoc) - 1);
}



