;;; Program:
;;;   dvdweb.ss
;;; Author:
;;;   Samuel A. Rebelsky
;;; Version:
;;;   1.1 of February 2001
;;; Summary:
;;;   A sample web interface for the procedures and stuff
;;;   in dvds.ss.
;;; Valid CGI Variables (and legal values):
;;;   operation
;;;     "" - no operation requested (yet)
;;;     "title" - search the list of DVDs for a particular title
;;;     "genre" - search the list of DVDS for a particular genre
;;;     "studio" - search the list of DVDS for a particular studio
;;;   title
;;;     used only when operation is "title"
;;;   genre
;;;     used only when operation is "genre"
;;;   studio
;;;     used only when operation is "studio"
;;; Contents:
;;;   Local Helpers
;;;     (search-forms)
;;;       Generate HTML for the "search DVDs" forms common to
;;;       every page.
;;;     (basic-page)
;;;       Build the initial search page, without any results.
;;;     (error-page)
;;;       Build a page that reports on errors.  I hope that
;;;       this never happens.
;;;     (search-title-page title)
;;;       Build a page that reports on the results for a particular
;;;       title.
;;;     (search-title-page-helper title search-result)
;;;       Where the page generation for the previous procedure happens.
;;;     (search-genre-page genre)
;;;       Build a page that reports on the results of a search
;;;       for a particular genre.  
;;;     (search-genre-page-helper genre results)
;;;       Where the page generation for the previous procedure happens.
;;;     (search-studio-page studio)
;;;       Build a page that reports on the results of a search
;;;       for a particular studio.  
;;;     (search-studio-page-helper studio results)
;;;       Where the page generation for the previous procedure happens.
;;;   Local Variables
;;;     operation
;;;       The operation selected on the CGI page.
;;;   Primary Procedure
;;;     (page)
;;;       Build an HTML page that either has the results of a
;;;       search or a new search page.
;;; History:
;;;   Thursday, 15 February 2001 [Version 1.0]
;;;     Created.
;;;   Wednesday, 21 February 2001 [Version 1.1]
;;;     Some cleanup: Moved some generic procedures to
;;;     webutils.ss (like I planned a week ago).  Added the table
;;;     of contents.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Required Libraries

; Since we're building Web pages, we might as well rely on
; my favorite (and growing) set of helper procedures.
(load "/home/rebelsky/Web/Scheme/webutils.ss")
; Here's the stuff that does the hard work for dealing with
; DVDs.  Note that we rely on sample-dvds for much of our work.
(load "dvds.ss")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Helper Procedures

;;; Procedure:
;;;   search-forms
;;; Parameters:
;;;   None
;;; Purpose:
;;;   Build HTML for all the search forms we need.
;;; Produces:
;;;   A string.
;;; Preconditions:
;;;   None.
;;; Postconditions:
;;;   Returns valid HTML.
(define search-forms
  (lambda ()
    (string-append
     (form "dvdweb.cgi" "Search for Title"
           (string-append
            (hidden "operation" "title")
            "Title: " (string #\newline)
            (textfield "title" "")))
     (form "dvdweb.cgi" "Search for Studio"
           (string-append
            (hidden "operation" "studio")
            "Movie Studio: " (string #\newline)
            (textfield "studio" "")))
     (form "dvdweb.cgi" "Search for Genre"
           (string-append
            (hidden "operation" "genre")
            "Genre: " (string #\newline)
            (textfield "genre" ""))))))

;;; Procedure:
;;;   basic-page
;;; Parameters:
;;;   None.
;;; Purpose:
;;;   Creates a basic search page (with no results).
;;; Produces:
;;;   page, a string
;;; Preconditions:
;;;   None.
;;; Postconditions:
;;;   Returns a complete valid HTML page
(define basic-page
  (lambda ()
    (make-page 
     (head "Search DVDs")
     (body (string-append
            (paragraph "Search a sample collection of DVDs")
            (search-forms))))))

;;; Procedure:
;;;   error-page
;;; Parameters:
;;;   None.
;;; Purpose:
;;;   Creates an error page.
;;; Produces:
;;;   page, a string
;;; Preconditions:
;;;   None.
;;; Postconditions:
;;;   Returns a complete valid HTML page
(define error-page
  (lambda ()
    (make-page 
     (head "Error!")
     (body (string-append
            (paragraph "Something went horribly wrong.")
            (paragraph "It's probably your fault.")
            (paragraph "But we can pretend it didn't happen.  So ... try again.")
            (search-forms))))))

;;; Procedure:
;;;   search-title-page
;;; Parameters:
;;;   The title of a DVD.
;;; Purpose:
;;;   Generates a page to report on the results of a search
;;;   for that DVD.
;;; Produces:
;;;   page, a string
;;; Preconditions:
;;;   title must be a string
;;;   variable sample-cds must be defined (presumably in dvds.ss).
;;; Postconditions:
;;;   Returns valid HTML for the search result.
(define search-title-page
  (lambda (title)
    (search-title-page-helper title
                              (find-dvd-by-title title sample-dvds))))

;;; Helper:
;;;   search-title-page-helper
;;; Parameters:
;;;   The title of a DVD that was searched for.
;;;   The result of a search: not found or a DVD entry.
;;; Purpose:
;;;   Displays the result as a page.
(define search-title-page-helper
  (lambda (title search-result)
    (if search-result
        (make-page 
         (head (string-append "Search for " title))
         (body (string-append (paragraph "I found")
                              (dvd->html search-result)
                              (search-forms))))
        (make-page
         (head "Search Failed")
         (body (string-append
                (paragraph (string-append "Could not find " title "."))
                (search-forms)))))))

;;; Procedure:
;;;   search-genre-page
;;; Parameters:
;;;   A film genre (animated, childrens, etc.)
;;; Purpose:
;;;   Generates a page to report on the results of a search
;;;   for DVDs in that genre.
;;; Produces:
;;;   page, a string
;;; Preconditions:
;;;   title must be a string
;;;   variable sample-cds must be defined (presumably in dvds.ss).
;;; Postconditions:
;;;   Returns valid HTML for the search result.
(define search-genre-page
  (lambda (genre)
    (search-genre-page-helper genre
                              (find-dvds-by-genre genre sample-dvds))))

;;; Helper:
;;;   search-genre-page-helper
;;; Parameters:
;;;   A genre.
;;;   The result of a search: a possibly-empty list of DVD entries.
;;; Purpose:
;;;   Displays the result as a page.
(define search-genre-page-helper
  (lambda (genre search-result)
    (if (not (null? search-result))
        (make-page 
         (head (string-append "Search for genre " genre))
         (body (string-append (paragraph "I found")
                              (dvds->html search-result)
                              (search-forms))))
        (make-page
         (head "Search Failed")
         (body (string-append
                (paragraph 
                 (string-append "No movies appear to be in genre " 
                                genre "."))
                (search-forms)))))))

;;; Procedure:
;;;   search-studio-page
;;; Parameters:
;;;   A film studio (Disney, Dreamworks, etc.)
;;; Purpose:
;;;   Generates a page to report on the results of a search
;;;   for DVDs from that studio.
;;; Produces:
;;;   page, a string
;;; Preconditions:
;;;   title must be a string
;;;   variable sample-cds must be defined (presumably in dvds.ss).
;;; Postconditions:
;;;   Returns valid HTML for the search result.
(define search-studio-page
  (lambda (studio)
    (search-studio-page-helper studio
                              (find-dvds-by-studio studio sample-dvds))))

;;; Helper:
;;;   search-studio-page-helper
;;; Parameters:
;;;   The name of a studio
;;;   The result of a search: a list of DVD entries.
;;; Purpose:
;;;   Displays the result as a page.
(define search-studio-page-helper
  (lambda (studio search-result)
    (if (not (null? search-result))
        (make-page 
         (head (string-append "Search for studio " studio))
         (body (string-append (paragraph "I found")
                              (dvds->html search-result)
                              (search-forms))))
        (make-page
         (head "Search Failed")
         (body (string-append
                (paragraph 
                 (string-append "No movies appear to be from studio " 
                                studio "."))
                (search-forms)))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Primary Procedure

;;; Value:
;;;   operation
;;; Type:
;;;   string
;;; Purpose:
;;;   Represents the operation requested by the user.
;;;   May be: "genre", "title", "studio", or "".
;;; Default Value:
;;;   ""
(define operation
  (get-cgi-var "operation" ""))

;;; Procedure:
;;;   page
;;; Parameters:
;;;   none; all values are extracted via CGI
;;; Purpose:
;;;   Build an appropriate Web page in response to a CGI request.
;;; Produces:
;;;   page, a string
;;; Preconditions:
;;;   None.
;;; Postconditions:
;;;   Returns a string that is valid HTML for a full page.
;;;   That page should be an appropriate response to the request.
(define page
  (lambda ()
    (cond
      ((equal? operation "") (basic-page))
      ((equal? operation "title") 
       (search-title-page (get-cgi-var "title" "TITLE")))
      ((equal? operation "genre")
       (search-genre-page (get-cgi-var "genre" "GENRE")))
      ((equal? operation "studio")
       (search-studio-page (get-cgi-var "studio" "STUDIO")))
      (else (error-page)))))
               
