
(** The type of cards for flashing :) *)
type t

val front : t -> string
val back : t -> string

val level : t -> int


decks, which is maintained abstractly, for the appropriate
  data structure, while probably trivial, is not clear *)
type t

(** The type of cards with simply a front and a back *)
type card = {
    front : string;
    back : string
}

type card_attr = {
    level : int;
    order : int;
}

(* *)
let make_card = 

(** A simple variant to indicate whether a deck is to be read as Granule or
  Cardflasher *)
type filetype = Granule | Cardflasher

(** An empty deck *)
val empty : t

(** {4 Deck combination and manipulation} *)

(** Gets a list of the cards in order, with their level. *)
val get_cards : t -> (card * card_attr) list

val filter : ((card * card_attr) -> bool) -> t -> t

(** Checks whether the card is in the deck. *)
val mem : card -> t -> bool

(** Takes a deck, and returns the same deck with the
  card added at the given level.  The card will be appended to the back
  of the deck, so it is, in fact, O(n) *)
val add : ?level:int -> card -> t -> t

(** 
  [merge deck1 deck2] merges the two deck as follows:  The new deck
  will start with [deck1] and any cards that are in [deck2] but not
  [deck1] will follow at the end.  In this way, the scores for any
  cards in both decks are taken from deck1 *)
val merge : t -> t -> t

(**
  [merge carddeck datadeck] returns a deck with all the scores for the
  cards in the first deck replaced by those in datadeck.  You can achieve
  a similar effect with a filter + merge, but this maintains the order of
  the first deck *)
val merge_scores : t -> t -> t

(** Returns a deck with the cards reverse *)
val flip : t -> t

(** Returns a deck with the cards in random order *)
val shuffle : t -> t

(** {4 Input / output / construction} *)

(** Creates a new deck from the cards and scores in the list *)
val of_list : (card * int) list -> t

(** Decides based on the filename what kind of deck to read; this means
  it just assumes Granule file if the filename ends in ".dkf" *)
val of_filename : string -> t

(** Reads a deck from an open input channel, type defaults to Cardflasher *)
val of_simple_channel : in_channel -> t

(** Reads a deck in record format from the given channel *)
val of_record_channel : in_channel -> t

(** Writes the given deck to the out_channel *)
val output_records : out_channel -> t -> unit

val output_simple : out_channel -> t -> unit
