<?php


namespace App\Tables;

/**
 * Sequential ID assigner
 */
abstract class BaseNumerator
{
    /** @var int */
    protected $next;

    /** @var int */
    protected $last;

    /**
     * BaseNumerator constructor.
     *
     * @param int|int[] $first - first index, or [first, last]
     * @param int|null $last - last index, or null
     */
    public function __construct($first, $last = null)
    {
        if (is_array($first) && $last === null) {
            list($first, $last) = $first;
        }

        $this->next = $first;
        $this->last = $last;
    }

    /**
     * Get next key, incrementing the internal state
     *
     * @return string
     */
    public function next()
    {
        if (!$this->hasMore())
            throw new \OutOfBoundsException("Column numerator has run out of allocated GCID slots");

        $key = $this->getKey($this->next);
        $this->advance();
        return $key;
    }

    /**
     * Advance to the next ID
     */
    protected function advance()
    {
        $this->next++;
    }

    /**
     * Convert numeric index to a key
     *
     * @param int $index
     * @return mixed
     */
    protected function getKey($index)
    {
        return $index; // simple default
    }

    /**
     * @return bool - true iof there are more keys available
     */
    protected function hasMore()
    {
        return $this->next <= $this->last;
    }

    /**
     * Generate all keys
     *
     * @return \Generator
     */
    public function generate()
    {
        while ($this->hasMore()) {
            yield $this->next();
        }
    }
}