define(['./Tile.class.js'], function (Tile){
var TileCollection = function ()
{
};

TileCollection.prototype.tileList = [];
TileCollection.prototype.history = [];
TileCollection.prototype.isSafeMode = false;

TileCollection.prototype.init = function(tileData, isSafeMode)
{
	for (var i = 0; i < tileData.tiles.length; i++)
	{
		var data = tileData.tiles[i];
		var newTile = new Tile();

		newTile.id = data.id;
		newTile.type = data.type;
		newTile.layout_id = tileData.layout_id;
		newTile.x = data.x;
		newTile.y = data.y;
		newTile.width = data.width;
		newTile.height = data.height;
		newTile.options = data.options;

		this.tileList.push(newTile);
	}

    this.isSafeMode = isSafeMode;
};

TileCollection.prototype.addtile = function(tileData)
{
	var newTile = new Tile();

	newTile.id = tileData.id;
	newTile.type = tileData.type;
	newTile.layout_id = tileData.layout_id;
	newTile.x = tileData.x;
	newTile.y = tileData.y;
	newTile.width = tileData.width;
	newTile.height = tileData.height;
	newTile.options = tileData.options;

	this.tileList.push(newTile);
};

TileCollection.prototype.updateGeometry = function(currentTiles)
{
	for (var i = 0; i < currentTiles.length; i++)
	{
		for (var j = 0; j < this.tileList.length; j++)
		{
			if (currentTiles[i].tile_id == this.tileList[j].id)
			{
				this.tileList[j].x = currentTiles[i].x;
				this.tileList[j].y = currentTiles[i].y;
				this.tileList[j].width = currentTiles[i].width;
				this.tileList[j].height = currentTiles[i].height;
			}
		}
	}
};

TileCollection.prototype.pushHistory = function()
{
	this.history.push(this.tileList);
};

TileCollection.prototype.popHistory = function()
{
	this.tileList = this.history.pop();
};

TileCollection.prototype.getPreviousHistoryVersion = function()
{
	return this.history[this.history.length - 1];
};

TileCollection.prototype.getTileFromHistory = function(tile_id)
{
	var history = this.getPreviousHistoryVersion();
	for (var i = 0; i < history.length; i++)
	{
		if (history[i].id === tile_id)
			return history[i];
	}

	return null;
};

/**
 * Compares the current state of the grid with the one when we started editing
 *
 * @return boolean
 */
TileCollection.prototype.checkForChanges = function(currentGeometry)
{
	var oldVersion = this.getPreviousHistoryVersion();

	// Early exit if the number of tiles is different
	if (currentGeometry.length !== oldVersion.length)
		return true;

	// Check each tile for changes
	for (var i = 0; i < currentGeometry.length; i++)
	{
		// Fail if the tile id doesn't match, or any location/size data has changed
		var tile = this.getTileFromHistory(currentGeometry[i].tile_id);
		if ((tile === null) ||
			(tile.x !== currentGeometry[i].x) ||
			(tile.y !== currentGeometry[i].y) ||
			(tile.width !== currentGeometry[i].width) ||
			(tile.height !== currentGeometry[i].height))
		{
			return true;
		}
	}

	return false;
};

TileCollection.prototype.getTileById = function(tile_id)
{
	for (var i = 0; i < this.tileList.length; i++)
	{
		if (this.tileList[i].id === tile_id)
			return this.tileList[i];
	}

	return null;
};

TileCollection.prototype.saveTile = function(page_id, tile_id, success_callback)
{
	var tile = this.getTileById(tile_id);

	var options = {};

	$.each(tile.options, function(key, value)
	{
		options[key] = value.value;
	});

	$.ajax(
	{
		url: '/api/pages/' + page_id + '/tiles/' + tile_id + '/options',
		method: 'PUT',
		contentType: 'application/json',
		data: JSON.stringify({
				options: options,
				return: ['status', 'header', 'body', 'info'],
                isSafeMode: this.isSafeMode
			}),
		dataType: 'json',
		success: function(data)
		{
			if (!data.status.success)
			{
				cla.showMessage(data.status.message, '', true);
				return
			}

			// Partial merge with existing tile options
			// This makes sure any Angular-added fields such as token don't get removed
			for (var option in data.info.options)
			{
				if (tile.options.hasOwnProperty(option))
				{
					for (var field in data.info.options[option])
					{
						if (option.hasOwnProperty(field))
							tile.options[option][field] = field;
					}
				}
			}


			var scope = angular.element('.grid-stack-item[data-tile_id=' + tile_id + '] .js-settings_app_directive div').scope();
			if (typeof scope === 'object')
			{
				scope.$apply();
				scope.select2ify();
			}

			if (typeof success_callback === 'function')
				success_callback(data, 'Success');
		},
		error: function (data) {
			if (typeof data.responseJSON.error === 'undefined')
			{
				cla.showMessage(data.responseText, '', true);
				return;
			}

			cla.showMessage(data.responseJSON.message, '', true);

			// Is it a "page not found" exception
			if (data.responseJSON.code === 1)
				cla.pages.invalidatePage();
		}
	});
};
return TileCollection;
});
