#!/usr/local/bin/guile-oops \
-e main -s
!#

(use-modules (oop goops))

(define-method (print-bool (b <;boolean>))
  (display (if b "true\n" "false\n")))


(define-class <;toggle> ()
  (state #:getter value? #:init-keyword #:state))

(define-class <;nth-toggle> (<toggle>)
  (count-max #:init-keyword #:count-max)
  (counter #:init-value 0))


(define-method (value? (t <;toggle>)) (slot-ref t 'state))

(define-method (activate! (t <;toggle>))
  (slot-set! t 'state (not (slot-ref t 'state)))
  t)

(define-method (activate! (n-t <;nth-toggle>))
  (let ((counter (+ 1 (slot-ref n-t 'counter))))
    (slot-set! n-t 'counter counter)
    (if (>;= counter (slot-ref n-t 'count-max))
    (begin (slot-set! n-t 'state (not (slot-ref n-t 'state)))
           (slot-set! n-t 'counter 0)))
    n-t))


(define-method (main (args <;list>))
  (let ((n (or (and (= (length args) 2) (string->;number (cadr args))) 1)))
    (let ((tog (make <;toggle> #:state #t)))
      (do ((i 0 (+ i 1))) ((= i 5))
    (print-bool (value? (activate! tog)))))
    (do ((i 0 (+ i 1))) ((= i n))
      (make <;toggle> #:state #t))
    (newline)
    (let ((ntog (make <;nth-toggle> #:state #t #:count-max 3)))
      (do ((i 0 (+ i 1))) ((= i 8))
    (print-bool (value? (activate! ntog)))))
    (do ((i 0 (+ i 1))) ((= i n))
      (make <;nth-toggle> #:state #t #:count-max 3))))