%
% print CIF with suitable indentation
%
:- module(print_cif,[print_cif/1]).

:- use_module(library(lists)).

:- use_module(is_daplex_variable).

print_cif(Cif) :-
	print_cif(0,Cif).			%start with 0 tab



%
% end of list
%
print_cif(Tab,[]) :-
	!,
	print_tab(Tab),
	format("[]",[]).

%
% if CIF is a Prolog var/daplex var/atom/number, just print it
%
print_cif(Tab,Cif) :-
	Cif=[Something],
	(	var(Something);
		is_daplex_variable(Something);
		atom(Something);
		number(Something)
	),
	!,
	print_tab(Tab),
	write(Cif).

%
% print CIF as a list
%
print_cif(Tab,Cif) :-
	is_list(Cif),					%if CIF is a list
	!,
	print_tab(Tab),					%print tabs
	write('['),					%then start a list
	nl,
%	More_tab is Tab+1,
	print_cif_without_brackets(Tab,Cif),		%print list without brackets
	print_tab(Tab),					%then close the bracket
	write(']').

%
% a single CIF construct
%
print_cif(Tab,Cif) :-
	print_construct(Tab,Cif).		%if it is not a list, print as construct


%
% print CIF in a list without the square brackets
%

print_cif_without_brackets(_,[]) :-		%end of list
	!.

print_cif_without_brackets(Tab,[Cif]) :-
	!,
	print_cif(Tab,Cif),			%last element in list
	nl.					%and a newline

print_cif_without_brackets(Tab,[Cif|Cifs]) :-
	print_cif(Tab,Cif),			%print CIF
	format(",~n",[]),			%then a newline
	print_cif_without_brackets(Tab,Cifs).	%and the rest of the list


%
% print different CIF/ICode constructs
%

%
% restrict_subquery/3
%
print_construct(Tab,Cif) :-
	Cif=restrict_subquery(Quantifier,Set,Predicate),
	!,
	print_tab(Tab),
	format("restrict_subquery(~n",[]),
	More_tab is Tab+1,
	print_tab(More_tab),
	write(Quantifier),
	format(",~n",[]),
	print_cif(More_tab,Set),
	format(",~n",[]),
	print_cif(More_tab,Predicate),
	nl,
	print_tab(Tab),
	format(")",[]).

%
% generate_subquery/5
%
print_construct(Tab,Cif) :-
	Cif=generate_subquery(Gen_type,Gen_var,Sub,Aux1,Aux2),
	!,
	print_tab(Tab),
	format("generate_subquery(~n",[]),
	More_tab is Tab+1,
	print_tab(More_tab),
	write(Gen_type),
	format(",~n",[]),
	print_tab(More_tab),
	write(Gen_var),
	format(",~n",[]),
	print_cif(More_tab,Sub),
	format(",~n",[]),
	print_cif(More_tab,Aux1),
	format(",~n",[]),
	print_cif(More_tab,Aux2),
	format("~n",[]),
	print_tab(Tab),
	format(")",[]).


print_construct(Tab,Cif) :-
	Cif=if(Something),
	length(Something,Length),
	Length>1,
	!,
	print_tab(Tab),
	format("if(~n",[]),
	More_tab is Tab+1,
	print_cif(More_tab,Something),
	nl,
	print_tab(Tab),
	format(")",[]).

%
% logical_not/1
%
print_construct(Tab,Construct) :-
	Construct=logical_not(Content),
	!,
	print_tab(Tab),
	format("logical_not(~n",[]),
	More_tab is Tab+1,
	print_cif(More_tab,Content),
	nl,
	print_tab(Tab),
	format(")",[]).

%
% logical_or/2 & logical_and/2
%
print_construct(Tab,Construct) :-
	Construct =.. [Functor,A,B],
	member(Functor,[logical_or,logical_and]),
	!,
	print_tab(Tab),
	format("~a(~n",[Functor]),
	More_tab is Tab+1,
	print_cif(More_tab,A),
	write(','),
	nl,
	print_cif(More_tab,B),
	nl,
	print_tab(Tab),
	format(")~n",[]).

%
% logical_or and logical_and
%
print_construct(Tab,Construct) :-
	Construct =.. [Functor|Args],
	member(Functor,[logical_or,logical_and]),
	!,
	print_tab(Tab),
	format("~a(~n",[Functor]),
	More_tab is Tab+1,
	print_cif_without_brackets(More_tab,Args),
	print_tab(Tab),
	format(")",[]).


print_construct(Tab,Construct) :-
	functor(Construct,Functor,Arity),
	member(Functor,[generate_subquery,
			restrict_subquery]),
	Arity > 0,
	Construct =.. [Functor|Args],
	!,
	print_tab(Tab),
	format("~a(~n",[Functor]),
	More_tab is Tab+1,
	print_cif_without_brackets(More_tab,Args),
	print_tab(Tab),
	format(")",[]).

%
% an explicit/1
%
print_construct(Tab,Construct) :-
	Construct=explicit(List),
	!,
	print_tab(Tab),
	format("explicit([~n",[]),
	More_tab is Tab+1,
	print_cif_without_brackets(More_tab,List),
	print_tab(Tab),
	format("])",[]).




%
% by default, just write the construct
%
print_construct(Tab,Cif) :-
	print_tab(Tab),
	write(Cif).



%
% print a number of tabs
%
print_tab(0) :-
	!.

print_tab(Tab) :-
	Tab >0,
        format("        ",[]),
	New_tab is Tab-1,
	print_tab(New_tab).

