(in-package :cl-blog)

(define-form entry ()
  ((entry :edit)
   (title :create :edit)
   (category :create :edit)
   (contents :create :edit)))

(define-class-gate-form-field (entry entry :edit) hidden-form-field blog-entry :key-slot-type integer)
(define-form-field (entry title :create :edit) form-field
  :string-acceptor #'nonempty-string-validator)
(define-form-field (entry category :create :edit) selector-form-field
  :allowed-values-generator (lambda () *categories*))
(define-form-field (entry contents :create :edit) textarea-form-field
  :string-acceptor #'nonempty-string-validator)

(define-form login ()
  (user password)
  (:semantic-check
   (unless (authenticate-user-from-name-and-password (user-name user) password)
     (fail-check "Try again."))
   (when (user-disabled-p user)
     (fail-check "This user has been disabled. Sorry."))))

(define-class-gate-form-field (login user) form-field user)
(define-form-field (login password) password-form-field
  :string-acceptor #'nonempty-string-validator)

(defvar *authenticated-user*)

(define-form user ()
  ((user :edit :select :hidden-select)
   (name :create)
   (display-name :create :edit)
   (link :create :edit)
   (description :create :edit)
   (password :create :edit))
  (:semantic-check
   :edit
   (unless (or (typep *authenticated-user* 'administrator)
               (eq *authenticated-user* user))
     (fail-check "You must be this user or an administrator.")))
  (:semantic-check
   :administrator-required
   (unless (typep *authenticated-user* 'administrator)
     (fail-check "You must be an administrator."))))

(define-form-field (user name :create) form-field
  :string-acceptor (lambda (string)
                     (when (zerop (length string))
                       (fail-check "Please enter a user name."))
                     (when (find-user string)
                       (fail-check "A user with that name already exists."))))

(define-class-gate-form-field (user user :edit :hidden-select) hidden-form-field user)
(define-class-gate-form-field (user user :select) selector-form-field user)

(define-form-field (user display-name :create :edit) form-field
  :string-acceptor #'nonempty-string-validator)
(define-form-field (user link :create :edit) form-field
  :string-acceptor #'nonempty-string-validator)
(define-form-field (user description :create :edit) textarea-form-field
  :string-acceptor #'nonempty-string-validator)
(define-form-field (user password :create) password-form-field
  :string-acceptor #'nonempty-string-validator)
(define-form-field (user password :edit) password-form-field
  :value-to-string-translator (constantly ""))

(define-form reload-configuration () () (:submit-text :reload-configuration))