/*
 * 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.
 */

/*
 * Make header files for data types (composite types)
 */
:- module(mkc_typ,[mkc/0]).

:- style_check(+string).

:- use_module(desc-files).
:- use_module(desc-names).
:- use_module(db-inter).
:- use_module(mkc-print).

mkc :-
     format("Making code for composite data types:~n"),
     vcgnew,
     forall(implemented(_:ctyp_imp(Dt,_)),
      ( file(type,Dt,Fnh),
	format("[~w", [Dt]), flush,
	class(Dt,Fnh),
        format("]"))), nl.

/*
 * Make a type class
 */
class(C,Fnh) :-
	data_type(C, D, Ln),
	typname(C,Cn),
	leng(Ln,Len), % max - length

	build_incl(C,DepL),
	build_vdecl(C,DecL),
	length(DecL, NOItems),

	htell(Fnh,Def,ctype),

	nl,
	format("~n#include <Composite.h>~n~n"),

	comment('DATA TYPE',C,Len,D),
	print_incl(DepL),
	class_begin(Cn,'Composite'),

	print_vdecl(DecL),

	/* itemtab */

	format("~nstatic itemdesc itemtab[~w];~n", NOItems),

	ppublic,

	/* ctor */

	format("~n~w();~n", Cn),

	/* get */

	forall(
	(
	    member([Type,_,Name,_,_], DecL),
	    Type \= '// void'
	),
	format("~nconst ~w& get~w() const;", [Type, Name])),

	/* set */
    
        nl,
	forall(
	(
	    member([Type,_,Name,_,_], DecL),
	    Type \= '// void'
	), 
	format("~nvoid set~w(const ~w &x);", [Name, Type])),
	class_end,
	iccinclude(Fnh),
	htold(Def),

	cctell(Fnh,ctype),

	nl,
	format("#include ~'Composite.h~'~n"),
	format("#include ~'DataTypeCode.h~'~n"),

	comment('DATA TYPE',C,Len,D),
	print_incl(DepL),

	/* itemtab */

	format("Composite::itemdesc ~w::itemtab[~w] = {~>", [Cn, NOItems]),
	forall(
	(
	    member([Type,_,Name,_,Cmt], DecL),
	    Type \= '// void'
	),  format("~n{ (::Type (::Composite::*))&~w::~w, ~'~w~' },",
                   [Cn, Name, Cmt])),
	format("~<~n};"),

	/* ctor */

	valname(C,Cv),
	format("~n~n~w::~w() : Composite(DataTypeCode::~w, ~w, itemtab) {}",
	[Cn, Cn, Cv, NOItems]),

	cctold,
	icctell(Fnh, ctype),

	/* get */

        forall(
	(
	    member([Type,_,Name,_,_], DecL),
	    Type \= '// void'
	),
	(
	    format("~ninline~n"),
	    format("const ~w& ~w::get~w() const~n", [Type, Cn, Name]),
	    format("{~n"),	    
	    format("  return ~w;~n", Name),
	    format("}~n")
	)),

	/* set */
    
	nl,
        forall(
	(
	    member([Type,_,Name,_,_], DecL),
	    Type \= '// void'
	),
	(
	    format("~ninline~n"),
	    format("void ~w::set~w(const ~w &x)~n", [Cn,Name,Type]),
	    format("{~n"),	    
	    format("  ~w = x;~n", [Name]),
	    format("  set();~n"),
	    format("}~n")
	)),
	nl,
	icctold,

        vcgtell,

% node

        format("node: {~>~ntitle: ~'~w~'~n", [Cn]),
        uppercase(C,UC), 
        format("label: ~'~w~'~n", [UC]),
        format("color: blue~n"),
        format("level: 11~<~n}~n"),

% edges
  
        forall(
	(
	    member([Type,_,_,_,Name], DecL),
	    Type \= '// void'
	),
        (
          ( concat(_,"Code",Type) -> Tp1 = 'IDtyp' ; Tp1 = Type ),
          uppercase(Name,UName), 
          format("edge: {~>~nlabel: ~'~w~'~n", [UName]),
          format("sourcename: ~'~w~'~n", [Cn]),
          format("targetname: ~'~w~'~<~n}~n", [Tp1])
        )),

        vcgtold.

/*
        htmltell(Fnh),

% node

        uppercase(C,UC),
        format("<H2>~w COMPOSITE DATATYPE</H2>~n", [UC]),
        format("<P><DL>~n"),
        main_package(P),
        format("<LI>Package: ~w~n", [Cn]),
        format("<LI>Class: ~w~n", [Cn]),
        format("level: 11~<~n}~n"),

% edges
  
        forall(
	(
	    member([Type,_,_,_,Name], DecL),
	    Type \= '// void'
	),
        (
          ( concat(_,"Code",Type) -> Tp1 = 'IDtyp' ; Tp1 = Type ),
          uppercase(Name,UName), 
          format("edge: {~>~nlabel: ~'~w~'~n", [UName]),
          format("sourcename: ~'~w~'~n", [Cn]),
          format("targetname: ~'~w~'~<~n}~n", [Tp1])
        )),

        vcgtold.
*/


/*
 * Build list of dependencies, i.e. objects which have to be included.
 */
build_incl(S,DepL) :-
	desc_ctyp:ctyp_imp(S,Dti),
	findall(Typ,
	  (member([Typ,_], Dti), nonnil(Typ)),
	  DepL1),
	sort(DepL1,DepL).

/*
 * Build list of variable/parameter declarations
 */
build_vdecl(S,DecL) :-
	desc_ctyp:ctyp_imp(S,Dti),
	findall([Type,'',CName,'',Name],
	(
	    member([Dt,Name], Dti),
	    cname(Name,CName),
	    once(typname(Dt,Type))
	),
	DecL).

