// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.

// it-range.go
package expr

import "io"

type RangeIterator struct {
	start   int64
	end     int64
	step    int64
	current int64
	index   int
}

func NewRangeIterator(start, end, step int64) *RangeIterator {
	if step == 0 {
		panic("Range step must be not zero")
	}
	if step < 0 && start < end {
		panic("When the range's step is less than zero, start must be greater than end")
	}
	if step > 0 && start > end {
		panic("When the range's step is greater than zero, start must be less than end")
	}
	return &RangeIterator{start: start, end: end, step: step, current: start, index: 0}
}

func (it *RangeIterator) Reset() {
	it.index = 0
	it.current = it.start
}

func (it *RangeIterator) Next() (item any, err error) {
	if it.step > 0 {
		if it.current < it.end {
			item = it.current
			it.current += it.step
			it.index++
		} else {
			err = io.EOF
		}
	} else {
		if it.current > it.end {
			item = it.current
			it.current += it.step
			it.index++
		} else {
			err = io.EOF
		}
	}
	return
}

func (it *RangeIterator) Index() int {
	return it.index - 1
}