#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 = nil;				// our list-source
	fScrollBar = nil;
	fAnims = nil;				// array of animators[fVisibleRowCount]
	fBindings = nil;			// 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()
{
	fScrollBar->safeUnref();
	fSource->safeUnref();
	delete[] fAnims;
	delete[] fBindings;
}

void SkListView::setHasScrollBar(bool hasSB)
{
	if (hasSB != this->hasScrollBar())
	{
		if (hasSB)
		{
			SkASSERT(fScrollBar == nil);
			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 = nil;
		}
		this->dirtyCache(kAnimContent_DirtyFlag);
	}
}

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

		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(nil);
			
			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(nil);
		
		if (fScrollBar)
			fScrollBar->setTotal(fSource->countRecords());
	}
	return src;
}

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

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

	if (fAnims == nil)
	{
		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")) != nil)
	{
		delete[] fBindings;
		fBindings = nil;
		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")) != nil);

			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 = nil;

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



