(* Configurator *)
(* $Id: config.ml,v 1.5 2004/10/26 09:44:54 berke Exp $ *)

module CF = Configfile;;

let home_directory = Sys.getenv "HOME";;
let directory_in_home x = Filename.concat home_directory ("."^x);;

class configurator
  ?(defaults=[])
  ?(directory=home_directory)
  ?(primary_file=Filename.concat home_directory ".something.config") ()
  =
  object(self)
    val mutable defaults = defaults
    val mutable directory = directory
    val mutable primary = Some primary_file
    val mutable context = CF.create_context (Some primary_file)
    method set_defaults x = defaults <- x
    method set_directory x = directory <- x
    method path str = Filename.concat directory str
    method ensure_directory_presence =
      if not (Sys.file_exists directory) then
        Unix.mkdir directory 0o755 
    method set_primary x =
      primary <- Some(x);
      CF.set_filename context primary

    method load ?(merge_with=[]) () =
      let (cx,ex) = CF.load ~merge_with primary defaults in
      context <- cx;
      ex
    method load_defaults =
      let (cx,ex) = CF.load None defaults in
      if ex = [] then context <- cx;
      ex
    method save =
      self#ensure_directory_presence;
      CF.save context
    method set_config t = CF.set_config context t
    method set_context ctx = context <- ctx
    method context = context
    (*method touch = CF.touch context*)
    method set k v = CF.set context k v
    method get ?default k = CF.get ?default context k
    method get_int ?default k = CF.get_int ?default context k
    method get_string ?default k = CF.get_string ?default context k
    method get_bool ?default k = CF.get_bool ?default context k
    method get_string_pair k =
      CF.get_pair
        (CF.to_string ~k) (CF.to_string ~k) context k

    method set_string_pair k (x,y) =
      CF.set_pair context k (CF.String x, CF.String y)

    method set_int k x = CF.set_int context k x
    method set_string k x = CF.set_string context k x
    method set_bool k x = CF.set_bool context k x
  end
;;

let duplicate (c : configurator) : configurator =  
  let c' = Oo.copy c in
  c'#set_context (Configfile.duplicate_context c'#context);
  c'
;;
