(*
 * <COPYRIGHT>
 * Copyright 2002 Joachim Schrod Network and Publication Consultance GmbH, Gerd Stolpmann
 *
 * <GPL>
 * This file is part of WDialog.
 *
 * WDialog is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * WDialog 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with WDialog; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * </>
 *)

(* $Id: wd_interactor.mli,v 3.6 2005/06/11 14:24:14 stolpmann Exp $
 * ----------------------------------------------------------------------
 *
 *)

(** This module provides a data type for containers of interactor descriptions.
  *)
(** The background of the module is that interactors (such as input elements,
 * hyperlinks, buttons) are referred to by two different naming schemes. On
 * the one hand, the interactor elements in the ui file have a name and
 * and optionally an index; e.g.
 *   {[<ui:button label="Press here" name="my_button" index="1"/>]}
 * or
 *   {[<ui:text variable="x" index="5"/>]}
 * Often the name/index pair is actually a variable/index pair because the
 * interactor is bound to a certain instance variable of the uiobject.
 * \- On the other hand, the interactors are transformed to HTML code, and
 * the HTML/CGI name is different. For example the following HTML output
 * might have been generated:
 *   {[<input type="button" name="xbutton_25" value="Press here">]}
 * or
 *   {[<input type="text" name="var_12" value="...">]}
 * Obviously, the HTML/CGI names are automatically chosen. Of course, there
 * is a bijective mapping from the internal names to the HTML/CGI names,
 * and the task of the Interactor.t type is to manage these mappings.
 *
 * A value of type Interactor.t contains the following:
 * - A list of name/index pairs
 * - The corresponding HTML/CGI identifiers. Only the identifier
 *   after the prefix (such as "var_" or "xbutton_") is stored.
 * - The bijection which name/index pair corresponds to which identifier.
 * - For every name/index pair (or every identifier) there may be another
 *   arbitrary value which can store additional information related to
 *   the interactor
 *
 * {b Example}
 *
 * {[let ia = create();;    (* : unit Interactor.t *)
 * ...
 * let id = add ia "my_button" "1" None ();;   (* = "25" *)]}
 *
 * Note that the "25" is an automatically created identifier (just the next
 * free number), and that the HTML/CGI name will be composed of a prefix
 * indicating the type of the interactor and the identifier, e.g. 
 * "xbutton_25".
 *
 * If we try to add the same name/index pair a second time, the add operation
 * raises an exception:
 *
 * {[add ia "my_button" "1" None ();;]}
 *    ==> raises [Element_exists "25"]
 *
 * When the incoming CGI parameters are analyzed, it must be possible to
 * look up the name/index pair for a given identifier. For example:
 *
 * {[let (name,index,value) = lookup ia "25";; (* = ("my_button", "1", () *)]}
 *
 * There is no reverse lookup operation. However, it is at least possible
 * to test the existence of a given name/index pair:
 *
 * [exists ia "my_button" "1"]      yields [true]
 *
 * As a last resort, it is possible to iterate over all members of the
 * ia value:
 *
 * {[let print id name index value =
 *   printf "ID=%s name=%s index=%s\n" id name index
 * in
 * iter print ia]}
 *
 * {b Selecting the identifier manually}
 *
 * If the ui element contains the [cgi="keep"] attribute, and there is no
 * index component, the CGI name retains the orignal name. For example:
 *   {[<ui:button label="Press here" name="press" cgi="keep"/>]}
 * The generated HTML code:
 *   {[<input type="button" name="button_press" value="Press here">]}
 *
 * Such an interactor would be added as follows:
 * {[let id = add ia "press" "" (Some "press") ();;   (* = "press" *)]}
 *
 * I.e. you can determine the identifier by passing it as fourth argument.
 * Of course, in this case it is checked whether the identifier is still
 * free; and [add] fails if the identifier was already previously used.
 * 
 * {b Representation}
 *
 * Note that the representation of [Interactor.t] is optimized for efficient
 * serialization (using the Marshal module). Especially, if there are many
 * name/index pairs differing only in the index component, the name component
 * is stored only once.
 *
 * {b Further information}
 *
 * See {!Wd_types.interactors}
 *)

open Wd_serialize_types

type 'value_type t;;
  (** The type of interactors *)

type id = string;;
  (** Interactors are identified by strings *)

exception Element_exists of id;;
  (** Raised by some functions if there is already a component with the ID *)

val create : 'value_type -> 'value_type t
    (** [create x]: Creates a new interactor manager. The value [x] must only
     * be passed because of typing restrictions.
     *)

val clear : 'value_type t -> unit
    (** [clear ia]: Removes all entries from the interactor. The sequence
     * generator for the automatic IDs is not reset, however.
     *)

val add : 'value_type t -> string -> string -> id option -> 'value_type -> id
    (** [add ia name index opt_id value]: adds the triple [(name,index,value)] to
     * [ia]; if [opt_id] is [None], the triple gets an automatically selected
     * numerical ID; if [opt_id] is [Some id], the triple has the ID [id].
     * The function returns the ID.
     *
     * Fails with [Element_exists] if the pair [(name,index)] is already
     * contained. The argument of this exception is the ID.
     *)

val lookup : 'value_type t -> id -> (string * string * 'value_type)
    (** [lookup ia id]: looks up the triple [(name,index,value)] for the ID [id]
     * within [ia].
     *
     * Fails with "Interactor.lookup" if the id cannot be associated.
     *)

val exists : 'value_type t -> string -> string -> bool
    (** [exists ia name index]: returns whether the pair [(name,index)] exists
     * in [ia].
     *)

val iter : (id -> string -> string -> 'value_type -> 'a) -> 'value_type t -> unit
    (** [iter f ia]: iterates over the elements of [ia] and invoke the function
     * [f] for every element by [f id name index value].
     *)

val serialize : ('value_type -> string) -> Buffer.t -> 'value_type t -> unit
  (** [serialize f b ia]: Writes the serialization of [ia] to buffer [b].
    * Contained values are serialized by calling [f].
   *)

val unserialize : 
  (('u,'d,'e) poly_ds_buf -> 'value_type) -> ('u,'d,'e) poly_ds_buf -> 'value_type t
  (** [unserialize f buf]: Reads the serialized string from [buf] and reconstructs
    * the interactors. Values are read by calling [f].
   *)

(**/**)

val revision_interactor : string
  (* Returns the CVS revision string. It is part of the hash value
   * that goes into the serialized objects
   *)


(* ======================================================================
 * History:
 *
 * $Log: wd_interactor.mli,v $
 * Revision 3.6  2005/06/11 14:24:14  stolpmann
 * Extension of bracket expressions: many new functions.
 * Functions in bracket expressions may now lazily evaluate their arguments.
 * ui:if and ui:ifvar may refer to any functions defined for bracket
 * expressions.
 * New: ui:ifexpr
 * Parsing of bracket expressions is now done with ulex. Private interfaces
 * of PXP are no longer used for this purpose.
 * Serialization has been rewritten, and it is now safe.
 * Fix: In ui:context there may now be macro references at any location.
 * Also documented all these changes.
 *
 * Revision 3.5  2002/04/10 21:27:52  stolpmann
 * 	New scheme for automatically generated interactor IDs. There
 * are now two parts: <base>_<seq> where <base> is the base number
 * (currently derived from the system clock), and where <seq> is the
 * sequence number. Sequence numbers are no longer reset to 0 after
 * "handle". (The reason for the new ID scheme are buggy browsers that
 * try to remember old form values. It is now very unlikely that a
 * name for a form field is reused before the page expires.)
 *
 * Revision 3.4  2002/04/10 20:03:14  stolpmann
 * 	The CVS revision number is exported.
 *
 * Revision 3.3  2002/02/16 17:29:45  stolpmann
 * 	mostly ocamldoc.
 *
 * Revision 3.2  2002/02/14 16:15:21  stolpmann
 * 	Added copyright notice.
 *
 * Revision 3.1  2002/02/12 20:29:23  stolpmann
 * 	Initial release at sourceforge.
 *
 * Revision 1.3  2000/12/04 11:58:54  gerd
 * 	Added documentation.
 *
 * Revision 1.2  2000/05/08 17:56:22  gerd
 * 	Changed such that arbitrary strings can be used as interactor
 * IDs as well as automatically generated numbers.
 *
 * Revision 1.1  2000/04/13 17:42:57  gerd
 * 	Initial revision.
 *
 *
 *)
