#lang racket
(require gigls/unsafe)
(provide (all-defined-out))

;;; File:
;;;   association-lists-lab.rkt
;;; Authors:
;;;   Janet Davis
;;;   Samuel A. Rebelsky
;;;   Jerod Weinman
;;;   YOUR NAME HERE
;;; Summary:
;;;   Procedures for the lab on association lists

;;; Procedure:
;;;   lookup-color-by-name
;;; Parameters:
;;;   cname, a color name
;;;   ctable, a list of color entries
;;; Purpose:
;;;   Looks up the color in the table.
;;; Produces:
;;;   color, an RGB color
;;; Preconditions:
;;;   Each entry in ctable must be a list.
;;;   Element 0 of each entry must be a string which represents a color name.
;;;   Elements 1, 2, and 3 of each entry must be integers which represent
;;;    the red, green, and blue components of each color, respectively.
;;; Postconditions:
;;;   If an entry for the name appears somewhere in the table, color is
;;;     the corresponding RGB color (computed from the components).
;;;   If multiple entries with the same name appear in the table, color
;;;     is the computed RGB color for one of them.
;;;   If no matching entries appear, color is -1.
;;;   Does not affect the table.
(define lookup-color-by-name
  (lambda (cname ctable)
    (let ([assoc-result (assoc cname ctable)])
      (if assoc-result
          (rgb-new (list-ref assoc-result 1)
                   (list-ref assoc-result 2)
                   (list-ref assoc-result 3))
          -1))))

;;; Value:
;;;   named-colors
;;; Type:
;;;   List of lists.
;;;   Each sublist is of length at least four and contains a name,
;;;     red, green, and blue components, and a sequence of attributes.
;;;   Each component is an integer between 0 and 255, inclusive.
;;;   Everything else is a string.
;;; Contents:
;;;   A list of common colors, their components, and some attributes.
(define named-colors
  (list (list "black"         0   0   0  "bw" "web-safe")
        (list "blah grey"   153 153 153  "bw" "web-safe")
        (list "blood red"   102   0   0  "reds" "web-safe")
        (list "blue"          0   0 255  "primary" "rainbow" "web-safe")
        (list "green"         0 128   0  "primary" "rainbow")
        (list "indigo"      102   0 255  "rainbow" "web-safe")
        (list "medium grey" 128 128 128  "bw")
        (list "off white"   250 250 250  "bw")
        (list "orange"      255 119   0  "rainbow")
        (list "pale red"    255 240 240  "reds")
        (list "red"         255   0   0  "primary" "rainbow" "web-safe" "reds")
        (list "violet"       79  47  79  "rainbow")
        (list "white"       255 255 255  "bw" "web-safe")
        (list "violet red"  204  50 153  "reds")
        (list "yellow"      255 255   0  "rainbow" "secondary" "web-safe")))

;;; Procedure:
;;;   lookup-color-by-component
;;; Parameters:
;;;   component, an integer between 0 and 255, inclusive
;;;   position, an integer between 1 and 3, inclusive
;;;   ctable, a list of color entries.
;;; Purpose:
;;;   Find a color name in the table which has the specified
;;;   component (1 for red, 2 for green, 3 for blue).
;;; Produces:
;;;   cname, a string (or the value #f)
;;; Preconditions:
;;;   Each entry in ctable must be a list.
;;;   Element 0 of each entry must be a string which represents a color name.
;;;   Elements 1, 2, and 3 of each entry must be integers which represent
;;;    the red, green, and blue components of each color, respectively.
;;; Postconditions:
;;;   If position is 1 and an entry with the same red value as component
;;;     appears somewhere in the table, cname is the name of one such entry.
;;;   If position is 2 and an entry with the same green value as component
;;;     appears somewhere in the table, cname is the name of one such entry.
;;;   If position is 3 and an entry with the same blue value as component
;;;     appears somewhere in the table, cname is the name of one such entry.
;;;   If no matching entries appear, cname is #f.
;;;   Does not affect the table.
(define lookup-color-by-component
  (lambda (component position ctable)
    (cond
      [(null? ctable)
       #f]
      [(equal? component (list-ref (car ctable) position))
       (car (car ctable))]
      [else
       (lookup-color-by-component component position (cdr ctable))])))

;;; Procedure:
;;;   image-draw-named-object
;;; Parameters:
;;;   image, an image
;;;   named-object, a named object
;;; Purpose:
;;;   Draw the given object on the image
;;; Produces:
;;;   [Nothing; Called for the side effect.]
;;; Preconditions:
;;;   named-object is a seven-element list of the form
;;;     (name type color left top width height), where
;;;     name is a string; type is either "ellipse" or "rectangle";
;;;     color is a color; left, top, width, and height are real numbers;
;;;     width and height are positive; and the described object fitst
;;;     in the image.
;;; Postconditions:
;;;   image now contains a rendered version of the named object.
;;;   Nothing is selected in the image.
(define image-draw-named-object!
  (lambda (image named-object)
    (let ([type (list-ref named-object 1)]
          [color (list-ref named-object 2)]
          [left (list-ref named-object 3)]
          [top (list-ref named-object 4)]
          [width (list-ref named-object 5)]
          [height (list-ref named-object 6)])
      (context-set-fgcolor! color)
      (if (equal? type "ellipse")
          (image-select-ellipse! image REPLACE
                                 left top width height)
          (image-select-rectangle! image REPLACE
                                   left top width height))
      (image-fill-selection! image)
      (image-select-nothing! image))))
