//A liteGrid data provider that operates on an in-memory collection of widget
//objects.
function WidgeDataProvider() {
	var base = this;

	//Delay to add to calls.
	base.delay = 500;

	//Called by liteGrid.
	base.initialize = function(liteGrid, options) {

		base.liteGrid = liteGrid;

		base.createData();
	}

	//Populates the in-memory collection of objects.
	base.createData = function() {

		var widgets = [];
		var widgetLookup = {};
		var coating = ["silver", "gold", "platinum", "adamantium"];

		var randomCoating = function() {
			return coating[Math.floor(Math.random() * coating.length)];
		}

		for (var i = 1; i <= 20; i++) {
			var widget = { id: i, name: "Widget " + i, price: 10 * i, coating: randomCoating(), available: i%3!=0, description: "This is a description for widget " + i };

			//Add children randomly
			if (Math.random() > 0.5) {
				widget.HasChildren = true;
				widget.children = [
					{ id: "child-" + i + "-1", name: "Subwidget " + i + "-1", price: 20 * i, coating: randomCoating(), description: "This is a child widget of widget " + i },
					{ id: "child-" + i + "-2", name: "Subwidget " + i + "-2", price: 30 * i, coating: randomCoating(), description: "This is a child widget of widget " + i }
				];

				widgetLookup[widget.children[0].id] = widget.children[0];
				widgetLookup[widget.children[1].id] = widget.children[1];
			}

			widgetLookup[widget.id] = widget;

			widgets.push(widget);
		}

		base.widgets = widgets;
		base.widgetLookup = widgetLookup;
	}

	//Gets data from the provider.
	//This takes two parameters: a callback for success, and a callback for errors.
	base.getData = function(success, error) {

		base.liteGrid.$el.trigger("dataLoading");

		var data = { dataItems: base.widgets };

		setTimeout(
			function() {
				success(data);
				base.liteGrid.$el.trigger("dataLoaded");
			},
			base.delay
		);
	}

	//Gets children of the specified item.
	base.getChildData = function(parentId, success, error) {

		base.liteGrid.$el.trigger("dataLoading");

		var parent = null;

		$(base.widgets).each(function() {
			if (this.id == parentId) {
				parent = this;
			}
		});

		setTimeout(
			function() {
				success({ dataItems: parent.children });
				base.liteGrid.$el.trigger("dataLoaded");
			},
			base.delay
		);
	}

	//Posts the data back to the server.
	base.saveData = function(dataItems, success, error) {

		console.log("Received data: ", dataItems);

		base.liteGrid.$el.trigger("dataLoading");

		var modifiedItems = [];

		$(dataItems).each(function() {

			var dataItem = this;

			//Copy new values to the original widget
			var widget = base.widgetLookup[dataItem.id];

			var isNew = widget === undefined;

			if (isNew) {
				widget = { id: base.widgets.length + 1 };
			}

			//If the widget specifies a new parent, move it there.
			if (dataItem.newParentId && dataItem.newParentId > 0) {
				var parent = base.widgetLookup[dataItem.newParentId];
				parent.HasChildren = true;

				if (!parent.children) {
					parent.children = [];
				}

				parent.children.push(widget);
			}

			for (prop in dataItem) {
				//Don't copy the ID field to newly inserted widgets
				if (prop == "id") {
					continue;
				}
				widget[prop] = dataItem[prop];
			}

			if (isNew) {
				base.widgets.push(widget);
				base.widgetLookup[widget.id] = widget;
			}

			//At this point you should really handle deletes, but given the nature of the demo,
			//that's really not necessary. 

			modifiedItems.push(widget);
		});

		setTimeout(
			function() {
				success({ status: true, dataItems: modifiedItems });
				base.liteGrid.$el.trigger("dataLoaded");
			},
			base.delay
		);
	}

	//Saves the value of a single cell back to the server.
	base.saveCell = function(id, column, value, success, error) {

		throw "Not Implemented!";
	}
}