/*  File:    pce_index.pl
    Author:  Jan Wielemaker
    Created: Mar 14 2003
    Purpose:
*/

:- module(pce_class_index,
          [ pce_make_library_index/1,   % +Dir
            pce_update_library_index/0
          ]).
:- use_module(library(pce_prolog_xref)).
:- use_module(library(lists)).

index_file('CLASSINDEX.pl').

%!  pce_make_library_index(+Dir)
%
%   Create a file CLASSINDEX.pl in Dir holding facts of the format
%
%!          class(Name, Super, Summary, File)
%
%   This file can be used for auto-loading as well as supporting
%   cross-referencing and syntax-highlighting.

pce_make_library_index(Dir) :-
    absolute_file_name(Dir,
                       [ file_type(directory),
                         access(exist)
                       ],
                       Path),
    working_directory(Old, Path),
    call_cleanup(make_library_index,
                 working_directory(_, Old)).

%       pce_update_library_index/0
%
%       Update out-of-date CLASSINDEX.pl files in defined library
%       directories.

pce_update_library_index :-
    index_file(File),
    (   absolute_file_name(library(File),
                           [ access(read),
                             access(write),
                             solutions(all),
                             file_errors(fail)
                           ],
                           AbsFile),
        file_directory_name(AbsFile, Dir),
        print_message(informational, pce(update_library_index(Dir))),
        pce_update_library_index(Dir),
        fail
    ;   true
    ).

pce_update_library_index(Dir) :-
    working_directory(Old, Dir),
    call_cleanup(update_library_index,
                 working_directory(_, Old)).

update_library_index :-
    expand_file_name('*.pl', Files),
    index_file(Index),
    (   library_index_out_of_date(Index, Files),
        catch(open(Index, write, Out), _, fail)
    ->  header(Out),
        call_cleanup(index_file_list(Files, Out),
                     close(Out))
    ;   true
    ).

make_library_index :-
    expand_file_name('*.pl', Files),
    index_file(Index),
    open(Index, write, Out),
    header(Out),
    call_cleanup(index_file_list(Files, Out),
                 close(Out)).

index_file_list([], _).
index_file_list([H|T], Out) :-
    index_file(H, Out),
    index_file_list(T, Out).

index_file('INDEX.pl', _) :- !.
index_file('MKINDEX.pl', _) :- !.
index_file('CLASSINDEX.pl', _) :- !.
index_file(File, Out) :-
    xref_source(File, [silent(true)]),
    (   xref_defined_class(File, Class, local(_Line, Super, Summary)),
        format(Out,
               'class(~q, ~q, ~q, ~q).~n',
               [Class, Super, Summary, File]),
        fail
    ;   true
    ),
    xref_clean(File).

header(Out) :-
    format(Out,
           '/*  $Id\c
               $\n\n    \c
               Creator: pce_make_library_index/1\n    \c
               Purpose: Provide index of XPCE classes in directory\n\c
               */\n\n',
           []).

library_index_out_of_date(Index, _Files) :-
    \+ exists_file(Index),
    !.
library_index_out_of_date(Index, Files) :-
    time_file(Index, IndexTime),
    (   time_file('.', DotTime),
        DotTime @> IndexTime
    ;   member(File, Files),
        time_file(File, FileTime),
        FileTime @> IndexTime
    ),
    !.
