:- ensure_loaded(common).
cvs_id('$Id: views.pl,v 1.35 2004/10/22 11:46:12 sandro Exp $').
/*

  <whatever_view>(?Q, +Focus, -H)

  Each "view" presents information from the rdf_db about the "Focus"
  as an HTML-ish term ("H"), suitable for html:write_html/1.  "Q" is
  an option list containing backtrackable state.

  (Another approach would be to have Q be an RDF term like Focus, and
  we look in the rdf_db for options and state, but that would not be
  backtrackable.  Q can carry an RDF Id for some state, of course.)


  html:write_html/1 supports view calls with the "+" syntax:
  when writing ['Hello, ', +photo(Q, opus)], it will attempt to call
  photo(Q, opus, H), and insert the resulting H after "Hello ".

  In general, views should always succeed deterministically.
  html:write_html/1 reports an error on view-call failure, and never
  backtracks into views.

  Maybe Someday:
     change these over to being an RDF (triple) rule/predicate
     using rdf_provide.    The predicate is the view; it
     maps from a "ViewRequest" to an xml literal.

  Maybe Someday:
     view metadata -- about the view.   short term, this can be
     view_uri(<view_function>, URI) or something.  Or just
     view_comment(<view_function>, 'doc string...'), etc.
     OR we could just have a namespace for our views.

*/

:- multifile(rdfq_provided/4).

%%  rdfq(?Q, ?Subj, ?Pred, ?Obj)
%%
%%  Match against the rdf_db, like rdf(S,P,O), except with additional
%%  options and controls given in the option-list "Q".  Also, do
%%  foo:bar expansion on Pred, rather than relying on term_expansion
%%  because it's nicer for some callers.
%%
%%  Options:   sources(SourceList)
%%
%%      Require that the source of the triple be in the SourceList
%%
%%      If SourceList is an unterminated list, this causes the source
%%      to be recorded.  BUT NOTE that inside a failure-driven loop
%%      (including findall/3 and forall/2), backtracking will undo
%%      the addition of the source to the list.   *SO* use findall/3
%%      to find all the triples you might want, gather them in a list,
%%      then gather up the sources with rdfq.  
%%
%%      Only the first occurance of this option is used, so a
%%      temporary override can be prepended for certain calls.
%%
%%  Option Ideas:  trust tagging?   lang suppressing?
%%
rdfq(Q,S,NSP,O) :-
	rdf_global_id(NSP, P),
	(   memberchk(sources(Sources), Q)
	->  ( rdf(S,P,O,Source); rdf(S,P,O,Source:_) ),
	    atom(Source),
	    %%%%  \+ rdfpage_uri(Source), %  Hrmmm????
	    memberchk(Source, Sources),
	    debug(rdfq, '~q:  using source ~a; total: ~q', [NSP, Source, Sources])
	;   rdf(S,P,O,_)
	).
rdfq(Q,S,P,O) :-
	% definitely index by the RDF predicate.
	rdfq_provide(P, S, O, Q).


/*
  
is_class(Q, X) :-
	once(rdfq(Q, X, rdf:type, rdfs:'Class')).

is_property(Q, X) :-
	once(rdfq(Q, X, rdf:type, rdf:'Property')).

neither(Q, X) :-
	\+ is_class(Q, X),
	\+ is_property(Q, X).
*/

/*
html_view('As Class', page, Focus, _Q, HTree) :-
	once(rdfq(Q, Focus, rdf:type, rdfs:'Class')),
	HTree = p(not_quite_implemented).

html_view('As Property', page, Focus, _Q, HTree) :-
	once(rdfq(Q, Focus, rdf:type, rdf:'Property')),
	HTree = p(not_quite_implemented).
*/

% :- ensure_loaded('rdelta').


any(Q, S, P) -->
	{ expand_goal(rdfq(Q, S, P, Value), G), G,
	  ( integer(Value) -> V=int(Value)
	  /* ; float(Value) -> V=float(Value, 3) */
	  ; V=Value) },
	[ V ].

any(_Q, _, _) -->
	[ em('(unknown)') ].

% how do we feel about backtracking, and ordering of backtracking
% here?  Hrmmm.

%  we could have BAD news when asked for ALL THE VIEWS, eh?


% best match?  often has to do with specificity -- v1 is better for
% s1, v2 is better for s2....

%tab(0, _Q, _Focus, 'Test-Start', p('not much to say')).
%tab(9999, _Q, _Focus, 'Test-End', p('not much to say here either')).

 
helplink(_Q, HelpName, LinkText, a(href=Link, LinkText)) :-
%helplink(_Q, HelpName, LinkText, [LinkText, ' (', a(href=Link, '?'), ')']) :-
	atom_concat('static/help-', HelpName, Link).

manual_table(Q, Resources, Properties, H) :-
	fail.

% auto_table would pick properties, allow re-sorting, ...
%
%    That needs option looping with only local knowledge, ie
%    http_query_option(Q, Option, Value)
%        reply_option(Q, ....)
