/*

	KRAFT Messaging Layer APIs

	Author:		K.Y. Hui
	Date:		15 June 1999
	Version:	1.30

			The original messaging layer is now divided into
			the message-formatting module and transportation module.

*/

:- module(messaging,	[	init_messaging/1,		%init messaging layer
				halt_messaging/0,		%halt messaging layer
				get_argument/2,			%get argument value(s)
				set_argument/2,			%create new argument values
				set_argument/3,			%update existing arg list
				generate_id/1,			%generate a random no. as id
				generate_id/2,			%generate a random no. as id with prefix
				compose_message/3,		%compose message from context+core
				compose_message/5,		%compose message from major CCQL components
				compose_context/6,		%compose message context-info
				compose_ccql_core/3,		%compose message CCQL-core
				decompose_message/3,		%decompose message into context+ccql
				decompose_message/5,		%decompose message into major CCQL components only
				decompose_context/6,		%decompose messsage context-info
				decompose_ccql_core/3,		%decompose CCQL-core
				send_message/1,			%send a message
				receive_message/1,		%receive a message
				receive_message/2,		%receive a message
				receive_message_noblock/1,	%receive without blocking
				receive_message_noblock/2,	%receive without blocking
				receive_message_noblock/3	%receive without blocking
			]).

:- [message_format].			%use message (de)composition module
:- [transport].				%use the message transportation module
:- ['../util/prolog_detect'].
:- prolog_detect:prolog(Prolog),
	(	(Prolog=sicstus,
		use_module(library(lists))
		);
		true
	).


%----------
% init the messaging layer w/ platform specific parameters
% The Linda layer requires the parameters "server_host" & "server_port"
%
% Parameters =	a list of platform-dependent parameters in the form:
%		[Name1:Value1, Name2:Value2, ...]
%----------

init_messaging(Parameters) :-
	transport:tp_init_transport(Parameters).


%----------
%
% stop the messaging layer
%
%----------

halt_messaging :-
	transport:tp_halt_transport.


%----------
%
% compose a message from components
%
%----------

%
% compose a messages from composed context+core
% (for hard working coders)
%
compose_message(Context,Core,Message) :-
	message_format:mf_compose_message(Context,Core,Message).

%
% compose a message from major components
% (for lazy coders)
%
compose_message(Orig,Dest,Perf,Args,Message) :-
	message_format:mf_compose_message(Orig,Dest,Perf,Args,Message).

%
% compose context
%
compose_context(Version,Cid,Origin,Dest,Time_stamp,Context) :-
	message_format:mf_compose_context(Version,Cid,Origin,Dest,Time_stamp,Context).

%
% compose CCQL core
%
compose_ccql_core(Perf,Args,Ccql_core) :-
	message_format:mf_compose_ccql_core(Perf,Args,Ccql_core).



%----------
%
% decompose a message into components
%
%----------

%
% decompose message into context+core
% (for hardworking corders)
%
decompose_message(Context,Core,Message) :-
	message_format:mf_decompose_message(Context,Core,Message).

%
% decompose message into components
% (for lazy coders)
%
decompose_message(Orig,Dest,Perf,Args,Message) :-
	message_format:mf_decompose_message(Orig,Dest,Perf,Args,Message).

%
% decompose context into components
%
decompose_context(Version,Cid,Origin,Dest,Time_stamp,Context) :-
	message_format:mf_decompose_context(Version,Cid,Origin,Dest,Time_stamp,Context).

%
% this one is API 1.10 CCQL core that conforms to KP39
%
decompose_ccql_core(Perf,Args,Ccql_core) :-
	message_format:mf_decompose_ccql_core(Perf,Args,Ccql_core).


%----------
%
% generate_id(-Id)
%
% generate an integer usable as an ID
%
%----------

generate_id(Id) :-
	transport:tp_generate_id(Id).


%----------
%
% generate_id(+Prefix,-Id)
%
% generate an integer usable as an ID, with a prefix
%
%----------

generate_id(Prefix,Id) :-
	generate_id(Idee),
	name(Idee,Idee_string),
	name(Prefix,Prefix_string),
	append(Prefix_string,Idee_string,String),
	name(Id,String).


%----------
%
% send_message(+Message)
%
% send the message
%
%----------

send_message(Message) :-
	transport:tp_send_message(Message).


%----------
%
% receive_message(?Message)
% receive_message(+Name,?Message)
%
% receive a message according to a message-template
%
%----------

receive_message(Message) :-
	transport:tp_receive_message(Message).


%
% receive a message according to my name
%
receive_message(Myname,Message) :-
	transport:tp_receive_message(Myname,Message).


%----------
%
% receive_message_noblock(?Message)
% receive_message_noblock(+Name,?Message)
% receive_message_noblock(+Timeout,?Message)
% receive_message_noblock(+Timeout,+Name,?Message)
%
% receive a message without blocking to a message-template
%
%----------

%
% receive a message without blocking
%
receive_message_noblock(Message) :-
	transport:tp_receive_message_noblock(Message).

receive_message_noblock(timeout(Second),Message) :-
	!,								%cut to avoid trying another receive_message_noblock/2
	transport:tp_receive_message_noblock(timeout(Second),Message).

%
% receive a message without blocking by my name
%
receive_message_noblock(Myname,Message) :-
	transport:tp_receive_message_noblock(Myname,Message).

receive_message_noblock(timeout(Second),Myname,Message) :-
	transport:tp_receive_message_noblock(timeout(Second),Myname,Message).


%----------
% get_argument(+Source,?Template)
%
% Source can be:	a message
%		OR	an argument-list in a message
%
% Template can be:	a "argument:value" pair
%		OR	a list of "argument:value" pair in the form
%			[arg1:value1, arg2,value2, ...]
%
%----------

%
% get_argument/2
%

get_argument(Args,Template) :-
	message_format:mf_get_argument(Args,Template).


%----------
% setting the CCQL argument-list
%
% set_argument(+Value_bindings,-Argument_list)
%
%	OR
%
% set_argument(+Old_args,+Value_bindings,-New_args)
%
%----------

%
% set_argument/2
%
% creating a new argument-list without updating
%

set_argument(Binding,Args) :-
	message_format:mf_set_argument(Binding,Args).


%
% set_argument/3
%
% update an existing arg-list
%

set_argument(Old,Binding,New) :-
	message_format:mf_set_argument(Old,Binding,New).

