;; Define helper functions
(define (drop-while pred lis)
  (cond ((null? lis) lis)
        ((not (pred (car lis))) lis)
        (else (drop-while pred (cdr lis)))))

(define (take-while pred lis)
  (let loop ((lis lis) (acc '()))
    (cond ((null? lis) (reverse acc))
          ((not (pred (car lis))) (reverse acc))
          (else (loop (cdr lis) (cons (car lis) acc))))))

(define (char-other? ch)
  (not (or (= (char->integer ch) 91)
           (= (char->integer ch) 93)
           (= (char->integer ch) 40)
           (= (char->integer ch) 41)
           (= (char->integer ch) 32)
           (= (char->integer ch) 10))))

(define (process-other chars)
  (and (not (null? chars))
       (let* ((token-chars (take-while char-other? chars))
              (rest (drop-while char-other? chars)))
         (list token-chars rest))))

;; Custom function to check if all elements in a list are characters
(define (all-char? lis)
  (if (null? lis)
      #t
      (and (char? (car lis)) (all-char? (cdr lis)))))

;; Function to tag tokens with their type
(define (tag-token type value)
  (list type value))

;; Functions to take and drop elements from the list
(define (take n lis)
  (if (or (<= n 0) (null? lis))
      '()
      (cons (car lis) (take (- n 1) (cdr lis)))))

(define (drop n lis)
  (if (or (<= n 0) (null? lis))
      lis
      (drop (- n 1) (cdr lis))))

;; Functions for Dot Count
(define (process-dots chars)
  (let* ((dot-chars (take-while (lambda (ch) (char=? ch (integer->char 46))) chars))  ; char 46 is '.'
         (num-dots (length dot-chars))
         (rest (drop-while (lambda (ch) (char=? ch (integer->char 46))) chars)))
    (list num-dots rest)))

;; Define main tokenize function with integrated new functions
(define (tokenize input)
  (let loop ((chars (string->list input)) (tokens '()))
    (cond
      ((null? chars) (reverse tokens))  ; Return the reversed tokens
      ((char=? (car chars) (integer->char 91))  ; Handle opening bracket [
       (loop (cdr chars) (cons (tag-token 'open-bracket "[") tokens)))
      ((char=? (car chars) (integer->char 93))  ; Handle closing bracket ]
       (loop (cdr chars) (cons (tag-token 'close-bracket "]") tokens)))
      ((char=? (car chars) (integer->char 40))  ; Handle opening parenthesis
       (loop (cdr chars) (cons (tag-token 'open-parenthesis "(") tokens)))
      ((char=? (car chars) (integer->char 41))  ; Handle closing parenthesis
       (loop (cdr chars) (cons (tag-token 'close-parenthesis ")") tokens)))
      ((char=? (car chars) (integer->char 32))  ; Skip spaces
       (loop (cdr chars) tokens))
      ((char=? (car chars) (integer->char 46))  ; Handle dots (.)
       (let* ((result (process-dots chars))
              (num-dots (car result))
              (rest (cadr result)))
         (loop rest (cons (tag-token 'dots num-dots) tokens))))  ; Use a tagged list structure
      (else
       (let* ((result (process-other chars))
              (token (car result))
              (rest (cadr result)))
         (loop rest (cons (tag-token 'other token) tokens))))))  ); End of tokenize function

(define (simplify-for-output x) x)

;; Function to check if a token represents dots
(define (dots? x) (eq? 'dots (caar x)))

(define (dot-count x) (cadr x))

;; Function to gather up the tokens based on dots
(define (process-final tokens)
(define (process-finalz . args)
  (debug 'process-finalz args))
(process-finalz tokens))

;; DEBUG
(define (debug procedure-name args)
  (define (debug-helper args)
    (if (null? (cdr args))
      args
      (cons (car args)
        (cons '--- (debug-helper (cdr args))))))
(write (cons procedure-name (debug-helper args)))(newline)(newline))

;; Example usage
(define input "(define) for good (). 1 2")

;; Tokenize the input
(let ((tokens (tokenize input)))
  (write tokens)  ; Write the intermediate tokenized output for debugging
  (newline)(newline)
  (write (process-final tokens)))  ; Return the final processed output
