(in-package :com.tee-it-up-golf.web)

;; Application

(defclass golf-frontend-application (golf-application)
  ())

(defcomponent show-previewer (show-viewer)
  ((preview-length :initform nil
		   :initarg :preview-length
		   :accessor preview-length)))

(defmethod render-item ((viewer show-previewer) (show radio-show))
  (<:h1 (<:as-html (show-title show)))
  (<:h2 (<:as-html (date-string (show-date show))))
  (let* ((transcript (transcript show))
	 (length (if (and (preview-length viewer)
			  (> (length transcript)  (preview-length viewer)))
		     (preview-length viewer)
		     (length transcript))))
    (<:p (<:as-html (subseq transcript 0 length))
	 (if (> (length transcript) length) (<:as-html "...")))))

(defmethod render-controls ((viewer show-previewer))
  (let ((show (viewer-item viewer))
	(self (parent viewer))) ; evil, I know
    (when show
      (component-controls ("View" (call 'frontend-show-viewer :item show))))))

(defcomponent frontend-show-viewer (full-show-viewer)
  ((player :component (flowplayer-component
		       :auto-play nil
		       :video-height 0
		       :player-width 300
		       :skin-config '((:control-bar-background-color . "0xBBBBBB")
				      (:show-menu . nil)
				      (:show-full-screen-button . nil)))
	   :accessor viewer-player)))

(defmethod render-item :after ((self frontend-show-viewer) show)
  (when (audio-data show)
    (setf (playlist (viewer-player self))
	  `((:url ,(ucw-core::action-href-body (:with-call/cc t)
					       (play-file self show))
		  :name "show"
		  :type "mp3")))
    (render (viewer-player self))))

(defcomponent frontend-show-chooser (ranged-show-chooser)
  ()
  (:default-initargs :viewer-class 'frontend-show-viewer))

(defcomponent archive-show-chooser (frontend-show-chooser
				    standard-ranged-show-list)
  ())


(defmethod render-item-for-select ((self frontend-show-chooser) (show radio-show))
  (with-slots (full-viewer-class) self
    (cross-component-link
     (yaclml:with-yaclml-output-to-string (render-item-in-select self))
     (ucw-core::make-action-body (:with-call/cc t)
       (call full-viewer-class :item show))
     self)))

(defmethod render-controls ((self frontend-show-chooser))
  (declare (ignore self)))

(defmethod update-url ((component frontend-show-chooser) url)
  (if-bind date (show-date (viewer-item component))
    (multiple-value-bind (s m h day month year) (decode-universal-time date)
      (declare (ignore s m h))
      (setf (ucw-core::uri.path url)
	    (format nil "/archive/~D/~D/~D" year month day))))
  url)

(defcomponent sidebar-show-chooser (frontend-show-chooser)
  ()
  (:default-initargs :viewer-class 'frontend-show-viewer))

(defmethod render-item-for-select ((self sidebar-show-chooser) (show radio-show))
  (let ((show (viewer-item self))
	(parent (parent self)))
    (<:h1 :class "date" (<:as-html (date-string-brief (show-date show))))
    (<:h1
     (let ((full-viewer (make-instance (slot-value self 'full-viewer-class)
				       :item show)))
       (cross-component-link (show-title show)
			     (ucw-core::make-action-body (:with-call/cc t
						)
			       (call-component parent full-viewer))
			     self)))))

(defmethod render-controls ((self sidebar-show-chooser))
  (declare (ignore self)))

(defcontainer next-last-show-previews (composite-component)
  (last-show show-previewer
	     :preview-length 200
	     :item (car (get-shows-by 'show-date nil (get-universal-time)
				      :from-end t :limit 1)))
  (next-show show-previewer
	     :preview-length 200
	     :item (car (get-shows-by 'show-date (get-universal-time) nil
				      :limit 1))))

(defcontainer golf-frontend-components (composite-component)
  (chooser sidebar-show-chooser
	   :reverse t :window-size 10 :max (get-universal-time))
  (show-previews next-last-show-previews))

(defmethod render ((self next-last-show-previews))
  (with-assoc (last-show next-show) (container.contents self)
    (<:div :class "last-show" (render last-show))
    (<:div :class "next-show" (render next-show))
    (<:div :style "clear: both" (<:as-html " "))))

(defmethod render ((self golf-frontend-components))
  (with-assoc (chooser show-previews) (container.contents self)
    (<:div :class "left-sidebar"
	   (render chooser))
    (render show-previews)
    (<:div :class "right-sidebar")
    (<:div :style "clear: both")))

(defcomponent golf-frontend-window (golf-window)
  ()
  (:default-initargs
      :body (make-instance 'tabbed-pane
			   :css-class "golf-frontend-pane"
			   :current-component-key 'main
			   :remember-selected-child t
			   :contents
			   `((main . ,(make-instance 'golf-frontend-components))
			     (archive . ,(make-instance 'archive-show-chooser))))))

(defmethod update-url ((c golf-frontend-window) url)
  (setf (ucw-core::uri.path url) "/index.ucw")
  url)

(defmethod render-html-body :before ((window golf-frontend-window))
  (<:div :class "header"
	 (<:h1 "Tee It Up Golf")))