/**
* Iterable interface compliant class for iterating over SlideList objects.
*
* @see {@link https://www.ecma-international.org/ecma-262/6.0/#sec-iterable-interface}
*
* @memberof module:libresignage/queue
*/
class SlideListIterator {
	/**
	* Construct a SlideListIterator.
	*
	* @param {SlideList} slidelist A SlideList object to iterate over.
	* @param {boolean}   wrap      Whether to wrap at the end of the SlideList.
	* @param {number}    step      The step to use when iterating.
	* @param {number}    start_at  The starting slide index to use.
	*/
	constructor(slidelist, wrap, step, start_at) {
		this.index = 0;
		this.wrap = wrap;
		this.step = step;
		this.first = true;

		// Sort the slide array by the Slide indices.
		this.sorted = Object.values(slidelist.slides).sort(
			function(a, b) {
				if (a.get('index') < b.get('index')) {
					return -1;
				} else if (a.get('index') == b.get('index')) {
					return 0;
				} else {
					return 1;
				}
			}
		);

		// Find the Slide with index start_at.
		for (let i = 0; i < this.sorted.length; i++) {
			if (this.sorted[i].get('index') === start_at) {
				this.index = i;
			}
		}
	}

	/**
	* Iterator interface compliant next() method.
	*
	* @see {@link https://www.ecma-international.org/ecma-262/6.0/#sec-iterator-interface}
	*/
	next() {
		let ret = {done: false};

		/*
		* Don't increment the index if this is the first iteration.
		* This is required to avoid skipping the first item in the SlideList.
		*/
		if (!this.first) {
			this.index += this.step;
		} else {
			this.first = false;
		}

		if (this.index >= this.sorted.length) {
			this.index -= this.sorted.length;
			ret.done = !this.wrap;
		} else if (this.index < 0) {
			this.index += this.sorted.length;
			ret.done = !this.wrap;
		}

		ret.value = !ret.done ? this.sorted[this.index]: null;
		
		return ret;
	}

	/**
	* Set the integer step used for looping the internal Slide array.
	*
	* @param {number} step The *integer* step value.
	*/
	set_step(step) { this.step = step; }

	/**
	* Get the step used for looping the internal Slide array.
	*
	* @return {number} The step value.
	*/
	get_step() { return this.step; }
}
module.exports = SlideListIterator;
