#include "SkWidget.h"
#include "SkCanvas.h"
#include "SkEvent.h"
#include "SkKey.h"
#include "SkParsePaint.h"
#include "SkSystemEventTypes.h"

#if 0

SkEvent* SkListSource::getEvent(int index)
{
	return NULL;
}

#include "SkOSFile.h"

class SkDirListSource : public SkListSource {
public:
	SkDirListSource(const char path[], const char suffix[], const char target[])
		: fPath(path), fSuffix(suffix), fTarget(target)
	{
		fCount = -1;
	}
	virtual int	countRows()
	{
		if (fCount < 0)
		{
			fCount = 0;
			fIter.reset(fPath.c_str(), fSuffix.c_str());
			while (fIter.next(NULL))
				fCount += 1;
			fIter.reset(fPath.c_str(), fSuffix.c_str());
			fIndex = 0;
		}
		return fCount;
	}
	virtual void getRow(int index, SkString* left, SkString* right)
	{
		(void)this->countRows();
		SkASSERT((unsigned)index < (unsigned)fCount);

		if (fIndex > index)
		{
			fIter.reset(fPath.c_str(), fSuffix.c_str());
			fIndex = 0;
		}

		while (fIndex < index)
		{
			fIter.next(NULL);
			fIndex += 1;
		}

		if (fIter.next(left))
		{
			if (left)
				left->remove(left->size() - fSuffix.size(), fSuffix.size());
		}
		else
		{
			if (left)
				left->reset();
		}
		if (right)	// only set to ">" if we know we're on a sub-directory
			right->reset();

		fIndex += 1;
	}
	virtual SkEvent* getEvent(int index)
	{
		SkASSERT((unsigned)index < (unsigned)fCount);

		SkEvent*	evt = new SkEvent();
		SkString	label;

		this->getRow(index, &label, NULL);
		evt->setString("name", label.c_str());

		int c = fPath.c_str()[fPath.size() - 1];
		if (c != '/' && c != '\\')
			label.prepend("/");
		label.prepend(fPath);
		label.append(fSuffix);
		evt->setString("path", label.c_str());
		evt->setS32("index", index);
		evt->setS32("duration", 22);
		evt->setType(fTarget);
		return evt;
	}

private:
	SkString		fPath, fSuffix;
	SkString		fTarget;
	SkOSFile::Iter	fIter;
	int				fCount;
	int				fIndex;
};

SkListSource* SkListSource::CreateFromDir(const char path[], const char suffix[], const char target[])
{
	return new SkDirListSource(path, suffix, target);
}

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

class SkDOMListSource : public SkListSource {
public:
	enum Type {
		kUnknown_Type,
		kDir_Type,
		kToggle_Type
	};
	struct ItemRec {
		SkString	fLabel;
		SkString	fTail, fAltTail;
		SkString	fTarget;
		Type		fType;
	};

	SkDOMListSource(const SkDOM& dom, const SkDOM::Node* node) : fDirTail(">")
	{
		const SkDOM::Node* child = dom.getFirstChild(node, "item");
		int	count = 0;

		while (child)
		{
			count += 1;
			child = dom.getNextSibling(child, "item");
		}

		fCount = count;
		fList = NULL;
		if (count)
		{
			ItemRec* rec = fList = new ItemRec[count];

			child = dom.getFirstChild(node, "item");
			while (child)
			{
				rec->fLabel.set(dom.findAttr(child, "label"));
				rec->fTail.set(dom.findAttr(child, "tail"));
				rec->fAltTail.set(dom.findAttr(child, "alt-tail"));
				rec->fTarget.set(dom.findAttr(child, "target"));
				rec->fType = kUnknown_Type;

				int	index = dom.findList(child, "type", "dir,toggle");
				if (index >= 0)
					rec->fType = (Type)(index + 1);

				child = dom.getNextSibling(child, "item");
				rec += 1;
			}
		}
	}
	virtual ~SkDOMListSource()
	{
		delete[] fList;
	}
	virtual int	countRows()
	{
		return fCount;
	}
	virtual void getRow(int index, SkString* left, SkString* right)
	{
		SkASSERT((unsigned)index < (unsigned)fCount);

		if (left)
			*left = fList[index].fLabel;
		if (right)
			*right = fList[index].fType == kDir_Type ? fDirTail : fList[index].fTail;
	}
	virtual SkEvent* getEvent(int index)
	{
		SkASSERT((unsigned)index < (unsigned)fCount);

		if (fList[index].fType == kDir_Type)
		{
			SkEvent* evt = new SkEvent();
			evt->setType(fList[index].fTarget);
			evt->setFast32(index);
			return evt;
		}
		if (fList[index].fType == kToggle_Type)
			fList[index].fTail.swap(fList[index].fAltTail);

		return NULL;
	}

private:
	int			fCount;
	ItemRec*	fList;
	SkString	fDirTail;
};

SkListSource* SkListSource::CreateFromDOM(const SkDOM& dom, const SkDOM::Node* node)
{
	return new SkDOMListSource(dom, node);
}

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

SkListView::SkListView(U32 flags) : SkWidgetView(flags)
{
	fSource = NULL;
	fScrollIndex = 0;
	fCurrIndex = -1;
	fRowHeight = SkIntToScalar(16);
	fVisibleRowCount = 0;
	fStrCache = NULL;

	fPaint[kBG_Attr].setColor(0);
	fPaint[kNormalText_Attr].setTextSize(SkIntToScalar(14));
	fPaint[kHiliteText_Attr].setTextSize(SkIntToScalar(14));
	fPaint[kHiliteText_Attr].setColor(SK_ColorWHITE);
	fPaint[kHiliteCell_Attr].setColor(SK_ColorBLUE);
}

SkListView::~SkListView()
{
	delete[] fStrCache;
	fSource->safeUnref();
}

void SkListView::setRowHeight(SkScalar height)
{
	SkASSERT(height >= 0);

	if (fRowHeight != height)
	{
		fRowHeight = height;
		this->inval(NULL);
		this->onSizeChange();
	}
}

void SkListView::setSelection(int index)
{
	if (fCurrIndex != index)
	{
		this->invalSelection();
		fCurrIndex = index;
		this->invalSelection();
		this->ensureSelectionIsVisible();

		{
			SkEvent	evt;
			evt.setType("listview-selection");
			evt.setFast32(index);
			this->sendEventToParents(evt);
		}
	}
}

void SkListView::moveSelectionUp()
{
	if (fSource)
	{
		int	index = fCurrIndex;
		if (index < 0)	// no selection
			index = fSource->countRows() - 1;
		else
			index = SkMax32(index - 1, 0);
		this->setSelection(index);
	}
}

void SkListView::moveSelectionDown()
{
	if (fSource)
	{
		int	index = fCurrIndex;
		if (index < 0)	// no selection
			index = 0;
		else
			index = SkMin32(index + 1, fSource->countRows() - 1);
		this->setSelection(index);
	}
}

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

void SkListView::ensureSelectionIsVisible()
{
	if (fSource == NULL)
		return;

	if ((unsigned)fCurrIndex < (unsigned)fSource->countRows())
	{
		int index = this->logicalToVisualIndex(fCurrIndex);

		if ((unsigned)index >= (unsigned)fVisibleRowCount)	// need to scroll
		{
			if (index < 0)	// too high
				fScrollIndex = fCurrIndex;
			else
				fScrollIndex = fCurrIndex - fVisibleRowCount + 1;
			SkASSERT((unsigned)fScrollIndex < (unsigned)fSource->countRows());

			this->dirtyStrCache();
			this->inval(NULL);
		}
	}
}

bool SkListView::getRowRect(int index, SkRect* r) const
{
	SkASSERT(r);
	index = this->logicalToVisualIndex(index);
	if (index >= 0)
	{
		SkScalar top = index * fRowHeight;

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

SkPaint& SkListView::paint(Attr attr)
{
	SkASSERT((unsigned)attr < kAttrCount);
	return fPaint[attr];
}

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

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

	canvas->drawPaint(fPaint[kBG_Attr]);

	int	visibleCount = SkMin32(fVisibleRowCount, fSource->countRows() - fScrollIndex);
	if (visibleCount == 0)
		return;

	this->ensureStrCache(visibleCount);
	int currIndex = this->logicalToVisualIndex(fCurrIndex);

	if ((unsigned)currIndex < (unsigned)visibleCount)
	{
		SkAutoCanvasRestore	restore(canvas, true);
		SkRect	r;

		canvas->translate(0, currIndex * fRowHeight);
		(void)this->getRowRect(fScrollIndex, &r);
		canvas->drawRect(r, fPaint[kHiliteCell_Attr]);
	}

	SkPaint*	p;
	SkScalar	y, x = SkIntToScalar(6);
	SkScalar	rite = this->width() - x;

	{
		SkScalar ascent, descent;
		fPaint[kNormalText_Attr].measureText(0, NULL, &ascent, &descent);
		y = SkScalarHalf(fRowHeight - descent + ascent) - ascent;
	}

	for (int i = 0; i < visibleCount; i++)
	{
		if (i == currIndex)
			p = &fPaint[kHiliteText_Attr];
		else
			p = &fPaint[kNormalText_Attr];

		p->setTextAlign(SkPaint::kLeft_Align);
		canvas->drawText(fStrCache[i].c_str(), fStrCache[i].size(), x, y, *p);
		p->setTextAlign(SkPaint::kRight_Align);
		canvas->drawText(fStrCache[i + visibleCount].c_str(), fStrCache[i + visibleCount].size(), rite, y, *p);
		canvas->translate(0, fRowHeight);
	}
}

void SkListView::onSizeChange()
{
	SkScalar count = SkScalarDiv(this->height(), fRowHeight);
	int		 n = SkScalarFloor(count);

	// only want to show rows that are mostly visible
	if (n == 0 || count - SkIntToScalar(n) > SK_Scalar1*75/100)
		n += 1;

	if (fVisibleRowCount != n)
	{
		fVisibleRowCount = n;
		this->ensureSelectionIsVisible();
		this->dirtyStrCache();
	}
}

void SkListView::dirtyStrCache()
{
	if (fStrCache)
	{
		delete[] fStrCache;
		fStrCache = NULL;
	}
}

void SkListView::ensureStrCache(int count)
{
	if (fStrCache == NULL)
	{
		fStrCache = new SkString[count << 1];

		if (fSource)
			for (int i = 0; i < count; i++)
				fSource->getRow(i + fScrollIndex, &fStrCache[i], &fStrCache[i + count]);
	}
}

bool SkListView::onEvent(const SkEvent& evt)
{
	if (evt.isType(SK_EventType_Key))
	{
		switch (evt.getFast32()) {
		case kUp_SkKey:
			this->moveSelectionUp();
			return true;
		case kDown_SkKey:
			this->moveSelectionDown();
			return true;
		case kRight_SkKey:
		case kOK_SkKey:
			if (fSource && fCurrIndex >= 0)
			{
				SkEvent* evt = fSource->getEvent(fCurrIndex);
				if (evt)
				{
					SkView* view = this->sendEventToParents(*evt);
					delete evt;
					return view != NULL;
				}
				else	// hack to make toggle work
				{
					this->dirtyStrCache();
					this->inval(NULL);
				}
			}
			break;
		}
	}
	return this->INHERITED::onEvent(evt);
}

void SkListView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
	this->INHERITED::onInflate(dom, node);

	SkScalar			x;
	const SkDOM::Node*	child;

	if (dom.findScalar(node, "row-height", &x))
		this->setRowHeight(x);

	if ((child = dom.getFirstChild(node, "hilite-paint")) != NULL)
		SkPaint_Inflate(&this->paint(kHiliteCell_Attr), dom, child);

	// look for a listsource
	{
		SkListSource* src = NULL;

		if ((child = dom.getFirstChild(node, "file-listsource")) != NULL)
		{
			const char* path = dom.findAttr(child, "path");
			if (path)
				src = SkListSource::CreateFromDir(	path,
													dom.findAttr(child, "filter"),
													dom.findAttr(child, "target"));
		}
		else if ((child = dom.getFirstChild(node, "xml-listsource")) != NULL)
		{
			src = SkListSource::CreateFromDOM(dom, child);
		}

		if (src)
		{
			this->setListSource(src)->unref();
			this->setSelection(0);
		}
	}
}

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

#include "SkImageDecoder.h"
#include "SkShader.h"

class SkScrollBarView : public SkView {
public:
	SkScrollBarView(const char bg[], const char fg[])
	{
		fBGRef = SkBitmapRef::Decode(bg, true);
		fFGRef = SkBitmapRef::Decode(fg, true);

		if (fBGRef)
			this->setWidth(SkIntToScalar(fBGRef->bitmap().width()));
	}
	~SkScrollBarView()
	{
		delete fBGRef;
		delete fFGRef;
	}
protected:
	virtual void onDraw(SkCanvas* canvas)
	{
		if (fBGRef == NULL) return;

		SkPaint	paint;

		SkShader* shader = SkShader::CreateBitmapShader(fBGRef->bitmap(), false, SkPaint::kNo_FilterType, SkShader::kClamp_TileMode);
		paint.setShader(shader)->unref();

		canvas->drawPaint(paint);
	}
private:
	SkBitmapRef*	fBGRef, *fFGRef;
};

SkGridView::SkGridView(U32 flags) : SkWidgetView(flags)
{
	fSource = NULL;
	fCurrIndex = -1;
	fVisibleCount.set(0, 0);

	fPaint[kBG_Attr].setColor(SK_ColorWHITE);
	fPaint[kHiliteCell_Attr].setColor(SK_ColorYELLOW);
	fPaint[kHiliteCell_Attr].setStyle(SkPaint::kStroke_Style);
	fPaint[kHiliteCell_Attr].setAntiAliasOn(true);
	fPaint[kHiliteCell_Attr].setStrokeWidth(SK_Scalar1*3);

	fScrollBar = new SkScrollBarView("icons/scrollbarGrey.jpg", "icons/scrollbarBlue.jpg");
	this->attachChildToFront(fScrollBar)->unref();
	fScrollBar->setVisibleP(true);
}

SkGridView::~SkGridView()
{
	fSource->safeUnref();
}

void SkGridView::getCellSize(SkPoint* size) const
{
	if (size)
		*size = fCellSize;
}

void SkGridView::setCellSize(SkScalar x, SkScalar y)
{
	SkASSERT(x >= 0 && y >= 0);

	if (!fCellSize.equals(x, y))
	{
		fCellSize.set(x, y);
		this->inval(NULL);
	}
}

void SkGridView::setSelection(int index)
{
	if (fCurrIndex != index)
	{
		this->invalSelection();
		fCurrIndex = index;
		this->invalSelection();
		this->ensureSelectionIsVisible();

		// this generates the click
		{
			SkEvent	evt;
			evt.setType("listview-selection");
			evt.setFast32(index);
			this->sendEventToParents(evt);
		}
	}
}

void SkGridView::moveSelectionUp()
{
	if (fSource)
	{
		int	index = fCurrIndex;
		if (index < 0)	// no selection
			index = fSource->countRows() - 1;
		else
			index = SkMax32(index - 1, 0);
		this->setSelection(index);
	}
}

void SkGridView::moveSelectionDown()
{
	if (fSource)
	{
		int	index = fCurrIndex;
		if (index < 0)	// no selection
			index = 0;
		else
			index = SkMin32(index + 1, fSource->countRows() - 1);
		this->setSelection(index);
	}
}

void SkGridView::invalSelection()
{
	SkRect	r;
	if (this->getCellRect(fCurrIndex, &r))
	{
		SkScalar inset = 0;
		if (fPaint[kHiliteCell_Attr].getStyle() != SkPaint::kFill_Style)
			inset += fPaint[kHiliteCell_Attr].getStrokeWidth() / 2;
		if (fPaint[kHiliteCell_Attr].isAntiAliasOn())
			inset += SK_Scalar1;
		r.inset(-inset, -inset);
		this->inval(&r);
	}
}

void SkGridView::ensureSelectionIsVisible()
{
	if (fSource == NULL)
		return;
#if 0
	if ((unsigned)fCurrIndex < (unsigned)fSource->countRows())
	{
		int index = this->logicalToVisualIndex(fCurrIndex);

		if ((unsigned)index >= (unsigned)fVisibleRowCount)	// need to scroll
		{
			if (index < 0)	// too high
				fScrollIndex = fCurrIndex;
			else
				fScrollIndex = fCurrIndex - fVisibleRowCount + 1;
			SkASSERT((unsigned)fScrollIndex < (unsigned)fSource->countRows());

			this->dirtyStrCache();
			this->inval(NULL);
		}
	}
#endif
}

bool SkGridView::getCellRect(int index, SkRect* r) const
{
	if (fVisibleCount.fY == 0)
		return false;

	index = this->logicalToVisualIndex(index);
	if (index >= 0)
	{
		SkRect	bounds;
		int row = index / fVisibleCount.fY;
		int col = index % fVisibleCount.fY;

		bounds.set(0, 0, fCellSize.fX, fCellSize.fY);
		bounds.offset(col * (fCellSize.fX + SkIntToScalar(col > 0)),
					  row * (fCellSize.fY + SkIntToScalar(row > 0)));

		if (bounds.fTop < this->height())
		{
			if (r)
				*r = bounds;
			return true;
		}
	}
	return false;
}

SkPaint& SkGridView::paint(Attr attr)
{
	SkASSERT((unsigned)attr < kAttrCount);
	return fPaint[attr];
}

SkListSource* SkGridView::setListSource(SkListSource* src)
{
	if (fSource != src)
	{
		SkRefCnt_SafeAssign(fSource, src);
	//	this->dirtyStrCache();
		this->ensureSelectionIsVisible();
		this->inval(NULL);
	}
	return src;
}

#include "SkShader.h"

static void copybits(SkCanvas* canvas, const SkBitmap& bm, const SkRect& dst, const SkPaint& paint)
{
	SkRect		src;
	SkMatrix	matrix;

	src.set(0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()));
	if (matrix.setRectToRect(src, dst))
	{
		SkPaint	  p(paint);
		SkShader* shader = SkShader::CreateBitmapShader(bm, false, SkPaint::kNo_FilterType, SkShader::kClamp_TileMode);
		p.setShader(shader)->unref();

		shader->setLocalMatrix(matrix);
		canvas->drawRect(dst, p);
	}
}

#include "SkImageDecoder.h"

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

	canvas->drawPaint(fPaint[kBG_Attr]);

	if (fSource == NULL)
		return;

#if 0
	int	visibleCount = SkMin32(fVisibleRowCount, fSource->countRows() - fScrollIndex);
	if (visibleCount == 0)
		return;

	this->ensureStrCache(visibleCount);
	int currIndex = this->logicalToVisualIndex(fCurrIndex);
#endif

	SkPaint	p;
	for (int i = 0; i < fSource->countRows(); i++)
	{
		bool	 forced = false;
		SkEvent* evt = fSource->getEvent(i);
		SkASSERT(evt);
		SkString path(evt->findString("path"));
		delete evt;

		SkBitmapRef* bmr = SkBitmapRef::Decode(path.c_str(), false);
		if (bmr == NULL)
		{
			bmr = SkBitmapRef::Decode(path.c_str(), true);
			if (bmr)
				forced = true;
		}

		if (bmr)
		{
			SkAutoTDelete<SkBitmapRef>	autoRef(bmr);
			SkRect	r;
			if (!this->getCellRect(i, &r))
				break;
			copybits(canvas, bmr->bitmap(), r, p);
		}
		// only draw one forced bitmap at a time
		if (forced)
		{
			this->inval(NULL);	// could inval only the remaining visible cells...
			break;
		}
	}

	// draw the hilite
	{
		SkRect	r;
		if (fCurrIndex >= 0 && this->getCellRect(fCurrIndex, &r))
			canvas->drawRect(r, fPaint[kHiliteCell_Attr]);
	}
}

static int check_count(int n, SkScalar s)
{
	// only want to show cells that are mostly visible
	if (n == 0 || s - SkIntToScalar(n) > SK_Scalar1*75/100)
		n += 1;
	return n;
}

void SkGridView::onSizeChange()
{
	fScrollBar->setHeight(this->height());
	fScrollBar->setLoc(this->locX() + this->width() - fScrollBar->width(), 0);

	if (fCellSize.equals(0, 0))
	{
		fVisibleCount.set(0, 0);
		return;
	}

	SkScalar rows = SkScalarDiv(this->height(), fCellSize.fY);
	SkScalar cols = SkScalarDiv(this->width(), fCellSize.fX);
	int		 y = SkScalarFloor(rows);
	int		 x = SkScalarFloor(cols);

	y = check_count(y, rows);
	x = check_count(x, cols);

	if (!fVisibleCount.equals(x, y))
	{
		fVisibleCount.set(x, y);
		this->ensureSelectionIsVisible();
	//	this->dirtyStrCache();
	}
}

bool SkGridView::onEvent(const SkEvent& evt)
{
	if (evt.isType(SK_EventType_Key))
	{
		switch (evt.getFast32()) {
		case kUp_SkKey:
			this->moveSelectionUp();
			return true;
		case kDown_SkKey:
			this->moveSelectionDown();
			return true;
		case kRight_SkKey:
		case kOK_SkKey:
			if (fSource && fCurrIndex >= 0)
			{
				SkEvent* evt = fSource->getEvent(fCurrIndex);
				if (evt)
				{
					// augment the event with our local rect
					(void)this->getCellRect(fCurrIndex, (SkRect*)evt->setScalars("local-rect", 4, NULL));

					SkView* view = this->sendEventToParents(*evt);
					delete evt;
					return view != NULL;
				}
			}
			break;
		}
	}
	return this->INHERITED::onEvent(evt);
}

void SkGridView::onInflate(const SkDOM& dom, const SkDOM::Node* node)
{
	this->INHERITED::onInflate(dom, node);

	SkScalar			x[2];
	const SkDOM::Node*	child;

	if (dom.findScalars(node, "cell-size", x, 2))
		this->setCellSize(x[0], x[1]);

	if ((child = dom.getFirstChild(node, "hilite-paint")) != NULL)
		SkPaint_Inflate(&this->paint(kHiliteCell_Attr), dom, child);

	// look for a listsource
	{
		SkListSource* src = NULL;

		if ((child = dom.getFirstChild(node, "file-listsource")) != NULL)
		{
			const char* path = dom.findAttr(child, "path");
			if (path)
				src = SkListSource::CreateFromDir(	path,
													dom.findAttr(child, "filter"),
													dom.findAttr(child, "target"));
		}
		else if ((child = dom.getFirstChild(node, "xml-listsource")) != NULL)
		{
			src = SkListSource::CreateFromDOM(dom, child);
		}

		if (src)
		{
			this->setListSource(src)->unref();
			this->setSelection(0);
		}
	}
	this->onSizeChange();
}

#endif
