open Printf

let cache_deck = ref Deck.empty
let cache_digest = ref ""

let get_datadeck () =
    let datafile = Dotfiles.data_filename () in
    (* Check if it is the same as when we last loaded *)
    if (Digest.file datafile) = !cache_digest then
        !cache_deck
    else (
        cache_digest := Digest.file datafile;
        cache_deck := Deck.of_filename datafile;
        !cache_deck
    )
    

(** Loads the level data for the deck given, so any
  data in the deck will be overwritten by the data in the
  ~/.cardflasher/data file *)
let load_data deck =
    Deck.merge_scores
        deck
        (get_datadeck ())
        
(** Saves the new level data for the deck, overwriting only
    the appropriate entries in the dotfile *)
let save_data deck =
    Debug.debug (sprintf "Saving %i cards.\n" (Deck.size deck));

    (* Load up the previous scores*)
    let prev_data = get_datadeck () in
    Debug.debug (sprintf "The previous datadeck has %i cards\n" (Deck.size prev_data));

    let new_data = Deck.merge deck prev_data in
    Debug.debug (sprintf "The new datadeck has %i cards\n" (Deck.size new_data));

    (* Save the modified scores to a tempfile so that if any error
       occurs it doesn't erase the scores *)
    let datafile = Dotfiles.data_filename () in
    let tempfile =(datafile ^ ".new") in
    let outchan = open_out tempfile in
    Deck.output_records outchan new_data;
    close_out outchan;

    (* Also make a backup file *)
    let backupfile = (datafile ^ ".backup") in
    
    try
        if Sys.file_exists backupfile then
            Sys.remove backupfile;
        
        Sys.rename datafile backupfile;
        Sys.rename tempfile datafile
    with
        | e -> 
              eprintf "Error saving data to '%s'; %s\n%!"
                    datafile (Printexc.to_string e)
                    
open Deck
let rec get_level deck level =
    let min, relmin = 
        List.fold_right
            (fun (card, clevel) (min, relmin) ->
                 let min = if clevel < min then clevel else min in
                 let relmin = 
                     if (clevel >= level) && (clevel < relmin) 
                     then clevel
                     else relmin
                 in
                 min, relmin)
            (Deck.to_list deck)
            (max_int, max_int)
    in

    (*printf "The min and relmin and level are %i, %i and %i\n%!"
      min relmin level;*)

    if relmin = level then
        relmin, Deck.filter (fun card attr -> attr.level = relmin) deck
    else if min < max_int then
        get_level deck min
    else
        failwith "There are no cards with level 0 or greater, this means the \
                  deck is empty, and this should have been caught before \
                  reaching this point."
