(function () {
	'use strict';

    var ng_module_name = 'tile_library';

	// Manual singleton as the .service() appears to return multiple instances across Angular apps
	var instance = null;
	if (instance === null)
		instance = new TileLibraryService();

	angular.module(ng_module_name)
		.service('tileLibraryService', ['$http', 'growl.service', function($http, growlService)
		{
			instance.setHttp($http);
			instance.setGrowlService(growlService);
			return instance;
		}]);

	function TileLibraryService()
	{
		var service = this;

		service.categories = {};
		service.tiles = [];
		service.$http = null;
		service.growlService = null;
		service.isLoading = false;
		service.isLoadingCategories = false;

        service.GetCategories = function () {
            if ((!service.isLoadingCategories) && Object.keys(service.categories).length === 0) {
                service.isLoadingCategories = true;
                service.LoadCategories();
            }

            return service.categories;
        };

        service.LoadCategories = function () {
            service.$http({
                method: 'GET',
                url: '/api/pages/v0/categories/?filter=populated&sort_by=name'
            }).then(function success(response) {
                if (typeof response.data === 'string') {
                    service.growlService.showError('', 'Error retrieving Pages Categories list');
                    service.isLoadingCategories = false;
                    return;
                }

                Object.keys(service.categories).forEach(function (category_index) {
                    delete service.categories[category_index];
                });

                for (var category_index in response.data) {
                    service.categories[category_index] = response.data[category_index];
                }

                service.isLoadingCategories = false;
            });
        };

		service.LoadTileInfo = function()
		{
			service.$http({
				method: 'GET',
				url: '/api/pages/v0/components/?expand=cover_info'
			}).then(function success(response)
			{
				if (typeof response.data === 'string')
				{
					service.growlService.showError('', 'Error retrieving component list');
					service.isLoading = false;
					return;
				}

				while (service.tiles.length > 0)
				{
					service.tiles.pop();
				}

				for (var tile in response.data)
				{
					var cover_info = response.data[tile].cover_info;
					var use_glyph = true;
					if (cover_info.icon_svg.length > 0)
						use_glyph = false;
					service.tiles.push(
					{
						title: cover_info.title,
                        categories: cover_info.categories,
						description: cover_info.description,
						icon_class: cover_info.icon_class,
						icon_svg: cover_info.icon_svg.replace(/<\?\s*xml\s*.*\?>/, ''),
						application: cover_info.application,
						size_constraints: cover_info.size_constraints,
						css_class: cover_info.css_class,
						key: tile,
						use_glyph: use_glyph
					});
				}

				// Sort into alphabetic order
				service.tiles.sort(function(a, b)
				{
					if (a.title < b.title)
						return -1;
					if (a.title > b.title)
						return 1;
					return 0;
				});

				service.isLoading = false;
			});
		};

		// Returns a reference to the tile list. Note that this is a reference and may be updated later once the
		// list is loaded (i.e. it will be empty when the page first loads).
		service.getTiles = function()
		{
			if ((!service.isLoading) &&
				(service.tiles.length === 0))
			{
				service.isLoading = true;
				service.LoadTileInfo();
			}

			return service.tiles;
		};

		service.getTileTitle = function(key)
		{
			for (var i = 0; i < service.tiles.length; i++)
			{
				if (service.tiles[i].key === key)
					return service.tiles[i].title;
			}

			return 'Unknown';
		};

		// Angular can't inject dependencies into a singleton so we have to pass this in manually.
		// Only the first one is saved to avoid any state-change issues being overwritten mid-request.
		service.setHttp = function($http)
		{
			if (service.$http === null)
				service.$http = $http;
		};

		service.setGrowlService = function(growlService)
		{
			if (service.growlService === null)
				service.growlService = growlService;
		};
	}
}());
