<?php

namespace app\commands\helpers;

/**
 * Helper trait for drawing a progress spinner onto the screen.
 * 
 * @author  Gareth Palmer <gareth@one-space.co.za>
 */

trait Spinner {

    /**
     * The total number of items the task will process.
     * 
     * @var int $spinnerTotal
     * 
     * @access  private
     */

    private int $spinnerTotal;


    /**
     * Sets the total the spinner needs for user feedback.
     * 
     * @var int $spinnerTotal   The total entries the spinner will spin over
     * 
     * @access  protected
     */

    protected function initSpinner(int $spinnerTotal): void {
        $this->spinnerTotal = $spinnerTotal;
    }


    /**
     * Updates and draws the progress onto the screen.
     * 
     * If `$this->spinnerTotal` is not set, only the spinner is shown, 
     * otherwise a message `Processing: x / y` will also be shown.
     * 
     * @param   int $index  The position within the loop which determines the state of the spinner.
     * 
     * @access  protected
     */

    protected function spinnerNext(int $index): void {
        if (!isset($this->spinnerTotal)) {
            echo sprintf("\r%s", $this->getSpinnerState($index % 4));
        } else {
            echo sprintf("\rProcessing: %d / %d complete [%s]", $index, $this->spinnerTotal, $this->getSpinnerState($index % 4));
        }
    }


    /**
     * Returns the actual spinner characted according to the index.
     * 
     * @param   int $index  The position within the loop which determines the state of the spinner.
     * 
     * @return  string  One of the following: `|`, `\`, `-` or `/`.
     * 
     * @access  public
     */

    private function getSpinnerState(int $index): string {
        $spinnerState = ['|', '\\', '-', '/'];
        return $spinnerState[$index % 4];
    }
}
