'use strict';

/**
 * Licensed Materials - Property of IBM
 * IBM Cognos Products: BI
 * (C) Copyright IBM Corp. 2016, 2019
 * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 */
define(['../../lib/@waca/dashboard-common/dist/core/Collection', './EventGroupEntry', 'underscore'], function (Collection, EventGroupEntry, _) {

	/**
  * The Event Groups associated with the board model
  */
	// Declare the class
	var EventGroups = null;
	EventGroups = Collection.extend({

		// The class of objects that this collection manages
		modelClass: EventGroupEntry,
		defaultGroupIndex: 1,
		maxGroupsPerPage: 5,
		init: function init() {
			EventGroups.inherited('init', this, arguments);
		},

		findGroup: function findGroup(widgetId) {
			return _.find(this.getModels(), function (group) {
				return group.widgetIds.indexOf(widgetId) > -1;
			});
		},

		_createGroupId: function _createGroupId(pageId, groupIndex) {
			return pageId + ':' + groupIndex;
		},

		_nextGroupIndex: function _nextGroupIndex(pageId) {
			var groups = _.filter(this.models, function (model) {
				return model.id.indexOf(pageId + ':') === 0;
			});
			return groups.length + 1;
		},

		getNumberOfGroups: function getNumberOfGroups(pageId) {
			var groups = _.filter(this.models, function (model) {
				return model.id.indexOf(pageId + ':') === 0;
			});
			return groups.length;
		},

		getDefaultGroup: function getDefaultGroup(pageId, options) {
			var defaultGroupId = this.createDefaultGroupId(pageId);
			if (!this.get(defaultGroupId)) {
				this.add([{
					id: defaultGroupId,
					widgetIds: []
				}], this._createTransactionOptions(options));
			}
			return this.get(defaultGroupId);
		},

		getGroupsOnPage: function getGroupsOnPage(pageId) {
			var groups = _.filter(this.models, function (model) {
				return model.id.indexOf(pageId + ':') === 0;
			});
			return groups;
		},

		_createGroup: function _createGroup(pageId, options) {
			var id = this._createGroupId(pageId, this._nextGroupIndex(pageId));
			this.add([{
				id: id,
				widgetIds: []
			}], this._createTransactionOptions(options));
			return this.get(id);
		},

		//remove the widgets from their current group, destroy the group if empty and relabel the groups
		removeWidgetsFromGroup: function removeWidgetsFromGroup(widgetIds, options) {
			var oldGroup;
			widgetIds.forEach(function (element) {
				oldGroup = this.findGroup(element);
				if (oldGroup) {
					if (oldGroup.widgetIds.length === 1) {
						// simply remove the entire group if the widget is the only widget in the group to avoid two events
						// destroy group and relabel the groups (e.g. 1, 3,4,5 => 1,2,3,4 )
						this._destroyGroupAndRelabel(oldGroup, this._createTransactionOptions(options));
					} else {
						// just remove the widget from the group
						oldGroup.removeWidget(element, this._createTransactionOptions(options));
					}
				}
			}.bind(this));
		},

		_addWidgetsToGroup: function _addWidgetsToGroup(widgetIds, group, options) {
			widgetIds.forEach(function (element) {
				group.addWidget(element, this._createTransactionOptions(options));
			}.bind(this));
		},

		_destroyGroupAndRelabel: function _destroyGroupAndRelabel(group, options) {
			this.remove(group, this._createTransactionOptions(options));
			//relabel
			var indexMap = {};
			var temp = [];
			var groups = this.getModels();
			groups.forEach(function (element) {
				var pageId = element.getPageId();
				if (indexMap[pageId]) {
					indexMap[pageId]++;
				} else {
					indexMap[pageId] = 1;
				}
				element.setGroupIndex(indexMap[pageId], this._createTransactionOptions(options));
				temp.push(element);
			}.bind(this));

			this.reset(temp, this._createTransactionOptions(options));
		},

		canCreateGroup: function canCreateGroup(pageId) {
			return this.get(pageId + ':' + this.maxGroupsPerPage) ? false : true;
		},

		//removes the widgets from their old group and creates a new group containing the widgets
		//The target page for the new group is either derived from the page of the first widget or via the targetPageId option.
		createGroup: function createGroup(widgetIds, options) {
			options = options || {};
			var pageId = options.targetPageId || this.findGroup(widgetIds[0]).getPageId();
			this.removeWidgetsFromGroup(widgetIds, options);
			var newGroup = this._createGroup(pageId, options);
			this._addWidgetsToGroup(widgetIds, newGroup, options);
			return newGroup;
		},

		//remove the widgets from their old group and add them to another existing group
		addToGroup: function addToGroup(groupId, widgetIds, options) {
			var group = this.get(groupId);
			widgetIds = widgetIds.filter(function (id) {
				return group.widgetIds.indexOf(id) === -1;
			});
			this.removeWidgetsFromGroup(widgetIds, options);
			this._addWidgetsToGroup(widgetIds, group, options);
		},

		//remove the widgets from their old group and add them to their own individual group
		disconnectFromGroup: function disconnectFromGroup(widgetIds, options) {
			var _this = this;

			var pageId = this.findGroup(widgetIds[0]).getPageId();
			this.removeWidgetsFromGroup(widgetIds, options);
			return widgetIds.map(function (element) {
				var group = _this._createGroup(pageId, options);
				_this._addWidgetsToGroup([element], group, options);
				return group;
			});
		},

		_createTransactionOptions: function _createTransactionOptions(options) {
			return options ? options.payloadData ? {
				payloadData: options.payloadData,
				sender: !options.sender ? this : options.sender
			} : {
				sender: this
			} : null;
		},

		createDefaultGroupId: function createDefaultGroupId(pageId) {
			return this._createGroupId(pageId, this.defaultGroupIndex);
		}
	});

	return EventGroups;
});
//# sourceMappingURL=EventGroups.js.map