(*
 * <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_var_functions.mli,v 1.6 2005/06/11 14:24:14 stolpmann Exp $
 * ----------------------------------------------------------------------
 *
 *)

(** This module defines the "variable functions" that can be called in
 * [$[...]] expressions. All these functions take formally a list of
 * [var_value] arguments and return a [var_value]. Actually, they are
 * often only defined for a certain number of arguments, and for arguments
 * of certain type.
 *
 * The functions raise a [Failure] exception if something is wrong.
 *)


open Wd_types

val id : dialog_type -> var_value list -> var_value
  (** Returns the first argument *)

val length : dialog_type -> var_value list -> var_value
  (** Returns the length of the single string argument in characters.
   *)

val card : dialog_type -> var_value list -> var_value
  (** Returns the cardinality of the single argument. The cardinality are the
   * number of iterations <ui:iterate> or <ui:enumerate> would do for a
   * variable with the given value:
   * - For a string: the number of words of the string
   * - For an enumerator: the number of elements
   * - For an association: the number of elements
   *)

val size : dialog_type -> var_value list -> var_value
  (** Returns the size of the single argument, which may be a [String_value],
   * [Enum_value], [Dyn_enum_value], or an [Alist_value].
   * The returned size is encoded as [String_value].
   *
   * {b [size] is deprecated! Use either [length] or [card] instead!}
   *)

val add : dialog_type -> var_value list -> var_value
  (** Adds the numbers encoded as [String_value], and returns the sum as
   * [String_value].
   *)

val sub : dialog_type -> var_value list -> var_value
  (** Subtracts the following numbers from the first number. All numbers
   *  must be encoded as [String_value].  Returns the result as 
   *  [String_value].
   *)

val mul : dialog_type -> var_value list -> var_value
  (** Multiplies the numbers encoded as [String_value], and returns the product
   * as [String_value].
   *)

val div : dialog_type -> var_value list -> var_value
  (** Divides the first number through the following numbers. All numbers
   *  must be encoded as [String_value].  Returns the result as 
   *  [String_value].
   *)

val modulo : dialog_type -> var_value list -> var_value
  (** The first number module the second number. Both numbers
   *  must be encoded as [String_value].  Returns the result as 
   *  [String_value].
   *)

val assoc : dialog_type -> var_value list -> var_value
  (** Looks the second argument up in the first argument, which must be
   *  an [Alist_value]. The index, i.e. second argument, must be an
   *  [String_value].
   *)

val nth : dialog_type -> var_value list -> var_value
  (** Returns the nth element of the first argument which must be an
   * [Alist_value]. The second argument is the position, a number encoded
   * as [String_value].
   *)

val contains : dialog_type -> var_value list -> var_value
  (** Returns 1 if the first argument contains the second argument, and 0 otherwise.
    * The second argument must be a string value. The function is defined as follows:
    * - If the first argument is a string, it is split up into a list of words,
    *   and it is tested whether the second string occurs in the list of words.
    * - If the first argument is a declared enumerator, it is tested whether
    *   the value includes the string as item.
    * - If the first argument is a dynamic enumerator, it is tested whether
    *   the value includes the string as internal item.
    * - If the first argument is an associative list, it is tested whether
    *   the value includes the string as index.
   *)

val mentions : dialog_type -> var_value list -> var_value
  (** Returns 1 if the first argument contains the second argument, and 0 otherwise.
    * The second argument must be a string value. The function is defined as follows:
    * - If the first argument is a dynamic enumerator, it is tested whether
    *   the value includes the string as external item.
    * - If the first argument is an associative list, it is tested whether
    *   the value includes the string as mapped value.
   *)

val translate : dialog_type -> var_value list -> var_value
  (** Like ui:translate maps internal values of enumerators to external
   * values. The function takes two arguments:
   * 
   * - [translate [dyn; int]]: The first argument is a dynamic enumerator,
   *   and the second argument is the internal value to translate to the
   *   external value
   * - [translate [type; int]]: The first argument denotes a declared 
   *   enumerator (as a string), and the second argument is the internal 
   *   value to translate to the external value
   *)

val rev_translate : dialog_type -> var_value list -> var_value
  (** Maps external values to internal values:
   * 
   * - [rev_translate [dyn; int]]: The first argument is a dynamic enumerator,
   *   and the second argument is the external value to translate to the
   *   internal value
   * - [translate [type; int]]: The first argument denotes a declared 
   *   enumerator (as a string), and the second argument is the external 
   *   value to translate to the internal value
   *)

val eq : dialog_type -> var_value list -> var_value
  (** Compares two strings, and returns 1 when equal and 0 when not equal *)

val ne : dialog_type -> var_value list -> var_value
  (** Compares two strings, and returns 0 when equal and 1 when not equal *)

val match_ : dialog_type -> var_value list -> var_value
  (** Checks whether the first string matches the regular expression in the
    * second string, and returns 1 on match and 0 otherwise
   *)

val nomatch : dialog_type -> var_value list -> var_value
  (** Checks whether the first string matches the regular expression in the
    * second string, and returns 0 on match and 1 otherwise
   *)

val substring : dialog_type -> var_value list -> var_value
  (** Returns a substring of the first argument, a [String_value]. The
   * following forms are accepted:
   *
   * - [substring [s; pos; length]]: The second argument is the position,
   *   and the third argument is the length. The length can be negative.
   * - [substring [s; pos]]: Only the position is passed. Returns the
   *   substring beginning at this position until the end of the string.
   *
   * If the start position or end position of the substring is outside
   * the possible range, only the part of the substring is returned that
   * is inside the possible range.
   *) 

val concat : dialog_type -> var_value list -> var_value
  (** Concatenates all the [String_value] arguments, and returns the
   * result as [String_value].
   *)

val int_eq : dialog_type -> var_value list -> var_value
val int_ne : dialog_type -> var_value list -> var_value
val int_lt : dialog_type -> var_value list -> var_value
val int_le : dialog_type -> var_value list -> var_value
val int_gt : dialog_type -> var_value list -> var_value
val int_ge : dialog_type -> var_value list -> var_value
  (** These functions compare two strings as integers, and return 1 if the
    * condition is fulfilled, and 0 if not. The conditions are:
    * - int_eq: The integers are equal
    * - int_ne: The integers are not equal
    * - int_lt: The first integer is less than the second integer
    * - int_le: The first integer is less or equal than the second integer
    * - int_gt: The first integer is greater than the second integer
    * - int_ge: The first integer is greater or equal than the second integer
   *)

val int_min : dialog_type -> var_value list -> var_value
val int_max : dialog_type -> var_value list -> var_value
  (** These functions compute the minimum/maximum of all integer arguments *)

val int_abs : dialog_type -> var_value list -> var_value
val int_sign : dialog_type -> var_value list -> var_value
  (** These functions compute the absolute value/the sign of the first integer
    * argument
   *)

val card_eq : dialog_type -> var_value list -> var_value
val card_ne : dialog_type -> var_value list -> var_value
val card_lt : dialog_type -> var_value list -> var_value
val card_le : dialog_type -> var_value list -> var_value
val card_gt : dialog_type -> var_value list -> var_value
val card_ge : dialog_type -> var_value list -> var_value
  (** These functions compare the cardinality of the first argument with a string taken
    * as integer, and return 1 if the condition is fulfilled, and 0 if not. 
    * The cardinality is defined as for the [card] function.
    * The conditions are:
    * - int_eq: The cardinality is equal to the integer
    * - int_ne: The cardinality is not equal to the integer
    * - int_lt: The cardinality is less than the integer
    * - int_le: The cardinality is less or equal than the integer
    * - int_gt: The cardinality is greater than the integer
    * - int_ge: The cardinality is greater or equal than the integer
   *)


val height : dialog_type -> var_value list -> var_value
  (** Returns the height of the [String_value] argument. The height is
   * the number of lines, i.e. the number of LF/CR/CRLF occurrences 
   * plus 1.
   *)

val width : dialog_type -> var_value list -> var_value
  (** Returns the width of the [String_value] argument. The width is
   * the length of the longest line (not counting the line separators).
   *)

val dialog_exists : dialog_type -> var_value list -> var_value
  (** When called with only one argument: The function returns 1 if the 
    * argument is an existing dialog (i.e. [Dialog_value(Some _)]) and
    * 0 if the dialog does not exist (i.e. [Dialog_value None]). 
    *
    * When called with two arguments (legacy mode): The first argument must
    * be a dialog value as before, and the second argument must be either
    * the string "yes" or the string "no". The function returns 1 if the
    * existence of the dialog is equivalent to the boolean value of the
    * string.
   *)

val and_ : dialog_type -> var_value Lazy.t list -> var_value
  (** Calculates the logical AND operation for all its arguments: Returns 1 if
    * all arguments are non-zero integers, and 0 otherwise.
   *)

val or_ : dialog_type -> var_value Lazy.t list -> var_value
  (** Calculates the logical OR operation for all its arguments: Returns 1 if
    * there is a non-zero integer as argument, and 0 otherwise.
   *)

val not_ : dialog_type -> var_value list -> var_value
  (** Calculates the logical NOT operation of its single argument: Returns 1
    * if the argument is 0, and 0 if the argument is non-zero.
   *)

val true_ : dialog_type -> var_value list -> var_value
  (** Returns the constant 1 *)

val false_ : dialog_type -> var_value list -> var_value
  (** Returns the constant 0 *)

val if_ : dialog_type -> var_value Lazy.t list -> var_value
  (** Evaluates the first argument (which must be an integer). If the integer is
    * non-zero, the result is the second argument. If the integer is 0, the result
    * is the third argument.
   *)

val var :  dialog_type -> var_value list -> var_value
  (** Returns the contents of the variable whose name is passed as
   * first argument, a [String_value].
   *)

val dialog : dialog_type -> var_value list -> var_value
  (** Returns the name of the current dialog (no arguments) *)

val self : dialog_type -> var_value list -> var_value
  (** Returns the current dialog (no arguments) *)

val page : dialog_type -> var_value list -> var_value
  (** Returns the name of the current page (no arguments) *)

val language : dialog_type -> var_value list -> var_value
  (** Returns the current language, or "" if none selected (no arguments) *)

val self_base_url : dialog_type -> var_value list -> var_value
  (** Returns the URL pointing to the current script without session state *)

val session_id : dialog_type -> var_value list -> var_value
  (** Returns the session ID without checksum *)

val create_anchor_event : dialog_type -> var_value list -> var_value
  (** Add an anchor event and return the identifier *)

val create_xanchor_event : dialog_type -> var_value list -> var_value
  (** Add an indexed anchor event and return the identifier *)


(* ======================================================================
 * History:
 * 
 * $Log: wd_var_functions.mli,v $
 * Revision 1.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 1.5  2005/06/02 21:14:35  stolpmann
 * Improved the configure script a bit.
 *
 * Revision 1.4  2004/12/12 17:57:32  stolpmann
 * 	Added <q:wd-link> and <q:wd-xlink> to generate links for
 * applications that cannot use Javascript. Limited functionality, however.
 * See stdlib.xml for details.
 *
 * Revision 1.3  2003/02/16 01:07:03  stolpmann
 * 	size, substring, width: string positions are measured as
 * the number of characters, not as the number of bytes
 *
 * Revision 1.2  2002/11/03 20:56:56  stolpmann
 * 	New functions: translate, rev_translate
 *
 * Revision 1.1  2002/10/20 19:38:18  stolpmann
 * 	Initial revision
 *
 * 
 *)
