define('application/widgets/carousel/horizontalcarouselaligner', [
'rofl/widgets/carousel/aligners/natural',
'antie/widgets/carousel/aligners/aligner',
'rofl/lib/utils'
], function (
NauturalAligner,
Aligner,
Utils
) {
'use strict';
return NauturalAligner.extend({
/**
* Aligns the Mask and WidgetStrip to their correct position.
*
* @param {Navigator} navigator - The carousel navigator object.
* @param {number} direction - The direction.
* Aligner.directions.FORWARD or Aligner.directions.BACKWARD.
* @param {Object} options - The animation options.
* @private
*/
_align: function (navigator, direction, options) {
var startIndex = this._mask.getWidgetStrip().getActiveChildWidgetIndex(),
targetIndex = (direction === Aligner.directions.FORWARD)
? navigator.indexAfter(startIndex)
: navigator.indexBefore(startIndex);
if (Utils.isNumber(targetIndex)) {
if (this._isWrap(startIndex, targetIndex, direction)) {
return;
}
this._doAlign(startIndex, targetIndex, options);
}
},
/**
* Executes the alignment.
*
* @param {number} startIndex - The start index.
* @param {number} targetIndex - The target index.
* @param {Object} [options] - The alignment options.
* @private
*/
_doAlign: function (startIndex, targetIndex, options) {
var mask = this._mask,
widgetStrip = mask.getWidgetStrip(),
targetDistance,
newAlignPoint,
distanceFromMask,
widgetLength;
this._informMaskBeforeAlign(targetIndex);
/*
* Calculate the virtual column position for our target based
* on the widget size and the current scroll position of the
* WidgetStrip
*/
widgetLength = widgetStrip.lengthOfWidgetAtIndex(targetIndex);
distanceFromMask = widgetStrip.getLengthToIndex(startIndex);
targetDistance = widgetStrip.getLengthToIndex(targetIndex);
if (!this._lastAlignerPoint) {
this._lastAlignerPoint = distanceFromMask;
}
if (targetIndex === 0) {
// Always align to the start position when the target is the first target.
this._scrolled = false;
newAlignPoint = 0;
mask.setAlignPoint(newAlignPoint);
} else if (targetIndex < startIndex) { // Navigating left
newAlignPoint = targetDistance;
// When we've scrolled and navigating backwards, move to the left position.
if (this._scrolled) {
newAlignPoint = newAlignPoint - widgetLength;
}
if (newAlignPoint < 0) {
newAlignPoint = 0;
}
if (this._lastAlignerPoint - newAlignPoint > widgetLength) {
newAlignPoint = this._lastAlignerPoint - widgetLength;
}
mask.setAlignPoint(newAlignPoint);
} else { // Navigating right
newAlignPoint = targetDistance;
// If we reached the end of the row, keep the same alignpoint.
if (newAlignPoint > (widgetLength * (this._itemsOnScreen - 1))) {
this._scrolled = true;
newAlignPoint = (widgetLength * (this._itemsOnScreen - 1));
}
if (newAlignPoint - this._lastAlignerPoint > widgetLength) {
newAlignPoint = this._lastAlignerPoint + widgetLength;
}
mask.setAlignPoint(newAlignPoint);
}
this._lastAlignerPoint = newAlignPoint;
this._moveNormally(targetIndex, options);
if (distanceFromMask !== newAlignPoint && newAlignPoint !== 0) {
this._informMaskAfterAlign(targetIndex);
}
},
/**
* Aligns the carousel to a specific index.
*
* @param {number} index - The index.
* @param {Object} [options] - The alignment options.
*/
alignToIndex: function alignToIndex (index, options) {
var mask = this._mask,
widgetStrip = mask.getWidgetStrip(),
widgetCount = widgetStrip.getChildWidgetCount();
if (index > widgetCount - this._itemsOnScreen) {
index = widgetCount - this._itemsOnScreen;
}
this._scrolled = true;
if (index < 0) {
index = 0;
}
this._mask.setAlignPoint(0);
this._lastAlignerPoint = 0;
alignToIndex.base.call(this, index, options);
},
/**
* Resets the aligner.
*/
reset: function () {
this._lastAlignIndex = null;
}
});
});