
open Printf
open Deck

(* TODO: find this function a happier home *)
let summarize_deck deck =
    let module IntMap = 
        Map.Make(struct 
                     type t = int
                     let compare = Pervasives.compare
                 end)
    in
    let score_map = 
        List.fold_right
            (fun (_, level) map -> 
                 try 
                     let curr_level = 
                         IntMap.find level map 
                     in
                     IntMap.add level (curr_level+1) map
                 with 
                     | Not_found -> IntMap.add level 1 map)
            (Deck.to_list deck)
            IntMap.empty
    in
    IntMap.iter
        (fun level count -> printf "Level %i: %i\n" level count)
        score_map

let main_dispatch deck =
    if deck = Deck.empty then
        (eprintf "No deck/empty deck specified!\n"; exit 1)
    else
        let deck = if !Config.flip then Deck.flip deck else deck in
        let deck = Data.load_data deck in
        
        (* Remember to shuffle after loading data because the 
           current load_data puts things in the order they exist in
           the data file.  This should be changed to only
           merge in scores. *)
        let deck = if !Config.shuffle then Deck.shuffle deck else deck in
        
        match !Config.dump with
            | `Granule -> failwith "Cannot output granule files yet.";
            | `Simple -> Deck.output_simple stdout deck
            | `Records -> Deck.output_records stdout deck
                  (* TODO: add a latex UI so it makes printable flashcards *)
            | `Summary -> summarize_deck deck
            | `NoDump ->
                  match !Config.ui with
                      | `Console -> SimpleUi.main ~level:!Config.level deck
                      | `Gtk -> GtkUi.main ~level:!Config.level deck
                            (*| _ -> eprintf "Sorry, the UI you chose isn't ready yet."; exit 1*)
                  



let () =
    Random.self_init ();
    Config.load_from_file (Dotfiles.config_filename ());
    Config.load_from_argv "Usage: cardflasher [options] [decks]";

    let decks = 
        List.map (fun filename -> filename, Deck.of_filename filename) 
            !Config.filenames 
    in

    if !Config.each then
        match !Config.dump with
            | `Summary ->
                  List.iter 
                    (fun (filename, deck) ->
                         printf "----- %s -----\n%!" filename;
                         main_dispatch deck)
                      decks
            | _ -> 
                  eprintf 
                      "The --each option is invalid without --dump summary";
                  exit 1
    else
        let deck = 
            List.fold_left
                Deck.merge 
                Deck.empty
                (List.map snd decks)
        in
        main_dispatch deck
