(* Copyright 2005-2007 Berke DURAK, INRIA Rocquencourt.

This file is part of Dose2.

Dose2 is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Dose2 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>. *)

(** Datastructure for life timelines.

    Provides a datastructure for representing sets of days as a list of intervals, suitable for
    rLepresenting the lifetime of a package in an archive. *)

exception Empty (** Raised when a function expects a non-empty lifetime *)
type day = int (** Represented as calendar days from an unspecified origin. *)
type lifetime
val io_lifetime : lifetime Io.literate
val io_day : day Io.literate

val day_of_ymd : (int * int * int) -> day (** Convert a date in Gregorian [(year,month,day)] format to a calendar day. *)
val ymd_of_day : day -> (int * int * int) (** Inverse function of [day_of_date]. *)

val empty : lifetime (** A lifetime containing no days. *)
val load : string -> lifetime (** Load lifetime data from a file using [Io]. *)
val save : string -> lifetime -> unit (** Save lifetime data to a file using [Io]. *)
val output : out_channel -> lifetime -> unit (** Output lifetime data to a channel using [Io]. *)
val singleton : day -> lifetime (** Create a lifetime with the given single day. *)
val add_day : lifetime -> day -> lifetime (** Add a day to a lifetime. *)
val is_empty : lifetime -> bool (** Returns [true] if the lifetime contains no days. *)
val range : lifetime -> day * day
(** [range lf] returns a pair [(a,b)] where [a] is the first day and [b]
 *  is the last day in the lifetime.  Raises [Empty] if [lf] is empty. *)
val iterate_over_intervals : (day * day -> unit) -> lifetime -> unit (** Iterate over the intervals in the lifetime. A
single day is represented by a pair [(d,d)]. *)
val iterate_over_days : (day -> unit) -> lifetime -> unit (** Iterate over every single day in the lifetime. *)
