define('application/widgets/guide/horizontalcarousel', [
'rofl/lib/utils',
'rofl/widgets/carousel',
'antie/widgets/carousel/keyhandlers/activatefirsthandler',
'application/widgets/carousel/strips/culling',
'antie/runtimecontext',
'application/formatters/guide',
'application/utils',
'application/widgets/guide/nextdayasset',
'application/widgets/guide/prevdayasset',
'application/widgets/guide/horizontalcarouselaligner'
], function (
Utils,
Carousel,
KeyHandler,
CullingStrip,
RuntimeContext,
Formatter,
AppUtils,
NextDayAsset,
PrevDayAsset,
HorizontalCarouselAligner
) {
'use strict';
var application = RuntimeContext.getCurrentApplication(),
carousels = application.getLayout().guide;
return Carousel.extend({
/**
* Initialises the button.
*
* @param {Object} items - Items.
* @param {number} day - Selected day filter index.
* @param {Date} filterData - Filter date object.
* @param {Array} daysArray - Days array..
*/
init: function init (items, day, filterData, daysArray) {
init.base.call(this, '', Carousel.orientations.HORIZONTAL);
this.addClass('carousel-row');
this._startTimes = [];
this._endTimes = [];
this._hasPreviousDay = null;
this._hasNextDay = null;
this.setContinuousListener(true);
this._buildCarousel(items, day, filterData, daysArray);
},
/**
* Builds the carousel.
*
* @private
* @param {Object} items - Items.
* @param {number} day - Selected day filter index.
* @param {Date} filterData - Filter date object.
* @param {Array} daysArray - Days array.
*/
_buildCarousel: function (items, day, filterData, daysArray) {
var keyHandler = new KeyHandler(),
formatter = new Formatter(),
nextDayButton = new NextDayAsset(),
prevDayButton = new PrevDayAsset(),
self = this,
filterTime = filterData.getTime() / 1000,
aligner = new HorizontalCarouselAligner(this.getMask()),
highestDayIndex = daysArray.length,
itemStartTime;
this.setWidgetStrip(CullingStrip);
keyHandler.setAnimationOptions({
duration: 300,
easing: 'easeInOut',
fps: 60,
skipAnim: false
});
keyHandler.attach(this);
this.setMaskLength(carousels.maskLength);
aligner.setNumberOfItemsVisibleOnScreen(4);
this.setWidgetLengths(carousels.carousels.widgetLength);
this.setAligner(aligner);
if (day > 0) {
this._hasPreviousDay = true;
if (daysArray.length && day > 0) {
prevDayButton.setDate(daysArray[day - 1]);
}
self.append(prevDayButton, carousels.carousels.widgetLength);
}
Utils.each(items, function (item) {
itemStartTime = item.getStartTime();
if ((itemStartTime >= filterTime && itemStartTime !== this._lastStartTime) || items.length === 1) {
this._lastStartTime = itemStartTime;
this._setItem(item);
this.append(formatter.format(item), carousels.carousels.widgetLength);
}
}, this);
if (day < (highestDayIndex - 1)) {
this._hasNextDay = true;
if (daysArray.length && day < daysArray.length) {
nextDayButton.setDate(daysArray[day + 1]);
}
self.append(nextDayButton, carousels.carousels.widgetLength);
}
},
/**
* Sets carousel item.
*
* @private
* @param {Object} item - Items.
*/
_setItem: function (item) {
var start = item.getStartTime() * 1000,
end = item.getEndTime() * 1000,
now = application.getDate().getTime(),
index = this._index || 1,
channelId = this._channelId || null;
if (channelId === null) {
this._channelId = item.getChannelId();
}
if (start <= now && now <= end) {
this._nowIndex = index;
}
this._startTimes.push(start);
this._endTimes.push(end);
this._lastIndex = index;
this._index = index + 1;
},
/**
* Executes a manual align to index.
*
* @param {number} index - The index.
* @param {Object} opts - Options.
*/
manualAlignToIndex: function (index, opts) {
var widgetCount = this.getChildWidgetCount(),
threshold = 3, // 4 items fit on screen, so stop scrolling when the max is already on screen.
maxManualIndex = widgetCount - threshold - 1; // Remove one because of index zero based.
if (index > maxManualIndex) {
index = maxManualIndex;
}
if (index < 0) {
index = 0;
}
this.alignToIndex(index, opts);
},
/**
* Aligns the carousel to a specific index.
*
* @param {number} index - The index.
* @param {Object} [options] - The alignment options.
*/
alignToIndex: function alignToIndex (index, options) {
this.activated = true;
if (this._delayedIndex) {
index = this._delayedIndex;
} else if (this._delayedTime) {
index = this._getIndex(this._delayedTime);
if (this._delayedPosition) {
index = index - this._delayedPosition;
}
}
this._delayedTime = null;
this._delayedIndex = null;
this._delayedPosition = null;
if (index < 0) {
index = 0;
}
if (this.outputElement &&
(!this.outputElement.parentElement || !this.outputElement.parentElement.parentElement)) {
options = options || {};
options.skipAnim = true;
}
alignToIndex.base.call(this, index, options);
},
/**
* Aligns the carousel to a specific time of day.
*
* @param {string|number} time - The time.
* @param {Object} [options] - The alignment options.
* @param {number} [position] - The carousel position.
*/
alignToTimeOfDay: function (time, options, position) {
var index;
position = position || 0;
if (this.outputElement) {
index = this._getIndex(time);
this._delayedTime = null;
this._delayedIndex = null;
this.alignToIndex(index - position, options);
} else {
this._delayedIndex = null;
this._delayedTime = time;
this._delayedPosition = position;
}
},
/**
* Aligns the carousel to a position.
*
* @param {number} position - Position 0 for the start, 1 for the end.
* @param {Object} [options] - The alignment options.
*/
alignToPosition: function (position, options) {
var index;
if (position === 0) {
index = 0;
} else {
index = this.getChildWidgetCount() - 1;
}
this._delayedTime = null;
this._delayedIndex = index;
if (this.outputElement) {
this._delayedIndex = null;
this.alignToIndex(index, options);
}
},
/**
* Returns active asset in carousel.
*
* @returns {Object} Active widget.
*/
getCarouselActiveAsset: function () {
return this.getMask().getWidgetStrip().getActiveChildWidget();
},
/**
* Returns the item index for the given time.
*
* @param {string|number} time - The time.
* @returns {number} - The index.
* @private
*/
_getIndex: function (time) {
var index;
if (time === '_nowIndex') {
index = this._nowIndex;
} else {
index = this._getEndIndex(time);
if (index <= 0) {
index = 1;
}
}
return index || 0;
},
/**
* Returns the start index.
*
* @param {number} time - The time.
* @returns {number} - The current time index.
* @private
*/
_getStartIndex: function (time) {
var startTimes = this._startTimes,
filtered,
index;
filtered = Utils.filter(startTimes, function (current) {
return current >= time;
});
if (filtered.length) {
index = startTimes.indexOf(filtered[0]);
if (this._hasPreviousDay) {
index = index + 1;
}
} else {
index = this.getChildWidgetCount() - 1;
if (this._hasNextDay) {
index = index - 1;
}
}
return index;
},
/**
* Returns the end index.
*
* @param {number} time - The time.
* @returns {number} - The current time index.
* @private
*/
_getEndIndex: function (time) {
var endTimes = this._endTimes,
filtered,
index;
filtered = Utils.filter(endTimes, function (current) {
return current > time;
});
if (filtered.length) {
index = endTimes.indexOf(filtered[0]);
if (this._hasPreviousDay) {
index = index + 1;
}
} else {
index = this.getChildWidgetCount() - 1;
if (this._hasNextDay) {
index = index - 1;
}
}
return index;
},
/**
* Activates the last item in the row.
*
* @param {Object} animOptions - The animation options.
*/
activateLast: function (animOptions) {
var last = this.getChildWidgetCount() - 1;
if (this._hasNextDay) {
last = last - 1;
}
if (this.outputElement) {
this.alignToIndex(last, animOptions);
this.setActiveIndex(last);
} else {
this._delayedIndex = last;
}
},
/**
* Returns the index from left.
*
* @returns {number} - The left index.
*/
getFromLeftIndex: function () {
var widgetStrip = this.getMask().getWidgetStrip(),
activeIndex = this.getActiveIndex(),
positionFromLeft = widgetStrip.getLengthToIndex(activeIndex),
widgetSize = widgetStrip.lengthOfWidgetAtIndex(activeIndex),
index;
index = positionFromLeft / widgetSize;
return index;
}
});
});