GroupWare API
-------------

Copyright (c) 1999-2022 IceWarp Ltd. All rights reserved.

                                                                                                               
(*

Overview
--------
                                     
IceWarp GroupWare is a fully compliant DB driven collaboration server which has a proper API interface.

All clients and server modules utilize this API (including WebClient, ActiveSync, Outlook Sync, WebDAV etc).
The ideal scenario is that you use WebDAV or CalDAV which leaves no space for server implementation error.
Should you choose to go with this low level API instead make sure you are familiar with the database structure
which can be explored in the calendar.xml file including all field type values and comments. You will never connect
directly to the DB server however.

There are several methods to connect to groupware and use the API. You can use the COM interface,
BEEP protocol (TCP/IP), icewarpphp PHP extension, RPC or indirectly via WebDAV, ActiveSync etc.
It is highly recommended to get familiar with the GroupWare API Tool first.
http://www.icewarp.com/download/tools/gwtool.zip

For examples and usage see the PHP class gw.php.

BEEP http://www.rfc-editor.org/rfc/rfc3080.txt
TLS is supported too
Content-Type for each function call must be "application/icewarp-calendar"
Msg structure: Base64Encode(FunctionName ";" Param1 ";" Param2 ";" Param3 ";" Param4)

For RPC the URL is http://<server>/rpc/gw.html and you must call the API functions described in this document (do not mix with FunctionCall).
See more information about RPC at http://www.xmlrpc.com/

The API (except RPC) has been designed so all calls are in only one wraping function described below:

string FunctionCall(string funcName, string param1, string param2, string param3, string param4)


Examples
--------

COM:
gw = new COM('IceWarpCOM.GroupWare');
gw.Connect('server'); // Not required if run locally
sess = gw.FunctionCall('loginuser', 'john@doe.com', 'pass');
gsess = gw.FunctionCall('opengroup', sess, '*');
list = gw.FunctionCall('getfolderlist', gsess);
gw.FunctionCall('logoutuser', sess); // Always call logoutuser to free the server session
gw.Disconnect(); // Not required if run locally


PHP:
<?
  define('SHAREDLIB_PATH', get_cfg_var('icewarp_sharedlib_path'));
  include(SHAREDLIB_PATH . 'api/gw.php');

  $gw = new IceWarpGWAPI();
  $gw->user = 'john@doe.com';
  $gw->pass = 'pass';
  $gw->Login();
  $gid = $gw->OpenGroup("*");
  $list = $gw->FunctionCall('getfolderlist', $gid);
  $gw->Logout();
?>


RPC:
HTTP POST to /rpc/gw.html
<methodCall><methodName>LoginUser</methodName><params><param><value><string>john@doe.com</string></value></param><param><value><string>pass</string></value></param></params></methodCall>


Function Parameters
-------------------

funcname - function name from the API
param1..param4 - proper values for the API function <funcname>

There are several types of function parameters depending on the action.


Add:
Parameters contain an URL encoded field value string where each field contains a value in the following format.

Eg:
EvnNote=Note%20Here&EvnClass=T

Non-mandatory parameters specify an edit/update function of an existing record.
All add functions return the item ID of the inserted item or boolean result for updated items if successful.


List:
All list functions return an array of URL encoded lines. The first line contains the database field names
and following lines contain the values for the fields (according to their order).

Eg:
EVN_ID&Evn_EditCounter& CRLF
1234567&0&
2345678&1&


Where:
Where allows you to specify additional condition for the SQL statement. Use only simple statements
and beware of database specifics. Database specifics are dealt with automatically (escaping etc.).
When using LIKE escaping, use the following escaping syntax (exact case match):

LIKE '...' {ESCAPE '\'}


Eg:
EvnClass='E'
or
EvnTitle LIKE '%meeting\_1%' {ESCAPE '\'}


Attributes:
Some list functions allows you to specify attributes. Attributes are used to set special behavior to
the list function. The following syntax and parameters is used:

order=<fields> ["DESC"]         ; sort results by fields
position=<index>                ; start listing at <index> position
limit=<count>                   ; limit number of returned lists to <count>

Each attribute is separated with semi-colon.
Eg:
order=EvnTitle, EvnLocation DESC; limit=1000


Interval:
The interval parameter can be used in several functions. It can contain local date, local date and time,
UTC date, UTC date and time and a VTIMEZONE object for querying floating time objects:

(JDStart ["." JTStart] "-" JDEnd ["." JTEnd]) ";" ([UTC]) ";" ([VTIMEZONE]) ";" ([JDEndAdd]) ";" ([URIParams])

JD        - Julian date
JT        - Julian time as a frac of SecondsFromMidnight / SecsPerDay
UTC       - "Z" specifies a UTC date/time format, blank stands for local date/time
VTIMEZONE - VTIMEZONE object as in iCal RFC (URL encoded)
JDEndAdd  - Add number of days to JDEnd

Eg:
2454718-2454719
2454718.10446-2454719.10446;Z

URIParams - Lets you specify additional interval attributes:
  max=<value>   - returns max number of results
  use_tzid=0/1  - instructs the function to recalculate local time of EvnDate/Time to owners TZID setting


Function Reference
------------------

*)

Type
  TEventInfo = Class(TRetainable)
    Public
      Day: Integer;
      Time: Integer;
      Id: AnsiString;
      Data : AnsiString;

      Function CompareWith(ADay,ATime: Integer;AID: AnsiString): Integer;
      Class Procedure DecodeTimeInfo(S: AnsiString; Out Day,Time: Integer; Out ID: AnsiString);
      Class Function EncodeTimeInfo(Day,Time: Integer;ID: AnsiString): AnsiString;
  End;

  TEventInfoList = Class(TGenericList<TEventInfo>)
    Private
      Function CompareMethod (Item1, Item2: Pointer): Integer;
    Public
      Procedure SortIt;
      destructor Destroy; override;
  End;


// --------------
// Authentication
// --------------

Function LoginUser(EmailAddress, Password: AnsiString; IP: AnsiString = ''; Options: AnsiString = ''): AnsiString;
// Logs in the user with the email address password and IP connected to. If successul the function
// returns the SessionID which has to be used for other functions.
//
// To login anonymously use blank EmailAddress or "anyone". In such case a new anonymous session will be created with read only rights.
// Options: Method|Challenge|RemoteIP
//  Method: authentication method, one of MD5, SHA1, CRAM-MD5, DIGEST-MD5, PLAIN, SYNCML-MD5; default is PLAIN
//  Challenge: challenge string for some authentication methods
//  RemoteIP: client IP - not used


Function AuthenticateChallenge(ccP: Pointer = Nil): AnsiString;
// Returns the challenge string for authentication. The P is an internal parameter and will be ignored.

Function Authenticate(EmailAddress, Hash: AnsiString; IP: AnsiString = ''; Options: AnsiString = ''; _P: Pointer = Nil): AnsiString;
// Authenticates the user using the Options (Scheme "|" Challenge). Hash is the calcualted digest using the challenge string and the password.
// By default CRAM-MD5 authentication scheme is used. Supported schemes are (PLAIN, MD5, SHA1, CRAM-MD5, DIGEST-MD5, SYNCML-MD5)
// The result is the SessionID if successful.

Function LogoutUser(SessionID: AnsiString): Boolean;
// Logs out the user and terminates all group sessions. The GroupWare uses persistent sessions
// so if you do not log out the session will remain on the server and time out after some time. During
// this time you can reuse the session anytime. To check if it is still active use the UserLoggedOn.

Function SubstituteUser(SessionID: AnsiString; Email: AnsiString): Boolean;
// Lets you become someone else. Only super user can call this function.
// It is not possible to revert the session back to superuser.


// -------
// Session
// -------

// Lock/Unlock

Function Lock(SessionID: AnsiString): Boolean;
Function Unlock(SessionID: AnsiString): Boolean;
// These function are transaction lock and unlocks. They allow you to perform a lock, then insert/updates, notifications
// and unlock which will result in commit. Groupware transactions are write only, meaning you cannot see your changes
// made within a transaction in listing functions. You always need to perform Unlock for that.
//
// Some functions automatically use transactions internally. These are all add and delete functions.
// If you use the low level groupware access you should use transactions. If you use high level (versit functions)
// they are used automatically. However if importing a known number of vcards for instance you might want to perform
// a lock before importing them all so the whole process is really quick.

// Owner

Function GetOwnerInfo(SessionID: AnsiString): AnsiString;
// Returns the owner's details

Function UpdateOwnerInfo(SessionID: AnsiString; Parameters: AnsiString): Boolean;
// Set the owner's details.

Function RenameOwner(SessionID: AnsiString; OldEmail, NewEmail: AnsiString): Boolean;
// Rename owner's email address (admin only).

Function GetShareAccountList(SessionID: AnsiString; Flags: Longint): AnsiString;
// Returns the list of all accounts sharing resources to the owner of this session
// Flags is a bit value and can specify additional items to return
//
//  Bit0 - Accounts sharing resources to the owner
//  Bit1 - Groups the owner is a member of (including the domain itself)
//  Bit2 - Same as Bit1 but groups will be expanded (use Bit1 or Bit2, not simultaneously)
//
//  Bit3 - Requests names to be returned (OwnerName) (for all results)
//  Bit4 - Ignore public folder accounts (for Bit0)
//  Bit5 - Output Flags if account is a public group (for Bit0)
//  Bit6 - Add "anyone" user to the result
//
// Returns:
// FrtEmail Flags OwnerName

// Groups

Function GetGroupList(SessionID: AnsiString; EmailAddress: AnsiString = ''): AnsiString;
// Returns the list of all valid groups for the session. If EmailAddress supplied
// a group of that account will be queried for the list (if trusted user).
//
// GRP_ID - ID of the group
// GRPOWN_ID - ID of the owner
// GrpLink - Link/reference to the real group from this virtual group
// GrpLinkFolder - Link/reference to the real subscribed folder
// GrpTitle - Description and title for public / shared group

Function SubscribeUser(SessionID: AnsiString; EmailAddress: AnsiString; SubscribeAs: AnsiString = ''): AnsiString;
// Subscribes a shared calendar of user and returns the new GRP_ID of the calendar
// To unsubscribe call the Unsubscribe() function.

Function Unsubscribe(GroupSessionID: AnsiString; Folder: AnsiString): Boolean;
// Unsubscribe subscribed user or folder.
// Example:
//    Unsubscribe user   - Unsubscribe($gid, "~john@doe.com");
//    Unsubscribe folder - Unsubscribe($gid, "~john@doe.com\Calendar");
//
// You cannot unsubscribe folders under subscribed account, it causes error.

Function OpenGroup(SessionID, GroupID: AnsiString; DefaultTitle: AnsiString = ''; _Flags: Longint = $00): AnsiString;
// Opens the group from the group list. A special groupid "*" stands for all user's groups and blank GroupID only the primary group.
// If successful a groupsessionid will be returned.
//
// It is also possible to open a shared group account directly via GroupID eg. "~john@doe.com" for instance.
// This way you can get directly access to the group of such account.
//
// DefaultTitle lets you specify the prefix for shared account group.

Function CloseGroup(GroupSessionID: AnsiString;ExcludedGroupSessionID: AnsiString ='';_DontShrink: Boolean = False): Boolean;
// Closes an open group

Function GetGroupAccessRights(GroupSessionID: AnsiString; Folder: AnsiString = ''): AnsiString;
// Returns the bit rights for the group session. See more details for GetFolderRightList and its possible bit values.

Function AddGroup(SessionID: AnsiString; Parameters: AnsiString; GroupID: AnsiString = ''): AnsiString;
// Only owners can add new groups. Group is a collection for all objects and can can have
// different share modes and properties. By default every user has only one group.
//
// GroupID can be blank if you want to edit the currently open group. In such case SessionID must contain the GroupSessionID

Function DeleteGroup(SessionID: AnsiString; GroupID: AnsiString): Boolean;
// Delete existing group from the list.

Function ExportGroup(GroupSessionID: AnsiString; UserID: AnsiString = ''; DSN: AnsiString = ''): AnsiString;
// Exports all group data to XML

Function ImportGroup(GroupSessionID: AnsiString; Data: AnsiString): Boolean;
// Imports all group data from XML

Function ExportData(SessionID: AnsiString; List: AnsiString): AnsiString;
// Export list of users to xml structure

Function RestoreDataFromDB(SessionID: AnsiString; UserEmail: AnsiString; DSN: AnsiString; Flags: Integer =0): Boolean;
// Restores GW data of give anncounts from backup of database


Function ImportData(SessionID: AnsiString; Data: AnsiString): Boolean;
// Import xml structure created with ExportData function

Function DeleteGroupObjects(GroupSessionID: AnsiString): Boolean;
// Deletes all objects from the group.

Function GetGroupOwnerEmail(GroupSessionID: AnsiString): AnsiString;
// Returns the email address of the group owner

Function GetGroupOwnerID(O: TGWSessionObject;FI: NativeInt): AnsiString;
// Returns the ID of the group owner


Function DeleteOwner(SessionID: AnsiString; EmailAddress: AnsiString; DataOnly: Boolean = False): Boolean;
// Deletes account from groupware with all its groups and properties.
// Only superuser or administrator can do this and it is used by the account management system.

Function CreateUser(SessionID: AnsiString; EmailAddress: AnsiString; Flags: Longint = $00): AnsiString;
// Creates a new user in the groupware. The user does not need to exist as email account on the server.
// The result value is the new ownerid. Only superuser can create new users.

Function GetUserSettings(SessionID: AnsiString): AnsiString;
Function SetUserSettings(SessionID: AnsiString; Settings: AnsiString): Boolean;
// Get and set user settings and attributes. See the xml settings structure below.
// SessionID can be blank to query global server settings

(*

<settings>
  <forwarder>
    <forwardto/>
    <null/>
  <forwarder/>

  <responder>
    <mode/>
    <after/>
    <message/>
    <between/>
  </responder>

  <rules>
    <content/>
  </rules>

  <password>
    <newpassword/>
  </password>

  <bwlist>
    <white/>
    <black/>
  </bwlist>

  <folders>
    <mail/>
  </folders>

</settings>

*)


// Holidays

Function GetHolidays(SessionID: AnsiString; CS: AnsiString; Search: AnsiString = ''): AnsiString;
// Returns all system holidays containing the selected flag (holidays selected by the user)
//
// CS (CalendarService) - "holiday" / "weather" / "all"
// Search - lookup new location for "weather" CS, URL-like notation
//             i.e.  lang=CZ&location=Prague

Function AddHoliday(SessionID: AnsiString; Parameters: AnsiString; CS: AnsiString): Boolean;
// Adds a new holiday

Function DeleteHolidays(SessionID: AnsiString; CS: AnsiString; ID: AnsiString = ''): Boolean;
// Deletes all holidays selected flag or only the specified HolidayID

Function ImportHolidays(SessionID: AnsiString; CS: AnsiString): Boolean;
// Imports holiday .ics files into calendarservice user
// Only superuser can call this function.



// -------
// Tickets
// -------

Function OpenTicket(SessionID: AnsiString; Ticket: AnsiString; Param: AnsiString = ''): AnsiString;
// Lets you open a ticket and returns a GroupSessionID to the ticket. You can then
// read the folder content and perform actions based on your rights. Tickets can be used for
// anonymous access so once a Ticket is known it can be used by anybody.
//
// Ticket is a logical secret token containing parameters and attributes of the ticket.
// Param can be used for additional functionality.
//
// info      - Returns XML information about ticket
//
// Apart from the params below there is also:
//
// group     - GroupID of the group
// folder    - FolderID
// key       - Authentication key

Function CreateTicket(GroupSessionID: AnsiString; Params: AnsiString): AnsiString;
// Creates a new ticket from the currently open folder. Use Params to specify the ticket
// properties. Is is also possible to create a ticket URL with GetAttachmentPath(..., 'TICKET').
//
// Params:
//
// rights      - Rights for the ticket owner
// expire      - Expiration of the ticket (unix timestamp)
// id          - ItemID/AttachID
// zip         - Zip file and id contains a list of ids separated with |
// short       - 0 = off |1 = on (suitable for MS Office because of shorter URL, the original ticket
//                                is stored in the Tickets table with 7 days of validity)



// ------
// Folder
// ------

Function UpgradeTasks(Version: AnsiString; Force: AnsiString): AnsiString;
// sets internal version of GW Database if not already set
// Force - sets the internal version regardless on it being already set
// returns info if GW needs to be restarted

Function DBTasks(SessionID:AnsiString; Conn: AnsiString; Task: AnsiString): Boolean;
// performs DB operation with database given by connection string conn
// Task - one of "create","drop"
// superadmin SessionID required


Function GetFolderUpdate(SessionID: AnsiString): Integer;
// Returns the update ID. The client should remember this value and instead of UserLoggedOn call this function.
// If the ID changes it means there has been a change of folders on the account and client should refresh the list.
// If 0 is returned the session exists no more.

Function GetFolderList(GroupSessionID: AnsiString; OtherSelect: AnsiString = ''): AnsiString;
// Returns the list of folders
// OtherSelect lets you specify additional fields to return
//
// FDR_ID      - ID of the folder
// FDR_PARENT  - ID of the parent folder
// Fdr_Created - unix time stamp of the folder
// Fdr_Default - 1 if default folder
// FdrType     - Type of the folder
//
// GrpLinkFolder - if the folder is visible thanks to folder subscription, here is the responsible subscribed folder
// GrpShareType - 'U' - Personal, 'S' - Shared, 'P'- Public , 'R' - Resource
// If the groupsessionid is a link to "*" group then all folders in all groups will be returned.

Function GenerateFolderId(GroupSessionID: AnsiString): AnsiString;
// Generate unique  for folder
// Use it together with setting FdrDisplay

Function AddFolder(GroupSessionID: AnsiString; Folder: AnsiString; Type_: AnsiString; Parameters: AnsiString): Boolean;
Function DeleteFolder(GroupSessionID: AnsiString; Folder: AnsiString; Attrib: Longint = 0): Boolean;
Function RenameFolder(GroupSessionID: AnsiString; OldFolder, NewFolder: AnsiString): Boolean;
// Manages folders
//
// AddFolder can be used to susbcribe a shared account if folder name as ~john@doe.com.
// DeleteFolder can be also used to unsubscribe shared account. In such case only the shared root folder name
// must be used and the account will be automatically unsubscribed.
//
// You can utilize the "F" files folder link to a real file system directory using the Parameters - FdrParam field.
// In such case FdrParam must contain an attribute "path=<fullpath>" and it will gain access to the <fullpath> directory
// thru the files folder.

Function SetDefaultFolder(GroupSessionID: AnsiString): Boolean;
// Clears the previous default folder of the same type and sets the new folder to be default.
// Default folders are required in some applications.


Function GetFolderInfo(GroupSessionID: AnsiString; Reload: Boolean = False): AnsiString;
// Returns the folder session information. Reload ensures to read fresh data from the database and updates the groupsession information.
// FDR_ID, FDR_PARENT, Fdr_Created, Fdr_Default, FdrType, FdrParam, FdrPublic, FdrShared, FdrOwner
//
// FdrShared
// 0 - Primary folder
// 1 - Public folder
// 2 - Shared folder

Function OpenFolder(GroupSessionID: AnsiString; AFolder: AnsiString; AutoSubscribe: Boolean = False): AnsiString;
Function CloseFolder(GroupSessionID: AnsiString;_DontShrink: Boolean = False): Boolean;
// Get access to folder items and close access. The function opens a specified folder and returns a foldersessionid.
// Use OpenFolder and the resulting FolderSessionID to access folder items.
// AutoSubscribe lets you open a folder of a shared account even if the account is not subscribed.
// In such case shared user's folder will be returned in GetFolderList() after calling OpenFolder()
//
// It is possible to open multiple folders simultaneously using a virtual folder mode.
// These folders will be combined in all list and action functions. This means that you can search multiple
// folders or display multiple interval events in just one call. In such case separate multiple folders with
// CRLF in the Folder parameter. All functionality will be preserved and even Add functions will work.
//
// You can easily open a shared account folder that has not been subscribed yet with
// OpenFolder(GroupSessionID, '~john@doe.com'). In such case a new folder list will be returned in GetFolderList
//
// There is a special folder named @@GAL@@ which allows you to open GAL (Global Address List) without a groupware license
// capability. In such case all GAL folders will be opened and a virtual folder session id will be returned. @@GAL@@ can
// be also used in general virtual folder mode combined with other folders.
//
//
// Eg.:
// $sessid = LoginUser()
// $groupsessid = OpenGroup($sessid, "*");
// $foldersessid = OpenFolder($groupsessid, "@@GAL@@")
// $list = GetContactList($foldersessid)
// CloseFolder($foldersessid)
//
// Special folder names:
// @@DEFAULT@@#<FdrType> - Default folder for FdrTtoe
// @@ALL@@#<FdrType> - All folders mode of FdrType
// @@PERSONAL@@#<FdrType> - All personal folders mode of FdrType
// @@PUBLIC@@#<FdrType> - All public folders mode of FdrType
// @@GAL@@ - GAL folders
// @@TRASH@@ - Trash folder for deleted items
//
// Eg.:
// $foldersessid = OpenFolder($groupsessid, "@@DEFAULT@@#C") // Open the default contacts folder

Function OpenFolderByEventId(GroupSessionID: AnsiString; EventId: AnsiString; Params: AnsiString): AnsiString;
//automatically opens folder where the event belongs to


Function GetFolderRightList(GroupSessionID: AnsiString; Folder: AnsiString; MyRights: Boolean = False; Flags: Longint = $00; _Params: AnsiString = ''): AnsiString;
Function AddFolderRight(GroupSessionID: AnsiString; Folder: AnsiString; Email: AnsiString; Right: Longint): Boolean;
Function AddFolderRightExt(GroupSessionID: AnsiString; Folder: AnsiString; Email: AnsiString; Params: AnsiString; _Params: AnsiString =''): Boolean;
Function DeleteFolderRight(GroupSessionID: AnsiString; Folder: AnsiString; Email: AnsiString): Boolean;
Function GetRightList(GroupSessionID: AnsiString): AnsiString;
// Folder access list right management (ACL). ACL is automatically hiearchic (natural inheritance) and controls the whole access behavior.
// Only users with Admin access rights can use these functions.
//
// GetFolderRightList returns also Frt_Folder field which contains the original folder name rights are inherited from.
//
// Email (FrtEmail) types:
// Email          - ordinary email address of the user
// Group / Domain - any system domain or groupname using the "[" group "]" notation
// Anyone         - default rights for everyone using the value "anyone"
// @              - in such case rights will be inherited from parent
//
// These types have their value/priority and email having the highest. If "anyone" has zero right, [group] read only and email full
// rights (all for the same account), the full rights of the user will be used.
//
// Rights (FrtRight):
// FrtRight can be of two types. A bit value or constant value. This is distinguished by checking the most left bit and
// if set bit value is used otherwise the constant values.
//
// Bits (with their IMAP ACL representation):
//  Bit0  - Owner (Read only)
//  Bit1  - Items Write          (i)
//  Bit2  - Admin Administer     (a)
//  Bit3  - Items Delete         (t)
//  Bit4  - Items Modify         (w)
//  Bit5  - Folder Read          (l)
//  Bit6  - Items Read           (r)
//  Bit7  - Folder Write         (k)
//  Bit8  - Folder Delete        (x)
//  ...
//  Bit12 - Admin Invite         (z)
//  Bit13 - Admin Remove         (y)
//  Bit14 - Folder Rename        (v)
//  Bit15 - Items Edit Documents (u)
//  ...
//  Bit31 - 1 indicates bit value
//
// Obsolete constants (do not use):
//  0 - frRead                   (lr)
//  1 - frReadWriteModifyDelete  (itwlr)
//  2 - frAdmin                  (iatwlrkx)
//  3 - frReadWrite              (ilr)
//  4 - frReadWriteModify        (iwlr)
//  5 - frNone                   ()
//
//  AddFolderRightExt - 4-th parameter Params contains url-like parameters
//                     -right  (see FrtRight)
//                     -suppressaclnotification  (bool, set to 1 to not allow ACL notification be generated for this change)
//     e.g.:    right=-2147483552&suppressaclnotification=1
//
// Special folder names:
//      - Root
//  \   - IMAP groupped ACL
//
//   Params_   - parameters used only in internal calls


Function GetExpandedFolderMembers(GroupSessionID: AnsiString; Folder: AnsiString; Params: AnsiString = ''): AnsiString;
//  Returns end user accounts with at least read permission for given folder
//  Of permission is defined for a group, the group is expanded here
//  Filtering and paging possible
//
//  Params is URL like list of additional parameters
//      filter - string - fulltext search in primary email and Name
//             - url like list of fulltext search conditions (logical AND used):
//                         - email  (search in email)
//                         - name   (search in name)
//                         - everywhere  (search in email and name)
//      noexpand - boolean - if set to 1, the goups will not be expanded
//      from - integer , used for paging
//      to -  integer, used for paging. if missing, or set to zero, items are returned until the end is reached
//      otherselect - several extended info can be requested, list - items delimited by ,
//             - ownerid  (groupware own id of the member)


Function InviteGuest(FolderSessionID: AnsiString; GuestEmail: AnsiString; Params: AnsiString = ''): Boolean;
// this function invites person to selected teamchat room and creates a guest account if necessary
// FolderSessionId -  link to opened teamchat folder
// GuestEmail - email of the person to invite
// Params - uri like list of additionalparameters
//        - comment about invitation which will appear in the chat room
//        - name  name of the invited account

Function NotifyGuest(SessionID: AnsiString; GuestEmail: AnsiString; Params: AnsiString = ''): Boolean;
// This function is used to request email verification of a guest account
// SessionId - session id of autenticated superuser
// GuestEmail - Email of the guest account
// Params -  url like list
//          sender

Function CheckGuestSignature(SessionID: AnsiString; Operation: AnsiString; Params: AnsiString = ''): Boolean;
// This function is used in guest signup to verify if the identity/email of the guest
// SessionId - session id of autenticated superuser
// Operation - defines type of operation to check
//           - "0" - verify identity
//           - "1" - verify email
//
// Params - uri like set of parameters for checking
//        - email
//        - hash

Function KickRoomMember(FolderSessionID: AnsiString; MemberEmail: AnsiString): Boolean;
// this function kicks person from the selected teamchat room
// FolderSessionId -  link to opened teamchat folder
// MemberEmail - email of the person to kick


Function GetUrlInfo(SessionID: AnsiString; Url: AnsiString): AnsiString;
// This function is used
// SessionId - session id of autenticated superuser
// Url -  Url to analyze
//
// Params - uri like set of parameters (currently not used)
//        -
//        -


// -----
// Items
// -----

Function GetItemList(FolderSessID: AnsiString; Where: AnsiString = ''; OtherSelect: AnsiString = ''; Attributes: AnsiString = '';_Flags: Longint = $00): AnsiString;
Function GetItemCount(FolderSessID: AnsiString; Where: AnsiString = ''; Attributes: AnsiString = ''): Cardinal;
Function GetItemDetailList(FolderSessID: AnsiString; Where: AnsiString = ''; OtherSelect: AnsiString = ''; Attributes: AnsiString = ''): AnsiString;
Function GetItemDetailCount(FolderSessID: AnsiString; Where: AnsiString = ''; Attributes: AnsiString = ''): Cardinal;
Function GetItemInfo(FolderSessID: AnsiString; ItemID: AnsiString; Params: AnsiString = ''): AnsiString;
Function GetItemObject(FolderSessID: AnsiString; ItemID: AnsiString; Params: AnsiString = ''): AnsiString;
Function AddItemObject(FolderSessID: AnsiString; Data: AnsiString; ItemID: AnsiString = ''; Params: AnsiString = ''): AnsiString;
Function DeleteItem(FolderSessID: AnsiString; ItemID: AnsiString; KeepTables: Boolean = False; Params: AnsiString = '';_Attrib: Longint = 0): Boolean;
Function MoveItem(FolderSessID: AnsiString; ItemID: AnsiString; NewFolder: AnsiString; Params: AnsiString = '';_Deleted: Boolean = False; _ItemList: TAnsiStringList = Nil; _Condition: AnsiString ='';_DontMoveOcurrences: Boolean = False;ItmClass_: AnsiString = '';ComLinkExtras_: AnsiString = ''; CreatorEmail_: AnsiString = '';NoteText_: AnsiString = ''): Boolean;
Function CopyItem(FolderSessID: AnsiString; ItemID: AnsiString; NewFolder: AnsiString; Params: AnsiString = ''): AnsiString;
// General item functions which call the calendar / contact functions according to folder type
// The same rules applies as to functions below. Object functions work with vCard/vCalendar
// For low level calls you must use the calendar/ contact functions directly
//
// MoveItem can be used to move all items from one folder to another (if ItemID blank) or just a single item (does not work with @@TRASH@@)
// Source folder must have Delete rights and destination folder must have Write rights.
//
// To undelete an item from @@TRASH@@ folder use MoveItem(trashsessid, itemid, itemOriginalFolder).
//
// CopyItem can be used to copy all items if ItemID blank.
// DeleteItem can be used to delete all items if ItemID blank.


//Locking functions
const LockItem_LockedBySomeoneElse = 0;
      LockItem_LockedAsFirst       = 1;
      LockItem_LockedAlready       = 2;
      LockItem_LockedAsSecond      = 3;
      LockItem_LockingError        = -1;

      UnLockItem_LockedBySomeoneElse  = 0;
      UnLockItem_Unlocked             = 1;
      UnLockItem_NotLocked            = 2;
      UnLockItem_Error                =-1;

      LockAppMask_Webclient = 1;
      LockAppMask_Webdav = 2;

Function LockItem(FolderSessID: AnsiString; ItemID: AnsiString; App: Integer; Params: AnsiString ): Integer;
Function UnlockItem(FolderSessID: AnsiString; ItemID: AnsiString; App: Integer; Ultimative:Boolean): Integer;
// Provides a mechanism to lock and unlock items
//
// LockItem
//   Parameters
//      FolderSessionId
//      ItemId
//      App - identifier of application doing changes (1 = webclient, 2 = webdav, 4 = outlooksync, 8 = activesync, 16 = conversion process)
//      Params -  url like additional parameters (now only one parameter is supported)
//          lockinfo - string used to store lock information - this should be again url-like list (urlencoded as a whole of course)
//
//   Return Value
//      0 -  could not lock, because already locked by someone else
//      1 - locked, given application is the first app having this lock
//      2 - nothing done, already locked for this application
//      3 - locked, given application is not the first application having this lock
//     -1 - not locked due to some error
//
//
// UnlockItem
//   Parameters
//      FolderSessionId
//      ItemId
//      App - identifier of application doing changes
//      Ultimative - if set to true, also lock done by different aplications are removed
//
//   Return Value
//      0 -  could not unlock, because locked by someone else and caller does not have admin access rights
//      1 - unlocked
//      2 - nothing done, not locked for this application
//     -1 - not unlocked due to some error


// Revision functions
Function GetItemRevisionList(FolderSessID: AnsiString; ItemID: AnsiString; Expanded: Boolean = False): AnsiString;
// Revision list returns the list of available revisions
//
// In order to use GetAttachmentList() or GetAttachmentPath() you need to use the RevID parameter
// See description for both of these functions
//

Function DeleteItemRevision(FolderSessID: AnsiString; ItemID, RevID: AnsiString): Boolean;
// deletes given revision, revision is deleted directly, without going into trash

Function EditItemRevision(FolderSessID: AnsiString; ItemID, RevId, Params: AnsiString): Boolean;
// edits information associated with specific revision
// Params - url-like encoded parameters
//  supported parameters:
//                     revcomment

Function RevertToItemRevision(FolderSessID: AnsiString; ItemID, RevId: AnsiString): Boolean;
// replaces actual version of the documment with version from specific revision


Function NotifyAboutItemChanges(FolderSessID: AnsiString; ItemID, Parameters: AnsiString): Boolean;
// performs notification about changes to a specific document
// Parameters - url like list
// -   all   - if set to '1' , all users with read access mode to this document will be notified
// -   list  - additional email addresses where the notification will be sent to, use ; as email delimiter
// -   comment - optional message - will be placed at the top of the notification email

Function NotifyAboutItemSharing(FolderSessID: AnsiString; ItemID, Parameters: AnsiString): Boolean;
// sends public document url to given person
// Parameters - url like list
// -   email   -  recipient of the email


Function RevisionExistsForCurrentVersion(FolderSessID,ItemID: AnsiString): Integer;
// detects if actual version of the document has already a revision and hence there is no need to create revision
// return values:
//      0  - does not exist
//      1  - exists
//      -1  error

Function CreateRevision(FolderSessID: AnsiString; ItemID, Params: AnsiString): Boolean;
// Forces creating a revision, even if there were no changes
// Parameters of the form:   &revisioncomment=comment
//
//                revisioncomment - textual comment of the revision.
//



// --------
// Calendar
// --------

Function GetEventList(GroupSessionID: AnsiString; Where: AnsiString = ''; OtherSelect: AnsiString = ''; Attributes: AnsiString = ''; _Flags: Longint = $00): AnsiString;
Function GetEventCount(GroupSessionID: AnsiString; Where: AnsiString = ''; Attributes: AnsiString = ''): Cardinal;
Function GetAllIntervalEvents(GroupSessionID: AnsiString; Interval: AnsiString; Where: AnsiString = ''; OtherSelect: AnsiString = '';_Attrib: Longint = 0): AnsiString;
Function GetIntervalEvents(GroupSessionID: AnsiString; Interval: AnsiString; Where: AnsiString = ''; OtherSelect: AnsiString = ''): AnsiString;
// Returns a list of all Events for the group or the number of records
//
// Where specifies other SQL conditions.
//
// OtherSelect specifies what fields you want to return besides EVN_ID.
// Eg: EvnClass,EnvNote,'' As EvnOwnerEmail
//
// GetAllIntervalEvents and GetIntervalEvents returns events occuring in the given interval.
// GetIntervalEvents returns all events but without calendar services events.

Function GetIntervalEventsList(GroupSessionID: AnsiString; Params: AnsiString; Where: AnsiString = ''; OtherSelect: AnsiString = ''): AnsiString;
// Returns a list of Events for "daily agenda"
//
// Where specifies other SQL conditions.
//
// OtherSelect specifies what fields you want to return besides EVN_ID.
// Eg: EvnClass,EnvNote,'' As EvnOwnerEmail
//
// Params - url like list
//         limit    - max number of items to return
//         from     - hashed info of the interval start - for first call use empty string, for the next calls use the id returned on the first dummy line



Function GetEventDetailList(GroupSessionID: AnsiString; Where: AnsiString = ''; OtherSelect: AnsiString = ''; Attributes: AnsiString = ''): AnsiString;
Function GetEventDetailCount(GroupSessionID: AnsiString; Where: AnsiString = ''; Attributes: AnsiString = ''): Cardinal;
// Returns the same output as GetEventList plus joined recurrence and reminders, moreover Attributes can contain additional parameter use_tzid=1

Function GetEventInfo(GroupSessionID: AnsiString; EventID: AnsiString; Parameters: AnsiString = ''; _AllItems: Boolean = False): AnsiString;
Function AddEventInfo(GroupSessionID: AnsiString; Parameters: AnsiString; EventID: AnsiString = ''; RCRID: AnsiString = ''; _Params: AnsiString = ''): AnsiString;
Function DeleteEvent(GroupSessionID: AnsiString; EventID: AnsiString; KeepTables: Boolean = False; Params: AnsiString = ''): Boolean;
// Manages calendar objects
//
// Special handling for item completion is used. For proper functionality and integrated functions
// you should call AddEventInfo once more after editing has been completed with blank Parameters and
// specified EventID. This notifies the server the item is finished and can process subsequent tasks
// with it.
//
// KeepTables - Does not delete the extension tables
//
// There is a special use of extra virtual Parameters which automatically calculates Owner TZID shift for your local time
// Specify "use_tzid=1" in Parameters and extended recalculated Evn* and _TZ* fields will be returned (Owner must have the OwnTZID set)
//
// The same "use_tzid" can be used for adding items. In such case you can easily specify the local time of the owner's TZID event and date/time
// will be shifted accordingly. In a case of Z EvnTimeFormat you need to specify the "_TZID" param with the correct TZID and _TZEvn* fields which
// allows you to specify the local time of the event in the TZID (Evn* fields will be ignored but must be present in Parameters).
//
// There is also a special parameter meeting_action by which you can create or delete meeting (which is associated with the event).
//   "meeting_action=create" (or "meeting_action=1") - Creates a new meeting and associate it with the event (specified by EventID).
//                                         Internally it sets the Event(EvnMeetingId) column.
//   "meeting_action=delete" (or "meeting_action=0") - Deletes the meeting (and clears the Event(EvnMeetingId) column.
//
// Eg.
// GetIntervalEvents(events, ';;;;use_tzid=1', '', 'EvnTitle');
// GetEventInfo(events, '3f68528e5002', 'use_tzid=1&_tzexpdate=2455873');
// AddEventInfo(events, 'use_tzid=1&_tzid=Atlantic/Bermuda&evntimeformat=Z&evnstartdate=0&evnenddate=0&evnstarttime=0&evnendtime=0&_tzevnstartdate=2455874&_tzevnstarttime=480&_tzevnenddate=2455874&_tzevnendtime=540', '3f68528e5002');
//
// /* Create Meeting*/
// AddEventInfo(events, 'title=Meeting&meeting_action=start', '3f68528e5002');
//
// Revision Control
// ==================
// As  already mentioned, you should call AddEventInfo once more after editing has been completed with blank Parameters and
// specified EventID.  Among others, this activates the automatic revision creation. So either pass blank Parameters, or pass
// Parameters of the form:   forcerevision=1&revisioncomment=comment
//                forcerevision - if set to 1, revision will be created  anyway (even if autorevision is disabled, even if there were no changes)
//                              - if set to 0, revision will be created only if automatic revisioning is enabled and there were really changes to the document
//
//                revisioncomment - textual comment of the revision. If Empty, default generic comment is used. revisioncomment is ignored when forcerevision is set to 0
//
//   blank Parameters are equivalent to forcerevision=0&revisioncomment=&
//
//   GetEventInfo supports additional entry in "Parameters" - revision_extended  , if set to 1, additional column 'evnlockown_email' will be returned
//   i.e.  getiteminfo($fid,$itmid,'revision_extended=1');


Function GetvCalendar(GroupSessionID: AnsiString; EventID: AnsiString; Params: AnsiString = ''): AnsiString;
Function AddvCalendar(GroupSessionID: AnsiString; Item: AnsiString; EventID: AnsiString = ''; Params: AnsiString = ''): AnsiString;
// vCalendar of the calendar object (vEvent, vToDo, vJournal, vNote, File, etc.)
//
// Params specifies additional attribute parameters. See the list of supported parameters below and use ";" as delimiter.
// Parameter values are not URL encoded as ordinary API parameters.
//
// [FORMAT] - If additional parameters will be passed data format must be always present and separated with ";".
//            It can be blank for Versit/Iternet format or any of the following:
//
//            XML  - Versit converted to XML
//            SIF  - Funambol
//            EAS  - Exchange ActiveSync (supports format params eg. "EAS=2" (GAL request for GetvCard)
//            LDIF - LDAP LDIF
//            text/plain - A text plain value used for notes in some devices
//            application/vnd.omads-file+xml - OMA File object
//
// VERIFY   - Used to verify if the inserted item is already on ths server. In such case the item will
//            not be added and the id will be returned. A special compare and search method is used. Use only for slow synchronization.
// VERSION  - Specifies the versit version (1.0, 2.0, 2.1, 3.0, 4.0)
// FILTER   - List of versit attributes not to be returned, use "," as attribute delimiter, use prefix "+" to return only the specified list of attributes
// NOTIF    - Notification parameters sent to the notification server
// PARAMS   - Support of additional groupware fields which you would supply to AddEventInfo/AddContactInfo functions (such as EvnRID=Value or ItmRID=Value), use "&" delimiter for multiple fields, values of fields must be URL encoded as in other Parameters
// EXPAND   - The list of versit objects will be expanded including the original UID and RECURRENCE-ID (used in GetVCalendars and GetPublicVCalendar)
// MATCHUID - Search for the item's UID on the server and use its ItemID if found (internaly enables SETUID param)
// SETUID   - Tells the server to read UID from the versit object and set object with this UID in <Item>UID field, can be also used to enforce a specific UID if used as SETUID=
// EMBEDATT - Instead of using WebDAV URL to all server's attachments embed objects as base64
// ITEMLIST - Interval contains a list of IDs separated with ; (used in GetVCalendars and GetPublicVCalendar)
// EXRESULT - The result of Add*() function will be an extended list result instead of just an ID
// CIDFILE  - Specifies the MIME CID file for CID attachments
// FBFREE   - Returns also FBTYPE=FREE FREEBUSY items in the VFREEBUSY object (incompatible with Outlook so if you need it ask for it)
// FBUID    - Returns object ID in FREEBUSY response - only if sufficient rights
// WHERE    - Allows additional WHERE parameter for VFREEBUSY
// NOW      - Timestamp
// XPARMS   - Extra params
// NOGAL    - Skips GAL group synchronization for SetMyvCard calls
//
// Eg:
// ";FILTER=VALARM;EXPAND;PARAMS=EvnRID=ID&EvnFlags=2"
// "EAS;VERIFY"
//
// AddvCalendar supports iCalendar format with multiple VEVENT objects so a complete .ics file can be added easily

Function ProposeFreeFileName(FolderSessionID: AnsiString; OriginalFileName: AnsiString; ObjectId: AnsiString): AnsiString;
// proposes modification of the filename so that filenames are unique in folder
//
//   Parameters
//      FolderSessionId  - identifies the desired folder
//      OriginalFileName - name of the file to process -
//      ObjectID - in a scenario of rename, ID of the item being renamed
//
//   Return value
//                 If  adding/renaming file  to OrigFileName would not cause duplicity, OrigFileName is returned
//                 otherwise Orig file name is modified  - e.g.  file.pdf -> file(1).pdf


Function GetVCalendars(GroupSessionID: AnsiString; Interval: AnsiString; Where: AnsiString = ''; Format: AnsiString = ''): AnsiString;
// Returns iCalendar for all events in the given Interval
// Format is the same type as in GetvCalendar function
// The function is analogous to GetPublicvCalendar
//
// A special behavior can be achieved if passed ";ITEMLIST" in the Format parameter. In such case
// the Interval should not contain time parameter but a list of EVN_IDs that will be returned in one
// complex vcalendar object.

Function ProcessvCalendar(GroupSessionID: AnsiString; EventID: AnsiString; Item: AnsiString; Parameters: AnsiString): AnsiString;
// Processes iTIP / iMIP requests and handles all possible actions. Actions are placed in the Parameters
//   Action requests: REQUEST, PUBLISH, CANCEL, REPLY, COUNTER
//   Action replies: CANCEL, ADD, REPLY, DECLINECOUNTER
//   Action list: SEND_ITIP[=CcEmail],REFRESH
//
// Action to accept or decline invitation REQUEST
// "REPLY=ACCEPTED" or "REPLY=DECLINED"
//
// Action "SEND_ITIP" returns the list response consisting of these fields:
// Attendee, Status, Data
//
// "SEND_ITIP" processes the iTIP vcalendar object and processes iMIP (creates and sends iMIP message)
// It can also process the VFREEBUSY object request
//
// Action "REFRESH" returns the current groupware object based on the Item (iCalendar) data UID. Usually used to retrieve
// the object when received DECLINECOUNTER response from organizer.
//
// This special and multi purpose function can be used for different tasks. It can be used to simply process
// any vcalendar object, reply actions or even processing and creating an iMIP message. There are use
// cases for each type.
//
// 1. Process a vcalendar object
//
// ProcessvCalendar(GroupSessID, '', vCalendarData, '')
//
// Applies to METHOD: REPLY, CANCEL, ADD, COUNTER (results in acceptance of object suggested time), REQUEST (results in acceptance of invitation)
//
// 2. Create a vcalendar request
//
// ProcessvCalendar(GroupSessID, EventID, '', Action)
//
// Applies to all action requests above and returns the new vCalendar object that can be used with SEND_ITIP such as
//
// ProcessvCalendar(GroupSessID, '', vCalendarData, 'SEND_ITIP=manager@icewarp.com')
//
// The email here is optional and is used as a Cc email address (a copy of iTIP will be sent to it)
//
// 3. Reply to a vcalendar request
//
// ProcessvCalendar(GroupSessID, '', vCalendarData, 'REPLY=DECLINED')
// ProcessvCalendar(GroupSessID, '', vCalendarData, 'DECLINECOUNTER')
//
// Applies to Action: REPLY, DECLINECOUNTER
//
// Additional Parameters attributes:
//
// OwnerEmail=john@doe.com (specifies the real item owner, used for sending invitations on behalf of somebody else)
//
// Eg. REPLY=DECLINED&OwnerEmail=john@doe.com
//
// VersitParams=%3BCIDFILE%3D%5Ctemp%5Cid.eml (specifies the AddvCalendar parameters - in our example it would be ";CIDFILE=\temp\id.eml" urlencoded)
//
// Eg. &VersitParams=%3BCIDFILE%3D%5Ctemp%5Cid.eml
//
// DontUpdateMaster=1  (if enabled, organizers event is not updated with the info about accept/decline of an attendee)
//
// CalDAV RFC6638
// Parameters: RFC6638=&ACTION=<action>&LASTSTATE=
// Actions: EDIT,DELETE,LIST_INBOX,DELETE_INBOX
//
// EDIT,DELETE
// When using the RFC6638 command the function handles all operations automatically. It updates and deletes items in the calendar storage
// In most cases you should only pass the Versit object and the rest is handled by the server. The same can be issued with the DELETE action
// but in most cases you need the EVN_ID for this properly.
//
// LIST_INBOX
// Returns an xml containing all scheduling items from Inbox. LASTSTATE is the modseq to be used so only new items are processed
// uid, filename, ical
//
// DELETE_INBOX
// Deletes the uid from inbox. Returns 1 for success and 0 for failure
//



Function GetEventReminders(GroupSessionID: AnsiString; EventID: AnsiString): AnsiString;
Function AddEventReminder(GroupSessionID: AnsiString; EventID: AnsiString; Parameters: AnsiString; ItemID: AnsiString = ''): AnsiString;
Function DeleteEventReminders(GroupSessionID: AnsiString; EventID: AnsiString; ID: AnsiString = ''): Boolean;
// Manages calendar reminders

Function GetReminderList(GroupSessionID: AnsiString; Interval: AnsiString; Where: AnsiString = ''): AnsiString;
// Returns the list of reminder events in the given interval. This list is used by the server to send reminder notifications.
// ReminderUnixTime specifies the exact calculated reminder time in unix time format

Function GetEventRecurrence(GroupSessionID: AnsiString; EventID: AnsiString): AnsiString;
Function AddEventRecurrence(GroupSessionID: AnsiString; EventID: AnsiString; Parameters: AnsiString; ItemID: AnsiString = ''): AnsiString;
Function DeleteEventRecurrence(GroupSessionID: AnsiString; EventID: AnsiString; KeepRCRID: Boolean = False): Boolean;
Function GetEventRecurrenceEndDate(GroupSessionID: AnsiString; Interval: AnsiString; Parameters: AnsiString): Longint;
// Manages calendar recurrences
//
// GetEventRecurrenceEndDate returns the julian event end date based on the recurrence parameters. Interval must be the
// start of the event and the end date you want to have checked (usually should beStart + k)

Function GetEventException(GroupSessionID: AnsiString; RecurrenceID: AnsiString): AnsiString;
Function AddEventException(GroupSessionID: AnsiString; RecurrenceID: AnsiString; Parameters: AnsiString; ItemID: AnsiString = ''): AnsiString;
Function DeleteEventException(GroupSessionID: AnsiString; ItemID: AnsiString): Boolean;
Function MoveEventException(GroupSessionID: AnsiString; OldRecurrenceID: AnsiString; NewRecurrenceID: AnsiString; Where: AnsiString = ''): Boolean;
// Manages calendar recurrence exceptions

Function GetEventContacts(GroupSessionID: AnsiString; EventID: AnsiString): AnsiString;
Function AddEventContact(GroupSessionID: AnsiString; EventID: AnsiString; Parameters: AnsiString; ItemID: AnsiString = ''): AnsiString;
Function DeleteEventContacts(GroupSessionID: AnsiString; EventID: AnsiString; ID: AnsiString = ''): Boolean;
// Manages calendar attendees


Function AddEventReaction(GroupSessionID: AnsiString; EventID: AnsiString; Parameters: AnsiString): AnsiString;
Function GetEventReactions(GroupSessionID: AnsiString; EventID: AnsiString): AnsiString;
Function GetReactedEventList(GroupSessionID: AnsiString; Where: AnsiString = ''; OtherSelect: AnsiString = ''; Attributes: AnsiString = ''; _Flags: Longint = $00): AnsiString;
Function GetReactedEventCount(GroupSessionID: AnsiString; Where: AnsiString = ''; Attributes: AnsiString = ''): Cardinal;

// Manages Event reactions

Function AddEventPin(GroupSessionID: AnsiString; EventID: AnsiString; Parameters: AnsiString): AnsiString;
Function DeleteEventPin(GroupSessionID: AnsiString; EvnID: AnsiString; Parameters: AnsiString): AnsiString;
Function GetPinnedEventList(GroupSessionID: AnsiString; Where: AnsiString = ''; OtherSelect: AnsiString = ''; Attributes: AnsiString = ''; _Flags: Longint = $00): AnsiString;
Function GetPinnedEventCount(GroupSessionID: AnsiString; Where: AnsiString = ''; Attributes: AnsiString = ''): Cardinal;

Function GetCommentedEventList(GroupSessionID: AnsiString; Where: AnsiString = ''; OtherSelect: AnsiString = ''; Attributes: AnsiString = ''; _Flags: Longint = $00): AnsiString;
Function GetCommentedEventCount(GroupSessionID: AnsiString; Where: AnsiString = ''; Attributes: AnsiString = ''): Cardinal;


Function SetTeamchatFolderSubscription(GroupSessionID: AnsiString; Parameters: AnsiString): AnsiString;
//Manages folder subscription

Function SetTeamchatFolderInfo(GroupSessionID: AnsiString; Parameters: AnsiString): AnsiString;
//Manages folder info (title, purpose)

Function CallTeamChatPluginManager(ASessionID, ACommand, AParams, AFlags: AnsiString): AnsiString;
// Calls team chat plugin manager service method, more info in team chat plugin manager interface

Function GetAPITokens(SessionID: AnsiString): AnsiString;
Function DeleteAPIToken(SessionID,TokenId: AnsiString): AnsiString;
Function AddAPIToken(SessionID,TokenHash,OwnerEmail,Params: AnsiString): AnsiString;
//must be called within admin session



Function GetVFreeBusy(Email: AnsiString; Interval: AnsiString; Where: AnsiString = ''; Format: AnsiString = ''; _Originator: AnsiString = ''): AnsiString;
Function GetServerVFreeBusy(SessionID: AnsiString; Email: AnsiString; Interval: AnsiString; Format: AnsiString = ''): AnsiString;
Function GetGroupVFreeBusy(GroupSessionID: AnsiString; Interval: AnsiString; Where: AnsiString = ''; Format: AnsiString = ''): AnsiString;
// Returns the VFreeBusy versit object for the given interval.
//
// GetVFreeBusy is a public and anonymous function which should be used only to query local users such as in:
//
// http://server/freebusy/?john@doe.com
//
// GetServerVFreeBusy checks local freebusy status and also supports iSchedule protocol for remote servers and distributed domains


Function GetPublicVCalendar(Email: AnsiString; Interval: AnsiString; Where: AnsiString = ''; Format: AnsiString = ''): AnsiString;
// Returns iCalendar for the default calendar folder in the given Interval
// Format is the same type as in GetvCalendar function
//
// The result is "Internet Calendar" or .ics content used by many applications:
// http://server/calendar/?john@doe.com
//
// The user's share mode must not be set to Private and ACL applies.
// This means that the user must set "anyone" access rights for his default
// calendar folder or there will be no access to that folder.

Function ConvertVersit(SessionID, Data, Format: AnsiString): AnsiString;
// Converts a versit object to other formats and vice-versa
// Supported formats: XML, SIF, EAS, ''


Function ExtractVersitAttachment(SessionID, Data, AttId: AnsiString): AnsiString;
// returns base64 encoded versit attachment
// attachment is identified by id, returned by IW_ATTACH_ID attribute in convertversit call
// i.e. <ATTACH IW_ATTACH_ID="_1_13" X-ORACLE-FILENAME="PDF.pdf" FMTTYPE="application/pdf" VALUE="BINARY"/>

// --------
// Meetings
// --------

// Meeting functions allow to manage online meetings using several functions described bellow.
// each online meeting on the world is idetified by an unique string in form of   number@domain
// i.e.: 54545@mydomain.com
// the used domain name corresponds with domain used in Services/SmartDiscover for webclient
// Some GW functions support working with meetings which are not local (according to the domain part)
// In such case, the server checks the url and decides if it is local server. If it is not a local server,
// it performs the operation on the remote server (https://).
// This is true only for operation which do not require authentication (get,wait).
// If the domain part of an id is missing, it is always expected to be a local meeting


// Dealing with meetings provides some additional set of error codes
//   meetingMissingAccount  	      (101)
//   meetingInvalidMeetingInfo 	    (102)
//   meetingNotAuthenticated	      (103)
//   meetingInvalidMeetingID	      (104)
//   meetingSaveError			          (105)
//   meetingWaitFailure		          (106)
//   meetingWaitTimeout		          (107)
//   meetingCouldNotAuthenticate    (108)
//   meetingInvalidSessionId,	      (109)
//   meetingNotAccessMode		        (110)
//   meetingNotEnabled		          (111)
//   meetingParseError		          (112)
//   meetingOnlyOrganizerCanDoThis	(113)
//   MeetingRemoteIdNotSupported		(118)
//   MeetingRemoteHTTPTimeout 		  (119)
//   MeetingRemoteCouldNotConnect	  (120)
//   meetingRemoteDisconnected		  (121)
//   meetingRemoteGeneralError		  (122)
//   meetingListError = 123;
//   meetingLicenseError = 124;
//   meetingNotLicensed = 125;
//   meetingOnlySuperuserCanDoThis= 126;
//   meetingNotStarted = 127;
//   meetingInvalidEventID = 128;
//   meetingRecordingFileNotFound = 129;
//   meetingSIPPipeError = 130;
//   meetingSIPNoParticipants = 131;
//   meetingSpecialPermissionsRequired = 132;
//   meetingOrganizerMissing = 133;
//   meetingRecordingGWerror = 134;
//   meetingServerMisconfigured = 135;
//   meetingCouldNotStartDesktopSession = 136;




//   General Errors:
//   ----------------
//   meetingMissingAccount  majority of requests requires identification of the account who is doing the operation. If session is authenticated, this is taken from the authenticated account, otherwise it must be passed as a parameter
//   meetingInvalidMeetingInfo  bad format of request
//   meetingNotAuthenticated  command required authenticated session
//   meetingInvalidMeetingID  ID of non existing meeting used
//   meetingSaveError  internal error during saving data to server database
//   meetingCouldNotAuthenticate  authentication failed
//   meetingInvalidSessionId  non existing session id used
//   meetingNotAccessMode  authenticated user does not have access mode for meeting service
//   meetingNotEnabled  meeting service is disabled (not started)
//   meetingParseError  general error during parsing the request
//   meetingOnlyOrganizerCanDoThis  start,delete,modify can be performed only by organizer and creator. If organizer is empty, it can be performed by everybody (authenticated)
//   meetingOnlySuperuserCanDoThis - some operations are available only for superuser. E.g. GetMeetingCount
//
//   Specific errors:
//   ---------------------
//   meetingWaitFailure  internal server error during wait operation
//   meetingWaitTimeout  wait timeout, meeting was not started in the specified amount of time, another wait call can be performed
//   MeetingRemoteIdNotSupported	 - Meeting id indicates that the meeting is not on local server but the performed operation can be done only on local server
//   MeetingRemoteHTTPTimeout  - Connection to remote server timed out before geting result
//   MeetingRemoteCouldNotConnect - Cound Not Connect to the remote server
//   meetingRemoteDisconnected - remote server disconnected before sending all results
//   meetingRemoteGeneralError - general error in connection with comunication with remote server
//   meetingListError - general error in listing meetings;
//   meetingLicenseError  -License does not allow to start more concurrent meetings
//   meetingNotLicensed  - server does not have valid license for online meetings
//   meetingSIPPipeError  - co not communicate with VOIP server
//   meetingNotStarted - attempt to enable/disable recording or desktop session on non started meeting
//   meetingInvalidEventID  - attept to finish meeting recording with invalid parameters
//   meetingRecordingFileNotFound - attept to finish meeting recording with invalid parameters (non existing file)
//   meetingSIPNoParticipants - attempt to start recording of meeting without participants
//   meetingSpecialPermissionsRequired  - attempto to perform operation which only organizer or moderator can do
//   meetingOrganizerMissing - attempt to enable/disable recording of meeting without organizer
//   meetingRecordingGWerror - error in communication with GW service (check GW logs)
//   meetingServerMisconfigured - VOIP server not probably configured -  Either incorrect local ip is used in VOIp settings, or conference account is not registered to SIP
//   meetingCouldNotStartDesktopSession =  unknown error during starting desktop sharing session


Function LoginMeetingUser(EmailAddress, Password: AnsiString; IP: AnsiString = ''; Options: AnsiString = ''): AnsiString;
// Logs in the user (into meeting) with the email address password and IP connected to. If successul the function
// returns the SessionID which has to be used for other meeting functions.
//
// This function is similar to LoginUser but it creates a groupware session which is limited only to meeting functions. It's for security
// reasons. Thus with this groupware session you cannot do other groupware actions (like deleting contacts of folders).



Function AddMeetingInfo(SessionID: AnsiString; Parameters: AnsiString; MeetingID: AnsiString = ''; GWParams: AnsiString= ''): AnsiString;
//  This function is used to create/modify an online meeting. Only organizer or owner can do  the modification
//
//  SessionID  - id of a session, output of LoginUser or similar function, logged user has to have access mode for meeting API
//
//  Parameters - URL like notation, following parameters supported:
//     type -  has to be conference
//     dtstart,dtend  timestamps in UTC
//     organizer  person who will be able to start the meeting
//     summary -  textual description of the meeting (purpose,)
//
//     i.e.: type=conference&summary=hello
//
//  MeetingId - Id of the meeting to modify, or empty if new meeting has to be created
//
//     GWParams - URL like notation, following parameters supported:
//       folder - folder name used for specifying in which folder the meeting was created

//
// Return Value:
//   empty string in case of error
//   properties of the new meeting in URL like notation. Following properties are supported:
//
//    type
//    dtstart,dtend
//    organizer
//    summary
//    id  -  unique identifier of the meting, same as MeetingId in case of modify operation
//    last-mod,created - UTC timestamps of changes
//    createdby  account who created this meeting
//    started  indicates if the meeting was already started or not (nobody can connect to non started meeting)
//    information_url  - url to anonymous web page where everybody can view status of the meeting, wait until is started, join..
//    information_sip  - sip address where you should call to get into the audio conference.
//    information_body-  human readable info about all info about the conference, which could be sent to anybody
//    appletcode  base64 of source code of applet which client should add to the web page so that the desktop sharing application will be started. Will be filled after conference is started
//
//  Specific Error codes: MeetingRemoteIdNotSupported , meetingOnlyOrganizerCanDoThis



Function AddMeetingHistory(SessionId, MeetingID, Email, Params: AnsiString): AnsiString;
//  Creates History items for Planned conference or for Adhoc connection to meeting
//  SessionID  - id of a session, logged user has  to be GWsuperuser
//  MeetingID - id of the conference
//  Email  - primary email address of the user who called the parent method (can be empty, if the parent method was called anonymously)
//  Params - url-like notation - there shoule be filled RecordingsUri, RecordingsApiUri; for remote conference without local participant there also have to be - EvnTitle, MeetingUrl, EvnOrganizer




Function GetMeetingInfo(MyEmail: AnsiString; MeetingID: AnsiString; IncludeExtendedInfo: AnsiString; Callid: AnsiString): AnsiString;
//  This function is used to query information about online meeting. Caller does not need to be authenticated
//
//  MyEmail  - email of the user who is requesting the information
//
//  MeetingID - id of the meeting. This call supports also remote id's (it automatically connects to the proper server)
//
//  IncludeExtendedInfo - if set to '1', also extended real-time info is returned.
//                      participants  - list of meeting participants - the whole output of getmeetingparticipants function , url encoded
//                      recordinginprogress - '1' of recording is in progress
//
//                      - if set to 1&1, or 0&1 also url of HTML only viewer (if available) is returned in the appletparams

//
//  Credentials  - optional credentials - CallId - helps you to determine corresponding item of participantslist
//
//
// Return Value:  the same as the AddMeetingInfo  function
//                if IncludeParticipants equals '1', additional output parameter is appended
//
// Specific error codes: MeetingRemoteHTTPTimeout,MeetingRemoteCouldNotConnect,meetingRemoteDisconnected,MeetingRemoteGeneralError



Function DeleteMeeting(SessionID: AnsiString; MeetingID: AnsiString): Boolean;
// Deletes an existing conference. Only Creator or Organizer can do this
//
//  SessionID  - id of a session, output of LoginUser or similar function, logged user has to have access mode for meeting API
//
//  MeetingID - id of the meeting. This call does not support remoter ids
//
//  Return Value:  1  - meeting was deleted
//                 0  - error occured
//
// Specific Error codes: meetingOnlyOrganizerCanDoThis,MeetingRemoteIdNotSupported



Function StartMeeting(SessionId: AnsiString; MeetingID: AnsiString):AnsiString;
// Enables the conference. Before conference is started, nobody can call its telephone number
// or connect to its desktop sharing. Authentication needed  action can be performed only by creator or organizer
//
//  SessionID  - id of a session, output of LoginUser or similar function, logged user has to have access mode for meeting API
//
//  MeetingID - id of the meeting. This call does not support remoter ids
//
//  Params - URL-like list of parameters for future customizations (currently unused)
//
//  Return Value:  the same as the AddMeetingInfo  function
//
// Specific Error Codes: meetingOnlyOrganizerCanDoThis, MeetingRemoteIdNotSupported

Function StopMeeting(Credentials: AnsiString; MeetingID: AnsiString):AnsiString;
// Disables the conference. Authentication needed  action can be performed only by creator or organizer or by caller with special permissions
//
//  Credentials  - id of a session, output of LoginUser or similar function, logged user has to have access mode for meeting API and has to be organizer
//               - or CallId - the call has to have special permissions previously obtained from organizer by setting HasSpecialPermissions property to 1
//
//  MeetingID - id of the meeting.
//
//  Return Value:  the same as the AddMeetingInfo  function
//
// Specific Error Codes: meetingOnlyOrganizerCanDoThis, MeetingRemoteIdNotSupported



Function WaitMeeting(MyEmail: AnsiString; MeetingId: AnsiString; TimeoutStr:AnsiString =''): AnsiString;
// This is used by participants to effectively wait until organizer starts the meeting.
// I.e. this is kind of push method  participant is immediately notified about start of the meeting. No authentication needed.
//
//  MyEmail  - email of the user who is requesting the information
//
//  MeetingID - id of the meeting. This call supports also remote id's (it automatically connects to the proper server)
//
//  Timeout  - number of miliseconds - how long should server wait before returning timeout error,default is 120000 (2 minutes)
//
//
// Return Value:  the same as the AddMeetingInfo  function,The meeting info with updated fields for making the call or connecting
//                to the desktop sharing will be returned.
//
// Specific error codes: meetingWaitFailure,meetingWaitTimeout,MeetingRemoteHTTPTimeout,MeetingRemoteCouldNotConnect,meetingRemoteDisconnected,MeetingRemoteGeneralError

Function GetMeetingsList(SessionId: AnsiString): AnsiString;
// Get list of all meetings where the authenticated user is oranizer or owner.
// If this function is called by GW superuser, it returns all meetings (regardless on owner)
//
//  SessionID  - id of a session, output of LoginUser or similar function,
//               logged user has to have access mode for meeting API, or it has to be GWsuperuser
//
//  Return Value - list of meeting informations. Each line contains info about one meeting, form of each line is same as output of GetMeetingInfo, but contains less information

Function GetMeetingsCount(SessionId: AnsiString): Integer;
// Get number of currently running meetings
// This function has to be called by GW superuser
//
//  SessionID  - id of a session, output of LoginUser or similar function,
//               logged user has  to be GWsuperuser
//
//  Return Value - number of started meetings

Function GetMeetingParticipants(MeetingId: AnsiString; CallId: AnsiString =''): AnsiString;
// Get list of currently calling participants of a meeting
//
//  MeetingID  - id of the meeting. This call supports also remote id's (it automatically connects to the proper server)
//
//  CallId - optional, callid of the caller, if set, caller is denoted in the returned list
//
//  Return Value - List of calling participants - each line of result contains url-encoded info about one participant. Form is as follows:
//  name=myname&email=a@t.com&participantid=00417b46c404&cancontrol=0&ismuted=1&haspermissions=0&iscaller=1&role=0
//  participantid - unique id of this participant, used when setting properties of participants and when chatting
//  cancontrol - is set to 1 if the participant is calling using IceWarp conferencing page (and hence is capable of doing some control)
//  ismuted - is set to 1 if the participant was muted
//  haspermissions - is set to 1 if participant has been granted special permissions  (using ManageMeetingParticipant call)
//  iscaller - present only if valid CallId was passed,  It is set to 1 for the participant corresponding to the given CallId
//  role -    0 = participant
//            1 = manager  (equivalent to haspermitions ==1)
//            2 = organizer (meeting organizer calling from IceWarp Conference page)
//         There can be arbitrary number of participant of all roles. Organizer is only one, but he can be making several calls, hence listed here several times

Function ManageMeetingParticipant(Credentials: AnsiString; MeetingID: AnsiString; ParticipantId: AnsiString; Params:AnsiString): AnsiString;
//  This function is used to set special properties of a partucular participant. Caller needs to be authenticated, or has to have special permissions
//
//  Credentials  - This can be either  - id of a session (output of LoginUser or similar function), logged user has to be organizer of the meeting
//                                     - CallId  - the call has to have special permissions previously obtained from organizer by setting HasSpecialPermissions property to 1
//
//  MeetingID - id of the meeting. This call support remote id's, if "callid" was given inside Credentials
//
//  ParticipantId - id of the participant we want to set properties to (e.g. from getparticipantlist)
//
//  Params - url-like notation
//         - "property"  (0=Muted, 1=HasSpecialPermissions,2=OnlySpeaker[all others are muted],3-kill )
//         - "value"   - value of the given property
//
//
// Return Value:  '0'/'1'
//
// Specific error codes: MeetingSpecialPermissionsRequired, MeetingOnlyOrganizerCanDoThis, MeetingRemoteHTTPTimeout,MeetingRemoteCouldNotConnect,meetingRemoteDisconnected,MeetingRemoteGeneralError



Function StartMeetingRecording(Credentials: AnsiString; MeetingID: AnsiString; Description: AnsiString = ''): AnsiString;
Function StopMeetingRecording(Credentials: AnsiString; MeetingID: AnsiString): AnsiString;
Function ManageMeetingRecording(Credentials: AnsiString; MeetingID: AnsiString; Start: Boolean; Description: AnsiString = ''): AnsiString;
// StartMeetingRecording and StopMeetingRecording are only aliases for ManageMeetingRecording
//
// Start/stop recording of the meeging. Once recording is finished and post processed on the server,
// it is inserted into GW Files folder of the user who wanted it.
// The file can have assigned the specified description.
//
// Credentials:    - id of a session, output of LoginUser or similar function,logged user has to have access mode for meeting API
//                 - or CallId - the call has to have special permissions previously obtained from organizer by setting HasSpecialPermissions property to 1
//
// MeetingID    - id of the meeting. This call does not support remoter ids
//
// Description  - Optional description which will be saved into file's description (in the Files folder).
//
// Return Value - 1 - recording has started
//                0 - an error occured

Function FinishMeetingRecording(SessionID, MeetingID, EventID: AnsiString; Mp3Path: AnsiString): AnsiString;
// After the recording is finished client should call this function. It performs last actions on groupware items (e.g.
// it computes size of the mp3 file) and move the mp3 file into groupware attachments so the user has it available
// for download from his Files.
//
// Return value - url-encoded list with the following fields
//   result  - 0/1
//   error  - code of the error, present only if result!=1
// examples:
//  'result=1'
//  'result=0&err=54'


Function ManageMeetingDesktopSession(Credentials: AnsiString; MyEmail: AnsiString; MeetingID: AnsiString; Params:AnsiString): AnsiString;
//bacha aby moderator zakladal meeting do mikoga za sebe
// Start/stop desktop session of the meeging.
// Credentials:    - id of a session, output of LoginUser or similar function,logged user has to have access mode for meeting API
//                 - or CallId - the call has to have special permissions previously obtained from organizer by setting HasSpecialPermissions property to 1
//
//  MyEmail        - email of the user who is performing the operation
//
// MeetingID       - id of the meeting. This call supports remote ids
//
// Params           - Url like list,
//                     start=1/0    e.g. start=1
//
// Return Value    '0','1'


Function ProcessXMLCall(InputXML: AnsiString): AnsiString;
// General function encapsulating the GW functions into XML. It is mainly used in WCS GW API
//
// InputXML - specifies the GW call - Name of the function and list of parameter has to be provided
//
// <body xmlns="http://icewarp.com/groupware-api" rid="reqId" >
// <iq type="request">
//   <command>NameOfTheCommand</command>
//   <params>
//     <param>Parameter 1</param>
//     <param>Parameter 2</param>
//     <param>Parameter 3</param>//
//     <param>Parameter 4</param>
//   </params>
//  </iq>
//  </body>
//
//  Return value - XML defining the result. XML is returned even if error occurred
//
// OK response
// ------------
// <body xmlns="http://icewarp.com/groupware-api" rid="reqId">
//   <iq type="response">
//     <value>9dede&dede</value>
//   </iq>
// </body>
//
// body/iq/value - contains the string returned from called GW function
//
//  Error Response
// ---------------
//   <body xmlns="http://icewarp.com/groupware-api" rid="reqId">
//   <iq type="error">
//    <error_code>9</error_code>
//    <error>invalid sessionid</error>
//  </iq>
//  </body>
//
// Client MUST NOT use the human readable <error>, it has to use the <error_code>

Function ProcessExternalNotification(NotifFunction: AnsiString;Params: AnsiString): AnsiString;
// If external notification library is installed, this comamnd calls its main entry function and passes parameters


// --------
// Contacts
// --------

Function GetContactList(GroupSessionID: AnsiString; Where: AnsiString = ''; OtherSelect: AnsiString = ''; Attributes: AnsiString = ''): AnsiString;
Function GetContactCount(GroupSessionID: AnsiString; Where: AnsiString = ''; Attributes: AnsiString = ''): Cardinal;
// Returns a list of all contacts in the group or the number of records

Function GetContactDetailList(GroupSessionID: AnsiString; Where: AnsiString = ''; OtherSelect: AnsiString = ''; Attributes: AnsiString = ''): AnsiString;
Function GetContactDetailCount(GroupSessionID: AnsiString; Where: AnsiString = ''; Attributes: AnsiString = ''): Cardinal;
// Returns the same output as GetContactList plus joined locations

Function GetContactInfo(GroupSessionID: AnsiString; ContactID: AnsiString;Parameters: AnsiString = ''): AnsiString;
Function AddContactInfo(GroupSessionID: AnsiString; Parameters: AnsiString; ContactID: AnsiString = ''; _Params: AnsiString = ''): AnsiString;
Function DeleteContact(GroupSessionID: AnsiString; ContactID: AnsiString; KeepTables: Boolean = False; Params: AnsiString = ''): Boolean;
// Manages contact objects
//
// Special handling for item completion is used. For proper functionality and integrated functions
// you should call AddContactInfo once more after editing has been completed with blank Parameters and
// specified ContactID. This notifies the server the item is finished and can process subsequent tasks
// with it.
//
// KeepTables - Does not delete the extension tables


Function GetvCard(GroupSessionID: AnsiString; ContactID: AnsiString; Format: AnsiString = ''): AnsiString;
Function GetvCards(GroupSessionID: AnsiString; Where: AnsiString = ''; Format: AnsiString = ''): AnsiString;
Function AddvCard(GroupSessionID: AnsiString; Item: AnsiString; ContactID: AnsiString = ''; Params: AnsiString = ''): AnsiString;

Function GetMyvCard(GroupSessionID: AnsiString; Params: AnsiString = ''): AnsiString;
Function SetMyvCard(GroupSessionID: AnsiString; Item: AnsiString; Params: AnsiString = ''): Boolean;
// vCard of the contact object
// The same rules for Format apply as for AddvCalendar function

Function GetContactLocations(GroupSessionID: AnsiString; ContactID: AnsiString; Where: AnsiString = ''): AnsiString;
Function AddContactLocation(GroupSessionID: AnsiString; ContactID: AnsiString; Parameters: AnsiString; ItemID: AnsiString = ''): AnsiString;
Function DeleteContactLocations(GroupSessionID: AnsiString; ContactID: AnsiString; LocationID: AnsiString = ''): Boolean;

// Manages contact locations


// ------------------------
// Attributes, Tags & Attachments
// ------------------------

Function GetItemAttributes(GroupSessionID: AnsiString; ObjectID: AnsiString; Where: AnsiString = ''; ListOnly: Boolean = False): AnsiString;
Function AddItemAttribute(GroupSessionID: AnsiString; ObjectID: AnsiString; Value: AnsiString; Params: AnsiString): AnsiString;
Function DeleteItemAttribute(GroupSessionID: AnsiString; ObjectID: AnsiString; AttrID: AnsiString = ''; AttrType: AnsiString = ''): Boolean;
// Manages item attributes
// A groupware object can any number of attributes such as certificates, notes, x- attributes or any other
//
// For AddItemAttribute params must always contain AtrType and may contain AtrParam (case sensitive)
//
// AtrType:
//  note - note for notes objects
//  cert - certificate for contacts
//  x    - versit X- properties
//  tz   - versit VTIMEZONE object
//
// AtrParam - custom attribute parameters
// AtrID - Attribute ID for editing object


Function GetEventLastModified(GroupSessionID: AnsiString; Where: AnsiString = ''; Attributes: AnsiString = ''): AnsiString;
Function GetContactLastModified(GroupSessionID: AnsiString; Where: AnsiString = ''): AnsiString;
// Returns the list containing last item modification timestamp and item count in fields Max_ and Count_.
// Can be used to check if there has been any recent change in the folder.


Function GetTagList(GroupSessionID: AnsiString; Where: AnsiString = ''; Attributes: AnsiString = ''; Global: Boolean = False): AnsiString;
Function GetTagCount(GroupSessionID: AnsiString; Where: AnsiString = ''; Attributes: AnsiString = ''; Global: Boolean = False): Cardinal;
Function GetTagDetailList(GroupSessionID: AnsiString; Where: AnsiString = ''; Attributes: AnsiString = ''; Global: Boolean = False): AnsiString;
Function DeleteTag(GroupSessionID: AnsiString; Tag: AnsiString): Boolean;
Function AddTag(GroupSessionID: AnsiString; Tag: AnsiString; OldTag: AnsiString = ''; Parameters: AnsiString = ''): AnsiString;
Function SetItemTags(GroupSessionID: AnsiString; ItemID: AnsiString; Tags: AnsiString; _Params: AnsiString = ''): Boolean;
Function GetItemTags(GroupSessionID: AnsiString; ItemID: AnsiString): AnsiString;
// Manages tags and their list. These funtions are used automatically by vcard and vcalendar functions.
// Should you use low level API you are required to use them.
//
// GroupSessionID can take two different IDs. A global group session ID and in such case it will return all global Tags. A folder session ID and in such
// case it will return the folder Tags. Global variable indicates you want the global list even for foldersessid (used to get tags for shared/public folders).
//
// SetItemTags links an item (contact, event) with a list of tags.
// These tags are separated with comma
//
// In order to lookup item tags you need to use Where with {TAG}tagname{/TAG}
// Eg.
// GetContactList(foldersessid, '{TAG}Competition{/TAG} And {TAG}Favorites{/TAG}', '', '')


Function ConvertEvnColors(GroupSessionID: AnsiString; Params: AnsiString ): AnsiString;
// Converts old style Evn Colors to Tags
// Params  contain  URL-like mapping of Color IDs to new tag names, i.e.
//1=IMPORTANT&2=BUSINESS&3=PERSONAL&4=VACATION&5=MUST_ATTEND&6=TRAVEL_REQUIRED&7=NEEDS_PREPARATION&8=BIRTHDAY&9=ANNIVERSARY&A=PHONE_CALL


Function GetAttachmentList(GroupSessionID: AnsiString; ObjectID: AnsiString; Name: AnsiString = ''; RevID: AnsiString = ''): AnsiString;
// Returns list of all attachments for the object. Any object can have an infinite number of
// attachments including notes, contacts, tasks, journals, contacts etc.
//
// AttName   - ID of the attachment
// AttDesc   - Description or filename
// AttType   - F,I,U,P,T,D (F - File, I - Link [FolderType:FolderID:ItemID], U - URL, P - Photo, T - Thumbnail, D - PDF Thumbnail)
// AttSize   - Size of the attachment
// AttTime   - Unix time of the last update
// AttParams - Custom params (mimetype, imagetype)
//
// AttSkipValue - Special parameter to skip value (original content will be preserved)

Function GetAttachment(GroupSessionID: AnsiString; ObjectID: AnsiString; Name: AnsiString; RevID: AnsiString): AnsiString;
// Returns attachment for the object in binary

Function AddAttachment(GroupSessionID: AnsiString; ObjectID: AnsiString; Parameters: AnsiString; Value: AnsiString; _IsFileName: Boolean = False): AnsiString;
// Adds a new attachment with data and value in binary format
//
// Special conversion mechanism can be achieved using the Parameters parameter
// AttConvertName - Filename of the new attachment
// The AttName will be converted to AttConvertName as a new attachment. The old object will be preserved as a revision and replaced with the newly creatd one.


Function DeleteAttachments(GroupSessionID: AnsiString; ObjectID: AnsiString; ID: AnsiString = ''): Boolean;
// Deletes attachments. If ID is blank all attachments will be deleted.

Function GetAttachmentPath(GroupSessionID: AnsiString; ObjectID: AnsiString; AttName: AnsiString; Params: AnsiString): AnsiString;
// Handles the file path to attachment. Use this function when setting or retrieving attachments.
// When setting attachments always use AddAttachment with blank content and then LOCK and UNLOCK via this function.
//
// This function can also be used to retrieve the WebDAV URL of the item. In such case the AttName needs to be blank
// (applies to URL, TICKET parameterts).
//
// Params specifies additional attribute parameters. See the list of supported parameters below.
//
// URL     - Used to retrieve the attachment WebDAV URL
// TICKET  - Used to retrieve the attachment URL (ticket URL without the need of authentication), can contain an optional param with ObjectID/AttName list
// LOCK    - Locks and returns the file path to read or write
// UNLOCK  - Unlocks and frees the file previously locked with LOCK
// REVID   - Return file path to a revision
// PHOTOCACHE - Return thumbnail file to your contact or GAL address in ObjectID
//
// Additional param attributes can specify
// AttType - filters out the specific attachment type without the need to supply the AttName parameter

Function GetAttachmentPathLocal(GroupSessionID: AnsiString; ObjectID: AnsiString; AttName: AnsiString; Params: AnsiString): AnsiString;
// See the documentation of GetAttachmentPath.
// The only difference is, that this function returns copy in file named using just ASCII characters (if the original file contains nonascci chars)
// When UNLOCK is passed as parameter, temporary file contents are synced back to the original path
// The temporary file is updated on each getattachmentpath request, it is deleted at session end

Function GetGroupMemberList(GroupSessionID: AnsiString): AnsiString;
// Returns the expanded group member list of the current public folder

Function GetAvatarToken(ASessionID,AWho: AnsiString): AnsiString;
// Returns token suitable for getting avatar later
// ASessionID - user session the token will be valid for
// AWho - specifies which avatar to get

Function GetAvatarPath(AEmail, AAvatarToken, ALocal: AnsiString): AnsiString;
// Returns avatar path of given AEmail. AAvatarToken needed for auth.
// AEmail - user which avatar to get
// AAvatarToken - auth token previously generated by GetAvatarToken
// ALocal - if 1, path is returned in system local encoding (windows)

// --------------
// Other & System
// --------------

Function GetLastError(SessionID: AnsiString): AnsiString;
// Returns the error of the last failed function. Call this function only after
// the call to the previous function failed. Do not call this function to validate
// the success of previous calls.
//
// The error consists of:
// Code ":" Textual representation
//
// Possible error codes:
//  E_GLICENSE = 1;    // Server does not have the sufficient license
//  E_RIGHTS = 2;      // User does not have rights to perform this action
//  E_ACCESS = 3;      // User does not have access permissions to performs this action
//  E_DB = 4;          // Database error or no result returned
//  E_PARAMETERS = 5;  // No database record found
//  E_GROUP = 6;       // Group not found
//  E_NOTFOUND = 7;    // Not found
//  E_TOOBIG = 8;      // Size too big
//  E_VIRUS = 9;       // Virus
//  E_TRANSACTION = 10; // Transaction error
//  E_DUPLICATE = 11;  // Duplicate data during import
//  E_LOCKED = 12;      // Document is locked
//  E_FILE_ALREADY_EXISTS =13; // Document with the same file name exists in the specified folde

//
// Eg.
// 4:Specified key was too long; max key length is 768 bytes


Function Introduce(SessionID: AnsiString;ClientDesc: AnsiString; DeviceId: AnsiString = ''): Boolean;
// call after beginning of the session to clearly show in the logs  which client is doing that session
// allso some specific behavior for particular client can be triggered this way
//
// SessionID  - The session we want to set information for
// ClientDesc - Unique identifier for each client - suggested form is country.vendor.clientname
//             e.g. - com.icewarp.webclient
//                  - com.icewarp.eas
//                  - com.icewarp.webdav
//
//
// DeviceId - unique identifier for the session - used to distinguish notifications from actions caused by my session
// Return Value:  True -  when sessionid is valid
//                False - Otherwise

Function SetSessionExpiration(SessionID: AnsiString; Minutes: Longint): Boolean;
// Set non default session expiration in minutes

Function MigrateData(SessionID: AnsiString; SourceDSN, DestinationDSN, Params: AnsiString): Boolean;
// Migrates all tables to new database. Only superuser or administrator can do this.

Function MigrateDataProgress: AnsiString;
// Returns information about progress of database migration being in progress

Function GetServerVersion: AnsiString;
// Returns the server version

Function GetServerTimeZone: AnsiString;
// Returns the server timezone

Function GetTZIDList(TZFormat: Longint = $00): AnsiString;
// Returns the TZID list
//
// TZFormat
//   0 - TZID list
//   1 - GMT offset list

Function GetTZIDTime(SourceTime, SourceTZ, DestTZ: AnsiString; TZFormat: Longint = $00): AnsiString;
// Converts time from source in ISO8601 format (eg. 2010-01-01T00:00:00) to dest TZID. Blank TZID stands for local TZ
//
// TZFormat:
//   0 - TimeZoneID
//   1 - ActiveSync base64 TZ


Function GetMainTZID(TZID: AnsiString): AnsiString;
// For given TZID, get corresponding TZID of the same timezone, which appears in response of GetTZIDList


Function GetTZIDVTIMEZONE(TZID: AnsiString): AnsiString;
// Returns VTIMEZONE object. Blank TZID stands for local TZ

Function GetVTIMEZONETZID(VTimeZone: AnsiString): AnsiString;
// Returns TZID from VTimeZone object. Blank VTimeZone stands for local TZ and standardized TZID will be returned.

Function IsAddressBookEmail(OwnerEmail: AnsiString; Email: AnsiString; Separate: Boolean): Boolean;
// Returns true if email is found in the server's address book

Function GetOwnerList(SessionID: AnsiString; Where: AnsiString = ''): AnsiString;
// Returns all groupware owner/users and their IDs

Function GetSessionList(SessionID: AnsiString): AnsiString;
// Returns all current sessions on the server

Function DialSIPNumber(SessionID: AnsiString; Number: AnsiString; Address: AnsiString = ''): Boolean;
// Initiates the call dialer on the SIP server which dials your SIP client and then
// transfers the call to the Number. If Address blank the currently logged on SIP client
// to your account will be used otherwise the Address will be dialed.

Function SyncGroupUsersContacts(GroupSessionID: AnsiString; Email: AnsiString; Folder: AnsiString = ''): Boolean;
// Synchronize all group members with the contacts folder (contacts and distribution lists)
// Members will be expanded (every member to its final form (domain = members, group = group members, etc.)


Function ReSyncContactsToLDAP(GroupSessionID: AnsiString): Boolean;
// If GW synchronization to LDAP is enabled, this schedules resync of the contacts of this folder


Function RenameDomain(SessionID: AnsiString; OldDomain: AnsiString; NewDomain: AnsiString): Boolean;
// Renames a domain and updates all required information in the database so the data
// is still accessible for account from the new domain.

Function DeleteDomain(SessionID: AnsiString; Domain: AnsiString): Boolean;
// Deletes a domain and

Function GetSessionIDFromHandle(Handle: Cardinal): AnsiString;
// Returns session ID string matching SessionHandle, which is cardinal type number


// --------
// Obsolete
// --------

// These functions still work but were replaced by higher and simpler API functions
// Try to avoid calling these

Function UserLoggedOn(SessionID: AnsiString): Boolean;
// Returns true if sessionID exists on the server.
// Note: Use GetFolderUpdate function instead

Function GetGroupAccess(SessionID, GroupID: AnsiString; DefaultTitle: AnsiString = ''; _Flags: Longint = $00): AnsiString;
// An alias to OpenGroup()

Function GetGlobalGroupList(SessionID: AnsiString; Where: AnsiString = ''): AnsiString;
// Returns the list of all public groups available for the user
// Note: Public folders automatically appear in the folder list


Function GetGroupAccessRightsList(SessionID: AnsiString; GroupID: AnsiString = ''): AnsiString;
// Returns the list of all open groups and their rights
//
// Fields: GRP_ID, GrpRights, OWN_ID, Own_Email

Function GetGroupUsers(GroupSessionID: AnsiString): AnsiString;
Function AddGroupUser(GroupSessionID: AnsiString; Parameters: AnsiString; ID: AnsiString = ''): AnsiString;
Function DeleteGroupUsers(GroupSessionID: AnsiString; ID: AnsiString = ''): Boolean;
// Manages ACL for the root folder
// Note: Use FolderRight functions instead


Function GetEventNoteText(GroupSessionID: AnsiString; EventID: AnsiString): AnsiString;
Function SetEventNoteText(GroupSessionID: AnsiString; EventID: AnsiString; Text: AnsiString): Boolean;
// Manages note object's infinite text content
// Note: Use Attribute functions instead with AtrType=note

Function GetIntervalHolidays(SessionID: AnsiString; Interval: AnsiString; CS: AnsiString): AnsiString;
// Returns holiday values and attributes for the given interval
// Note: GetAllIntervalEvents returns subscribed holidays with the EvnClass=H automatically


Function GetContactCertificate(GroupSessionID: AnsiString; ContactID: AnsiString): AnsiString;
Function SetContactCertificate(GroupSessionID: AnsiString; ContactID: AnsiString; Cert: AnsiString): Boolean;
// Manages contact certificates
// Note: Use Attribute functions instead with AtrType=cert

Function GetContactLocationPhones(GroupSessionID: AnsiString; LocationID: AnsiString): AnsiString;
Function AddContactLocationPhone(GroupSessionID: AnsiString; LocationID: AnsiString; Parameters: AnsiString; ItemID: AnsiString = ''): AnsiString;
Function DeleteContactLocationPhones(GroupSessionID: AnsiString; LocationID: AnsiString; ItemID: AnsiString = ''): Boolean;
// Manages contact location phones
// Note: Use direct ContactLocation functions instead (LctPhn fields)