(asdf:load-system :webthiteth)
(asdf:load-system :herbie-utility)

(use-package :utils)

(defun date (start end)
 (format nil "~A/~A" start end))

(defun gpa (gpa bounds)
 (format nil "~A/~A" gpa bounds))

(defun education (&key school location start end degree majorgpa totalgpa)
 (let
  ((locationtext (format nil "~A: ~A - ~A" location start end))
   ;(majortext (format nil "~A Major GPA" majorgpa))
   ;(totaltext (format nil "~A Total GPA" totalgpa))
   )
  `((h1 "Education")
    (hr :align "left")
    (div :style-float "right"
     ,locationtext
     (br)
     ,degree
     ;(br)
     ;,majortext
     ;(br)
     ;,totaltext
     )
    ,school
    (div :style-clear "both"))))

(defun skills (skill-list)
 `((h1 "Relevant Skills")
   (hr :align "left")
   (table
    ,@(utils:mapit
      `(tr :valign "top"
        (td ,(handle-desc-element (car it)))
        (td :width "50%"
            ,@(if (listp (cadr it))
                  (utils:mapit `(,it (br)) (cadr it))
                  (list (cadr it)))))
      skill-list))))

(defun handle-desc-list (list)
 `(ul ,@(utils:mapit `(li ,(handle-desc-element it)) list)))

(defun handle-paragraph-element (p-elem)
 (cond
  ((stringp p-elem) p-elem)
  ((and (listp p-elem) (eql (car p-elem) 'bold)) `(span :style-font-weight "bold" ,(cadr p-elem)))
  ((and (listp p-elem) (eql (car p-elem) 'invisible)) `(span :style-color "white" ,(cadr p-elem)))))

(defun handle-paragraph (paragraph)
 (mapcar #'handle-paragraph-element paragraph))

(defun handle-desc-element (desc-element)
 (cond
  ((stringp desc-element) desc-element)
  ((and (listp desc-element) (eql 'list (car desc-element)))
   (handle-desc-list (cdr desc-element)))
  ((listp desc-element) (handle-paragraph desc-element))))

(defun print-description (description)
 (mapcar #'handle-desc-element description))

(defun pos (&key position start end description one-line)
 `(div
   (span :style-font-weight "bold" ,position) " (" ,start " - " ,(or end "Present") ")"
   ,(if one-line (print-description description) `(div :style-margin-left 20 ,(print-description description)))))

(defun all-work (work)
 `((h1 "Work Experience")
   (hr :align "left")
   ,@work))

(defun work (&key company positions)
 `(div
   (h2 ,company)
   (div :style-margin-left 20
    ,@positions)
   (br)))

(defun all-oss (oss-projs)
 `((h1 "Open Source Projects")
   (hr :align "left")
   ,@oss-projs))

(defun oss-proj (&key project project-desc project-website role start end)
 `(div
   (h2 ,project " (" ,project-website ")")
   (div :style-margin-left "20px" (span :style-font-weight "bold" ,role) " (" ,start " - " ,(or end "Present") ")"
    (div :style-margin-left "20px"
     ,(print-description project-desc)))))

(defun build-css ()
 '((body nil :font-size "90%" :font-family "Book Antiqua")
   (table nil :font-size "100%")
   (hr nil :width "50%" :margin-top 2 :margin-bottom 2)
   (p nil :margin-top 0 :margin-bottom 0)
   (ul nil :margin-top 0 :margin-bottom 0)
   (h1 nil :font-size "120%" :margin-top 0 :margin-bottom 0)
   (h2 nil :font-size "110%" :margin-top 0 :margin-bottom 0)))

(defun resume (&key name email phone addr1 addr2 education skills work oss)
 `(html
   (head
    (title ,name)
    (style ,(build-css)))
   (body
    (div
     (center (span :style-font-weight "bold" ,(format nil "~:@(~A~)" name)))
     (div :style-float "right" :style-text-align "right" ,addr1 (br) ,addr2)
     (div ,email (br) ,phone)
     (br)
     ,education
     (br)
     ,skills
     (br)
     ,(all-work work)
     ,(all-oss oss)))))

(defun dump-to-html (resume-file out-file)
 (with-open-file (out out-file :direction :output :if-exists :supersede)
  (with-open-file (in resume-file)
   (format out "~A" (webthiteth::list-to-html-pretty (eval (read in)))))))