(** Azimuthal quantum number, represented as {% $s,p,d,\dots$ %} *)

type t =
 | S | P | D | F | G | H | I | J | K | L | M | N | O
 | Int of int

exception AngularMomentumError of string
(** Raised when the {!AngularMomentum.t} element can't be created.
  *)


val of_char : char -> t
(** Returns an {!AngularMomentum.t} when a shell is given as a character (case
  insensitive).

  Example:

{[
  AngularMomentum.of_char 'p' -> AngularMomentum.P
]}
 *)

val to_string : t -> string
(** 
{[
  AngularMomentum.(to_string D) -> "D"
]}
 *)


val to_char : t -> char
(** 
{[
  AngularMomentum.(to_char D) -> 'D'
]}
 *)


val to_int : t -> int
(** 
  Returns the l{_max} value of the shell.

  Example:

{[
  AngularMomentum.to_int D -> 2
]}
 *)

val of_int : int -> t
(** 
  Opposite of {!of_int}.

  Example:

{[
  AngularMomentum.of_int 3 -> AngularMomentum.F
]}
 *)

type kind =
    Singlet of t
  | Doublet of (t * t)
  | Triplet of (t * t * t)
  | Quartet of (t * t * t * t)


val n_functions : t -> int
(** Number of cartesian functions in shell.

  Example:

{[
  AngularMomentum.n_functions D -> 6
]}
  *)


val zkey_array : kind -> Zkey.t array
(** Array of {!Zkey.t}, where each element is a a key associated with the
  the powers of x,y,z.

  Example:

{[
  AngularMomentum.( zkey_array Doublet (P,S) ) ->
    [| {Zkey.left = 0; right = 1125899906842624} ;
       {Zkey.left = 0; right = 1099511627776}    ;
       {Zkey.left = 0; right = 1073741824}       |] 
  =
 
  let s,x,y,z =
      Powers.( of_int_tuple (0,0,0),
               of_int_tuple (1,0,0),
               of_int_tuple (0,1,0), 
               of_int_tuple (0,0,1) ) 
  in
  Array.map (fun (a,b) -> {!Zkey.of_powers_six} a b)
      [| (x,s) ; (y,s) ; (z,s) |]
]}

*)

val ( + ) : t -> t -> t
val ( - ) : t -> t -> t


(** {2 Printers} *)
  
val pp_string : Format.formatter -> t -> unit
(** Prints as a string S, P, D, ... *)

val pp_int : Format.formatter -> t -> unit
(** Prints as an integer 0, 1, 2, ... *)

