rackout-dvd-title.rkt
#lang racket/base
;; Copyright Neil Van Dyke.  See file "info.rkt".

;; http://www.hometheaterinfo.com/dvdlist.htm

(module+ test
  (require (planet neil/overeasy)))

(define (dvd-titlecase str)
  (string-titlecase (regexp-replace* #rx"_" str " ")))

(provide dvd-title-parse)
(define (dvd-title-parse title)
  (cond ((bytes? title) (dvd-title-parse (bytes->string/utf-8 title)))
        ((string? title)
         (let-values (((main alist)
                       (cond ((regexp-match #rx"^(.*)_[Ss]([0-9]+)_[Ds](?:[Ii][Ss][Cc])?([0-9]+)$" title)
                              => (lambda (m)
                                   (apply (lambda (whole main season disc)
                                            (values main
                                                    `((season . ,(string->number season))
                                                      (disc   . ,(string->number disc)))))
                                          m)))
                             (else (values title '())))))
           ;; TODO: Separate out "The"?
           (values (dvd-titlecase main)
                   alist)))
        (else (raise-argument-error 'dvd-title-parse
                                    "(or/c string? bytes?)"
                                    title))))

(module+ test
  
  (test (dvd-title-parse "WEST_WING_S1_D2")
        (values "West Wing" '((season . 1) (disc . 2))))
  
  (test (dvd-title-parse "POWER YOGA TOTAL BODY")
        (values "Power Yoga Total Body" '()))
  
   (test (dvd-title-parse "GAME_OF_THRONES_S1_DISC5")
         (values "Game Of Thrones" '((season . 1) (disc . 5)))))
                
(provide dvd-title-pretty)
(define (dvd-title-pretty title)
  (let-values (((main alist) (dvd-title-parse title)))
    (if (null? alist)
        main
        (let ((os (open-output-string)))
          (write-string main os)
          (for-each (lambda (pair)
                      (write-string ", " os)
                      (write-string (hash-ref #hasheq((disc   . "Disc")
                                                      (season . "Season"))
                                              ;; TODO: Error check?
                                              (car pair))
                                    os)
                      (write-char #\space os)
                      (display (cdr pair) os))
                    alist)
          (get-output-string os)))))

(module+ test
  
  (test (dvd-title-pretty "WEST_WING_S1_D2")
        "West Wing, Season 1, Disc 2")
  
  (test (dvd-title-pretty "POWER YOGA TOTAL BODY")
        "Power Yoga Total Body")

  (test (dvd-title-pretty "GAME_OF_THRONES_S1_DISC5")
        "Game Of Thrones, Season 1, Disc 5"))

;; "MGGEU6LF10" -> "Midnight in the Garden of Good and Evil"
;;
;; "Quinceanera" -> "Quince\u00d1nera"
;;
;; "WHOLPHIN_NO9" -> "Wholphin No. 9"
;;
;; "FADE_TO_BLACK" -> "Jay-Z in Fade to Black"