;;; -*- Mode:LISP; Readtable:CL; Base:10 -*-

(defun string-replace(old new str)
  (let((pos (string-search old str))
       (rep new)
       oldstr)
    (if (null pos)
	str
      (progn
	(setq oldstr (substring str 0 pos))
	(setq str (substring str (+ pos (string-length old))))
;	(print str)
	(when (and (plusp (string-length str))
		   (char-equal (aref str 0) #\{ )
		   (setq pos (string-search "}" str)))
	  (multiple-value-bind (thing ignore)
	      (read-from-string (substring str 1 pos))
	    (if (not (numberp thing))
		(ferror nil "Search string ~s followed by non-numeric ~s"
			old thing))
	    (setq rep (format nil "~v@<~a~>" thing new))
	    (setq str (substring str (1+ pos)))))
;	(print str)
	(string-append
	  oldstr
	  rep
	  (string-replace old new str))))))

(defmacro section(vars text &optional (tagstr "$!"))
  `(let* ,vars
     (declare(special ,@(mapcar #'car vars)))
     (loop for var in ',(mapcar #'car vars)
	   as svar = (string-append ,tagstr (write-to-string var))
	   as sval = (write-to-string (symbol-value var))
	   with txt = ,text
	   do (setq txt (string-replace svar sval txt))
	   finally (return txt))))

(defun memo(to from date subj copy text &optional (cols 72))
  (with-output-to-string(str)
    (format str "~&~v:@<~a~>" cols "MEMORANDUM")
    (format str "~2%")
    (format str "~&  TO:~,12t~a" to)
    (format str "~&  FROM:~,12t~a" from)
    (format str "~&  DATE:~,12t~a" date)
    (format str "~&  SUBJ:~,12t~a" subj)
    (if copy (format str "~&  COPY:~,12t~a" copy))
    (format str "~2%~a" text)
    (format str "~&")))

(defun vars(vardb varlist)
  (do*((vl varlist (cdr vl))
       (varl (car vl) (car vl))
       (var (car varl) (car varl))
       (val (cadr varl) (cadr varl)))
      ((null vl) vardb)
    (format t "~&Set ~s to ~s in ~s from ~s" var val vardb vl)
    (setf (getf vardb var) val)
    (print vardb)) vardb)

(defvar *header*
	(memo "Pat Kareiva" "Keith Corbett"
	      "April 23, 1987"
	      "3.0 Software Upgrade Costs and Requirements"
	      "Clovis Regis, Dan Remeika, David Lee"
	      "
Following is a summary of short- and long-term materials requirements
for release 3.0 software upgrade kits.  The various software kits in
question are:

	- 3.0 LISP (operating system release)
	- 3.0 TCP/IP
	- 3.0 Laser1+ (printer software)
	- 3.0 Vista and Iris (graphics)

For each software upgrade, I summarize the requirements to complete all
shipments, then the more immediate requirements.  In other words, in
each case there is a short-term plan that would provide the maximum
benefit for the least expense.  

I am working on a general plan for funding and completing these
shipments which I will complete later in the week.
"))

(defconst *cost-of-a-tape* 10)

(defvar *rel3* "")

(eval-when (eval compile load)
  (setq *rel3*
	(section ((nsites 70)
		  (nsys5-kits 65)
		  (nboot-kits 30)
		  (nkits (+ nsys5-kits nboot-kits 5))
		  (qty-bands 20)
		  (qty-files 20)
		  (qty-sys5 5)
		  (qty-usr 5)
		  (qty-boot 20)
		  (nbands (- nkits qty-bands))
		  (nfiles (- nkits qty-files))
		  (nsys5  (- nsys5-kits qty-sys5))
		  (nusr   (- nsys5-kits qty-usr))
		  (nboot  (- nboot-kits qty-boot))
		  (nall   (+  nbands nfiles nsys5 nusr nboot))
		  (costape *cost-of-a-tape*)
		  (cost-band  (* nbands costape))
		  (cost-files (* nfiles costape))
		  (cost-sys5  (* nsys5  costape))
		  (cost-usr   (* nusr   costape))
		  (cost-boot  (* nboot  costape))
		  (cost-tapes   (+ cost-band cost-files cost-sys5 cost-usr cost-boot))
		  (cost-adoc 30)
		  (cost-docs (* cost-adoc nkits))
		  (cost-all (+ cost-tapes cost-docs))
		  )

  "

1. 3.0 LISP

The most immediate requirement is for 3.0 upgrade kits.  There are about
$!nsites customer sites which have not received any 3.0 software.  The
maximum number of kits required (one per system) is about $!nkits.

Based on a worst-case estimated cost per documentation set of about $$!cost-adoc,
the total cost of completing the 3.0 shipments is approximately:

        Item            qty       cost
        ----            ---       ----

        band tape       $!nbands{10} $!cost-band{10}
        files tape      $!nfiles{10} $!cost-files{10}
        sys5 boot tape  $!nsys5{10} $!cost-sys5{10}
        sys5 usr tape   $!nusr{10} $!cost-usr{10}
        reg. boot tape  $!nboot{10} $!cost-boot{10}
                        ---       ----
                        $!nall{10} $!cost-tapes{10}

        doc set         $!nkits{10} $!cost-docs
                                  ----
        Total                     $$!cost-all



;Pro-rating this, the cost per kit is $95; with shipping, roughly $110.
;(???).

;We have enough tapes on hand for about 20 kits, but we are completely
;out of several manuals, and other quantities are very low.  Our most
;critical need is for documentation; with another run of manuals we could
;have about 20 kits on hand.  This would cost us about $1000 and would
;enable us to continue to respond to urgent requests.

;Looking ahead somewhat, we might price an upgrade kit at $250 and more
;than cover these costs. If even half the 70 customers who haven't
;received any kits bought just one, we would net $8750 -($3850) = $5000.

;The $250 price was proposed to our distributors for extra copies.  At
;the lower price of $195 (our 'traditional' media charge), we would net,
;as above, $2975.

;2. TCP/IP

;We need 54 kits to complete shipment. There is one tape ($20) plus one
;manual (about $10) for a kit cost of about $30 plus $10 shipping = $40.
;Maximum materials costs are thus $2160.

"
)))

(defun doit(&optional (stream standard-output))
  (format stream "~a" *header*)
  (format stream "~a" *rel3*))