-- Comp1100 Introduction to Programming and Algorithms

-- Example: Supermarket Docket
-- Docket module

-- Functions to produce a docket from a list of barcodes for the
-- sample database

-- Clem Baker-Finch and <YOUR NAME HERE>  March 2006
----------------------------------------------------------------------
module Docket where

import DB
import SampleDB

-- The types of till inputs, and of the converted information, names
-- and prices replacing bar codes.

type TillType = [BarCode]
type BillType = [(Name,Price)]

----------------------------------------------------------------------
--        Principal functions of the system.

-- The makeBill function takes a list of bar codes and returns a list
-- of (Name,Price) pairs.

makeBill :: TillType -> BillType
makeBill = map findIt

-- The formatBill function takes the bill data, i.e. a list of
-- Name,Price pairs and prints out the formatted receipt.

formatBill :: BillType -> String
formatBill bill = 
    "\n"
    ++ cjustify lineLength "Alonzo's Mega-Mart"
    ++ "\n\n"
    ++ formatLines bill
    ++ formatTotal (makeTotal bill)

-- Combining the above two functions give the central function of the
-- script.

printBill  :: TillType -> String
printBill = formatBill . makeBill

----------------------------------------------------------------------
-- Formatting functions

-- The width of the printed docket

lineLength :: Int
lineLength = 30

-- A function to centre justify a string in a width.

cjustify :: Int -> String -> String
cjustify n s  =
    replicate halfm ' ' ++ s ++ replicate (m - halfm) ' '
	where m     = n - length s
	      halfm = m `div` 2

-- formatCents takes a number of cents and produces a string
-- representing the dollar and cents value.  The only tricky bit is if
-- cents is < 10 and if cents == 0.

formatCents :: Price -> String
-- YOUR CODE HERE

-- formatLine takes a product name and a price and justifies with dots
-- to lineLength character width, and appends a newline.

formatLine  :: (Name,Price) -> String
-- YOUR CODE HERE

-- formatLines <YOUR COMMENT HERE>

formatLines :: [ (Name,Price) ] -> String
-- YOUR CODE HERE

-- The makeTotal function takes a bill, i.e. a list of Name,Price
-- pairs and returns the total cost, i.e. the sum of the Prices.

makeTotal :: BillType -> Price
-- YOUR CODE HERE

-- The formatTotal function prepares a line of output to append the
-- total cost to the end of the receipt.  It is just about layout.

formatTotal :: Price -> String
formatTotal total =
    "\nTotal"++ dots ++ totalStr ++ "\n"
    where totalStr = '$' : formatCents total
	  spacing  = lineLength - 5 - length totalStr   -- length "Total" is 5
	  dots     = replicate spacing '.'

----------------------------------------------------------------------
-- A sample list of bar codes for testing purposes.

purchases :: [BarCode]
purchases  = [1234,3216,4719,1112,1113,3814,1234]

----------------------------------------------------------------------


