package primes

// Iterator represents an iterator for iterating over numbers (prime numbers).
type Iterator interface {
	Next() bool
	Get() int64
	GoTo(p int64) bool
	Nth() int
}

// NewIterator creates a new iterator for prime numbers (uses a default cache).
func NewIterator() Iterator {
	return &iterator{primes, -1}
}

// NewIteratorFromCache creates a new iterator for prime numbers and specifies the cache to use.
func NewIteratorFromCache(c Cache) Iterator {
	return &iterator{c, -1}
}

type iterator struct {
	cache  Cache
	offset int
}

func (i *iterator) Next() bool {
	i.offset++
	return true
}

func (i *iterator) GoTo(p int64) bool {
	i.offset = i.cache.OffsetOfPrime(p)
	return true
}

func (i *iterator) Get() int64 {
	return i.cache.Prime(i.Nth())
}

func (i *iterator) Nth() int {
	return i.offset + 1
}