<?php
namespace nur\b\date;

use nur\b\ValueException;

/**
 * Class Delay: une durée en secondes
 *
 * l'unité pour cet objet est calculé à partir d'un objet Time référence. par
 * exemple, la méthode {@link Delay::getu()} retournera des minutes si l'heure
 * de référence est une instance de {@link Hour}
 */
class Delay extends Time {
  const WRAP = false;

  static function parse_delay($ref): array {
    $unit = static::UNIT;
    if ($ref instanceof Time) {
      $unit = $ref->UNIT();
      $seconds = $ref->getSeconds();
    } elseif ($ref === null || is_int($ref)) {
      $seconds = $ref !== null? $ref: 0;
      $seconds *= $unit;
    } elseif (is_array($ref)) {
      [$h, $m, $s] = $ref;
      $seconds = $h * 3600 + $m * 60 + $s;
    } elseif (is_string($ref) && preg_match('/^(-)?(\d+):(\d{2}):(\d{2})$/', $ref, $ms)) {
      $seconds = intval($ms[2]) * 3600 + intval($ms[3]) * 60 + intval($ms[4]);
      if ($ms[1]) $seconds = -$seconds;
    } else {
      throw ValueException::invalid_value($ref, "delay");
    }
    return [$unit, $seconds];
  }

  function UNIT(): int {
    return $this->unit;
  } protected $unit;

  function __construct($ref) {
    parent::__construct(false);
    [$unit, $seconds] = self::parse_delay($ref);
    $this->unit = $unit;
    $this->setSeconds($seconds);
  }

  function __toString(): string {
    $v = $this->seconds;
    $sign = $v < 0? "-": "";
    $v = abs($v);
    $h = intdiv($v, 3600); $v = $v % 3600;
    $m = intdiv($v, 60);
    $s = $v % 60;
    return sprintf("%s%u:%02u:%02u", $sign, $h, $m, $s);
  }

  /** créer un nouvel délai en soustrayant l'heure spécifiée à cette heure */
  function until(Time $end): Time {
    if ($this->isUndef() || $end->isUndef()) return self::undef();
    $clone = clone $this;
    $clone->setSeconds($end->getSeconds() - $clone->getSeconds());
    return $clone;
  }
}
