\documentclass{article}
\usepackage{axiom}

\title{src/algebra color.spad}

\begin{document}
\author{Gabriel Dos~Reis \and Jim Wen}

\maketitle
\begin{abstract}
\end{abstract}
\tableofcontents
\eject

\section{The category of RGB Color Model}

<<category RGBCMDL RGBColorModel>>=
)abbrev category RGBCMDL RGBColorModel
++ Author: Gabriel Dos Reis
++ Date Created: October 06, 2008
++ Related Constructor: 
++ Description:
++   This category defines the common interface for RGB color models.
RGBColorModel(T: AbelianMonoid): Category == AbelianMonoid with
    red: % -> T
      ++ red(c) returns the `red' component of `c'.
    green: % -> T
      ++ green(c) returns the `green' component of `c'.
    blue: % -> T
      ++ blue(c) returns the `blue' component of `c'.
    componentUpperBound: T
      ++ componentUpperBound is an upper bound for all component values.
@


\section{The category of RGB Color Space}

<<category RGBCSPC RGBColorSpace>>=
)abbrev category RGBCSPC RGBColorSpace
++ Author: Gabriel Dos Reis
++ Date Created: October 06, 2008
++ Related Constructor: 
++ Description:
++   This category defines the common interface for RGB color spaces.
RGBColorSpace(T: AbelianMonoid): Category == RGBColorModel T with
    whitePoint: %
      ++ whitePoint is the contant indicating the white point 
      ++ of this color space.
@


\section{domain COLOR Color}

<<domain COLOR Color>>=
)abbrev domain COLOR Color
++ Author: Jim Wen
++ Date Created: 10 May 1989
++ Date Last Updated: 19 Mar 1991 by Jon Steinbach
++ Basic Operations: red, yellow, green, blue, hue, numberOfHues, color, +, *, =
++ Related Constructors:
++ Also See:
++ AMS Classifications:
++ Keywords: 
++ References:
++ Description: Color() specifies a domain of 27 colors provided in the 
++ \Language{} system (the colors mix additively).
 

Color(): Exports == Implementation where
  I      ==> Integer
  PI     ==> PositiveInteger
  SF     ==> DoubleFloat
 
  Exports ==> AbelianSemiGroup with
    "*"    : (PI, %) -> %
      ++ s * c, returns the color c, whose weighted shade has been scaled by s.
    "*"    : (SF, %) -> %
      ++ s * c, returns the color c, whose weighted shade has been scaled by s.
    "+"    : (%, %) -> %
      ++ c1 + c2 additively mixes the two colors c1 and c2.
    red    : ()      -> %
      ++ red() returns the position of the red hue from total hues.
    yellow : ()      -> %
      ++ yellow() returns the position of the yellow hue from total hues.
    green  : ()      -> %
      ++ green() returns the position of the green hue from total hues.
    blue   : ()      -> %
      ++ blue() returns the position of the blue hue from total hues.
    hue    : %       -> I
      ++ hue(c) returns the hue index of the indicated color c.
    numberOfHues : ()    -> PI
      ++ numberOfHues() returns the number of total hues, set in totalHues.
    color  : Integer -> %
      ++ color(i) returns a color of the indicated hue i.
  
  Implementation ==> add
    totalHues   ==> 27  --see  (header.h file) for the current number

    Rep := Record(hue:I, weight:SF)
 

    f:SF * c:% ==
      -- s * c returns the color c, whose weighted shade has been scaled by s
      zero? f => c
      -- 0 is the identitly function...or maybe an error is better?
      [c.hue, f * c.weight]
 
    x + y ==
      x.hue = y.hue => [x.hue, x.weight + y.weight]
      if y.weight > x.weight then  -- let x be color with bigger weight
        c := x
        x := y
        y := c
      diff := x.hue - y.hue
      if (xHueSmaller:= (diff < 0)) then diff := -diff
      if (moreThanHalf:=(diff > totalHues quo 2)) then diff := totalHues-diff
      offset : I := wholePart(round (diff::SF/(2::SF)**(x.weight/y.weight)) )
      if (xHueSmaller and not moreThanHalf) 
           or (not xHueSmaller and moreThanHalf) 
      then
        ans := x.hue + offset
      else
        ans := x.hue - offset
      if (ans < 0) then ans := totalHues + ans
      else if (ans > totalHues) then ans := ans - totalHues
      [ans,1]
 
    x = y     == (x.hue = y.hue) and (x.weight = y.weight)
    red()     == [1,1]
    yellow()  == [11::I,1]
    green()   == [14::I,1]
    blue()    == [22::I,1]
    sample()  == red()
    hue c     == c.hue
    i:PositiveInteger * c:% == i::SF * c
    numberOfHues() == totalHues 

    color i ==
      if (i<0) or (i>totalHues) then
       error concat("Color should be in the range 1..",totalHues::String)
      [i::I, 1]
 
    coerce(c:%):OutputForm ==
      hconcat ["Hue: "::OutputForm, (c.hue)::OutputForm,
               "  Weight: "::OutputForm, (c.weight)::OutputForm]

@
\section{domain PALETTE Palette}
<<domain PALETTE Palette>>=
)abbrev domain PALETTE Palette
++ Author: Jim Wen
++ Date Created: May 10th 1989
++ Date Last Updated: Jan 19th 1990
++ Basic Operations: dark, dim, bright, pastel, light, hue, shade, coerce
++ Related Constructors:
++ Also See:
++ AMS Classifications:
++ Keywords: dim,bright,pastel,coerce
++ References:
++ Description: This domain describes four groups of color shades (palettes).
 
Palette(): Exports == Implementation where
  I      ==> Integer
  C      ==> Color
  SHADE  ==> ["Dark","Dim","Bright","Pastel","Light"]

  Exports ==> SetCategory with
    dark   : C  -> %
      ++ dark(c) sets the shade of the indicated hue of c to it's lowest value.
    dim    : C  -> %
      ++ dim(c) sets the shade of a hue, c,  above dark, but below bright.
    bright : C  -> %
      ++ bright(c) sets the shade of a hue, c, above dim, but below pastel.
    pastel : C  -> %
      ++ pastel(c) sets the shade of a hue, c,  above bright, but below light.
    light  : C  -> %
      ++ light(c) sets the shade of a hue, c,  to it's highest value.
    hue    : %  -> C
      ++ hue(p) returns the hue field of the indicated palette p.
    shade  : %  -> I
      ++ shade(p) returns the shade index of the indicated palette p.
    coerce : C  -> %
      ++ coerce(c) sets the average shade for the palette to that of the 
      ++ indicated color c.
 
  Implementation ==> add
    import I
    import C
    Rep := Record(shadeField:I, hueField:C)

    dark   c == [1,c]
    dim    c == [2,c]  
    bright c == [3,c]  
    pastel c == [4,c]  
    light  c == [5,c]  
    hue    p == p.hueField
    shade  p == p.shadeField
    -- sample() == bright(sample())
    coerce(c:Color):% == bright c
    coerce(p:%):OutputForm ==
      hconcat ["[",coerce(p.hueField),"] from the ",SHADE.(p.shadeField)," palette"]

@
\section{License}
<<license>>=
--Copyright (c) 1991-2002, The Numerical Algorithms Group Ltd.
--All rights reserved.
--
--Copyright (C) 2007-2008, Gabriel Dos Reis.
--All rights reserved.
--
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are
--met:
--
--    - Redistributions of source code must retain the above copyright
--      notice, this list of conditions and the following disclaimer.
--
--    - Redistributions in binary form must reproduce the above copyright
--      notice, this list of conditions and the following disclaimer in
--      the documentation and/or other materials provided with the
--      distribution.
--
--    - Neither the name of The Numerical Algorithms Group Ltd. nor the
--      names of its contributors may be used to endorse or promote products
--      derived from this software without specific prior written permission.
--
--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@
<<*>>=
<<license>>

<<category RGBCMDL RGBColorModel>>
<<category RGBCSPC RGBColorSpace>>
 
<<domain COLOR Color>>
<<domain PALETTE Palette>>
@
\eject
\begin{thebibliography}{99}
\bibitem{1} nothing
\end{thebibliography}
\end{document}