/*
 * Copyright (c) 1995, 1996 Gunther Schadow.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 * Print diverse sections of the code
 */
:- module(mkc_print,[print_incl/1, print_vdecl/1, print_cdef/1,
	             comment/4, class_begin/2, class_end/0,
               	     pprivate/0, pprotected/0, ppublic/0, 
		     param/2,param/3,aparam/1]).

:- style_check(+string).

:- ensure_loaded(supp-format).

:- use_module(desc-files).
:- use_module(desc-names).

/*
 * Includes
 */
print_incl(DepL) :- nl,
	mapIdtoFile(DepL,IncL),
	sort(IncL,IncLs),
	print_include1(IncLs),
	nl.

mapIdtoFile([],[]).
mapIdtoFile([Hi|Ti],[Hf|Tf]) :-
	ifile(_,Hi,Hf),
	mapIdtoFile(Ti,Tf).

print_include1([]).
print_include1([H|T]) :-
	format("#include <~w>~n", H),
	print_include1(T).

/*
 * Declaration of variables.
 *
 * Declaration list entries have the format:
 *
 * [Type, (Pointer/Optional-Flag), Name, Range, Comment]
 */
print_vdecl([]).
print_vdecl(DecL) :-
	ppublic, nl,
	print_vdecl1(DecL).
print_vdecl1([]).
print_vdecl1([['ANYseg',_,N,Set,_]|T]) :-
	format("ANYseg ~w;~45|//any of ", N),
	any_comment(Set),
	print_vdecl1(T).
print_vdecl1([['repANYseg',_,N,Set,_]|T]) :-
	format("repANYseg ~w;~45|//any of ", N),
	any_comment(Set),
	print_vdecl1(T).
/*
print_vdecl1([['repstruc<ANYseg>',_,N,Set,_]|T]) :-
	format("repstruc<ANYseg> ~w;~45|//any of ", N),
	any_comment(Set),
	print_vdecl1(T).
*/
print_vdecl1([H|T]) :-
	format("~w~i ~w~w;~45|//~w~n", H),
	print_vdecl1(T).

any_comment([Seg1, Seg2]) :-
	uppercase(Seg1,USeg1),
	uppercase(Seg2,USeg2),
	format("~w and ~w~n", [USeg1, USeg2]).
any_comment([Seg|R]) :-
	uppercase(Seg,USeg),
	format("~w, ", USeg),
	any_comment(R).

/*
 * Declaration of variables.
 *
 * Declaration list entries are alists with the following defined tokens:
 *
 * tpfx(TypePrefix),
 * scope(Scopename),
 * type(Typename),
 * tsfx(TypeSuffix),
 * npfx(NamePrefix),
 * name(Name),
 * nsfx(NameSuffix),
 * comment(Comment)
 * Flags: opt, rep, any.
 *
 * Scopename::Typename Pointer(e.g. & or *) Name Index(e.g. [10]); // Comment
 * 
 * CURRENTLY NOT ACTIVE

print_vdecl_a([]).
print_vdecl_a(DecL) :-
	ppublic, nl,
	print_vdecl_a1(DecL).
print_vdecl_a1([]).
print_vdecl_a1([H|T]) :- assoc(H,type('ANYseg')),
	assoc(H,name(N)),
	assoc(H,comment(C)),
	format("ANYseg ~w;~45|//~w~n", [N,C]),
	print_vdecl_a1(T).
print_vdecl_a1([H|T]) :-
	assoca(H,tpfx(Tp)),
	assoca(H,type(T)),
	assoca(H,tsfx(Ts)),
	assoc(H,name(N)),
	assoc(H,comment(C)),
	format("~w ~w~w;~45|//~w~n", [Tp,T,Ts,N,C]),
	print_vdecl_a1(T).
 */

/*
 * Definitions of constants
 */ 
print_cdef([]).
print_cdef(L) :-
	findall([Name,Value],
	     (member(const(Name,Value), L)),
	     ConstL),
	print_cdef_const(ConstL).
print_cdef(_).

print_cdef_const([]).
print_cdef_const(ConstL) :-
	ppublic, nl,
	format("enum~>~n{~>"),
	print_cdef_const1(ConstL),
	format("~<~n};~<~n").

print_cdef_const1([]).
print_cdef_const1([H|T]) :-
	format("~nmax~w = ~w,", H),
	print_cdef_const1(T).


comment(T,N,F,D) :-
	format("~n/*~n * ~w~n *~n * ~w(~w) -- ~w~n */~n",
    [T,N,F,D]).

class_begin(N,T) :- !,
	format("class ~w : public ~w~n{~>~n", [N,T]).
class_end :- format("~<~n};~n~n").

pprivate :-   format("~<~n private:~>~n").
ppublic :-    format("~<~n public:~>~n").
pprotected :- format("~<~n protected:~>~n").

/*
 * Format parameter list
 */
param(X,Y) :-
	format("~/"),
	param1(X,Y),
	format("~<").

param1(nopar,_).
param1(_,[['// void',_,_,_,_]]).
param1(Cv,[H]) :-
	param2(Cv,H).
param1(Cv,[['// void',_,_,_,_]|T]) :- 
	param1(Cv,T).
param1(Cv,[H|T]) :- 
	param2(Cv,H),
	format(",~n"),
	param1(Cv,T).

param2(const,[Type,_,Name,_,_]) :- !,
	format("const ~w &__~w", [Type, Name]).
param2(var,[Type,_,Name,_,_]) :- !,
	format("~w &__~w", [Type, Name]).

/*
 * with scoping
 */
param(S,X,Y) :-
	format("~/"),
	param1(S,X,Y),
	format("~<").

param1(_,nopar,_).
param1(_,_,[['// void',_,_,_,_]]).
param1(S,Cv,[H]) :-
	param2(S,Cv,H).
param1(S,Cv,[['// void',_,_,_,_]|T]) :- 
	param1(S,Cv,T).
param1(S,Cv,[H|T]) :- 
	param2(S,Cv,H),
	format(",~n"),
	param1(S,Cv,T).

param2(S,const,[Type1,_,Name,_,_]) :- !,
	scopetype(S,Type1,Type),
	format("const ~w &__~w", [Type, Name]).
param2(S,var,[Type1,_,Name,_,_]) :- !,
	scopetype(S,Type1,Type),
	format("~w &__~w", [Type, Name]).

/*
 * Format actual parameter list
 */
aparam(X) :-
	format("~/"),
	aparam1(X),
	format("~<").

aparam1([]).
aparam1([['// void',_,_,_,_]]).
aparam1([H]) :-
	aparam2(H).
aparam1([['// void',_,_,_,_]|T]) :- 
	aparam1(T).
aparam1([H|T]) :- 
	aparam2(H),
	format(",~n"),
	aparam1(T).

aparam2([_,_,Name,_,_]) :-
	format("__~w", Name).

