:- ensure_loaded(common).
cvs_id('$Id: source_views.pl,v 1.20 2004/10/18 22:37:30 sandro Exp $').
/*

   getting grotty...

   ... triples_in_source
   ... triples_in_graph

  
*/
:- ensure_loaded(views).
% :- debug(sv).

tab(6000, Q, Focus, 'RDF Source (Terms Used)', +terms_in_source(Q, Focus)) :-
	rdf(Focus, rdf:type, retr:'RDFSource').
% tab(9500, Q, Focus, 'URI :: Usage Survey', +term_uses(Q, Focus)).

%term_uses(Q, Focus, HTree) :-
%	HTree = 'temporarily unavailable'.

source(S,P,O,Source) :-
	rdfpage(Ret, retr:finalResource, Source),
	rdfpage(Ret, retr:chunk, Graph),
	rdf(S,P,O,Graph).

term_source(Term, Source) :- source(Term, _, _, Source).
term_source(Term, Source) :- source(_, Term, _, Source).
term_source(Term, Source) :- source(_, _, Term, Source), atom(Term).

% on 750KT, takes ...?    a LLLLONG time    linear?
%  shouold be done in "pagein".
not_used___build_term_graph :-
	findall( p(S,G),
		 ( rdfpage(_, retr:chunk, G),
		     rdf(S,_,_,G)
		 ),
		 SL),
	sort(SL, SSL),
	length(SSL, C1),
	format(user_error, 's/g pairs: ~w~n', [C1]),
	findall( p(P,G),
		 ( rdfpage(_, retr:chunk, G),
		     rdf(_,P,_,G)
		 ),
		 PL),
	sort(PL, SPL),
	length(SPL, C2),
	format(user_error, 'p/g pairs: ~w~n', [C2]),
	findall( p(O,G),
		 (   rdfpage(_, retr:chunk, G),
		     rdf(_,_,O,G), atom(O)),
		 OL),
	sort(OL, SOL),
	length(SOL, C3),
	format(user_error, 'o/g pairs: ~w~n', [C3]),
	append(SSL, SPL, L1),
	sort(L1, L2),
	append(L2, SOL, L3),
	sort(L3, L4),
	length(L4, C4),
	format(user_error, 't/g pairs: ~w~n', [C4]),
	forall(  member(p(T,G), L4),
		 (   rdf_assert(G, retr:uses, T, term_graph_index),
		     write('.')
		 )
	      ).

/*
	forall(  rdf(S,P,O,G),
		 (  rdf_assert(G, retr:uses, S, foo),
		     rdf_assert(G, retr:uses, P, foo),
		     (   atom(O)
		     ->  rdf_assert(G, retr:uses, S, foo)
		     ;   true
		     )
		 )
	      ).
*/

term_uses(Q, Focus, HTree) :-
	setofsome(10, Done, User,
		term_source(Focus, User),
		Users
	       ),
	sort(Users, SortedUsers),
	(  Done
	-> DoneText = 'All uses found: '
	;  DoneText = 'Some of the uses found: '
	),
	HTree = [   p(DoneText,  +thing_list(Q, SortedUsers))
		 ].

/*
html_view('Terms Used', page, Focus, Q,
	  +terms_in_source(Q, Focus, FocusURI)) :-
	uri(Focus, FocusURI),
	parse_url(Focus, Parts),
	( \+ member(fragment(_), Parts)
	; member(fragment(''), Parts)
	),
	once(source(_, _, _, FocusURI)).
*/

% html_view('Null', page, _Focus, _Q, []).

tab(6500, Q, Focus, 'RDF Source (Latest Triples)', +triples_in_graph(Q, Graph)) :-
	once(rdfq(Q, Focus, rdf:type, retr:'RDFSource')),
	address_latest_successful_ret(Focus, Ret),
	rdf(Ret, retr:finalResource, Focus),
	once(rdf(Ret, retr:chunk, Graph)).

tab(6501, Q, Focus, 'RDF Graph (Triples)', +triples_in_graph(Q, Focus)) :-
	debug(tab, '1  ~q', [rdfq(Q, Focus, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'http://www.w3.org/2004/03/retr/RDFSource')]),
	once((   rdfq(Q, Focus, rdf:type, retr:'RDFGraph')
	    ;   rdfpage_uri(Focus),
		\+rdfpage_sub_uri(_,_,Focus)
	    )).
 
first(Max, [H|T], [H|T2]) :-
	Max > 0,
	Next is Max - 1,
	first(Next, T, T2).
first(Max, _, []) :-
	Max =< 0.
first(_Max, [], []).

unit_test(  first(0, "12345678", "")  ).
unit_test(  first(1, "12345678", "1")  ).
unit_test(  first(8, "12345678", "12345678")  ).
unit_test(  first(9, "12345678", "12345678")  ).
      
triples_in_graph(Q, Graph, HTree) :-
	findall(rdf(S,P,O),
		rdf(S,P,O,Graph),
		Triples),
	debug(sv, '2 Triples: ~q', [Triples]),
	length(Triples, N),
	(   N > 100
	->  first(100, Triples, HeadTriples),
	    Comment = [int(N),' triples present; only showing first 100.']
	;   Comment = [], HeadTriples=Triples
	),
	debug(sv, '3 HeadTriples: ~q', [HeadTriples]),
	findall(tr(td(+word(Q, S)),
		   td(+word(Q, P)),
		   td(class=semWalkerPTableCell, +word(Q, O))),
		(   member(rdf(S,P,O), HeadTriples),
		    debug(sv, '4. Row: ~q', [rdf(S,P,O)])
		),
		Rows),
	debug(sv, '5', []),
	HTree = [ table(Rows), Comment ].
	 
is_class(Q, X) :-
	once(   rdfq(Q, X, rdf:type, rdfs:'Class')
	    ;   rdfq(Q, _, rdf:type, X)
	    ).

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

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

terms_in_source(Q, Focus, HTree) :-
	findall(Term,
		term_source(Term, Focus),
		UnsortedTerms 
	       ),
	sort(UnsortedTerms, Terms),
	sublist(is_class(Q), Terms, Classes),
	sublist(is_property(Q), Terms, Properties),
	sublist(neither(Q), Terms, OtherTerms),
	HTree = [
		 p('This is an RDF information source.  The terms (URIs) it uses are given below.   Items marked like ', span(class=high, this), ' are in this namespace (that is, the URIs begin with ', span('"', Focus, '"'), ').'),
		 h3('RDF terms used as classes'),
		 +thing_list(Q, Classes, in_ns(Focus)),
		 h3('RDF terms used as properties'),
		 +thing_list(Q, Properties, in_ns(Focus)),
		 h3('Terms used in other ways'),
		 +thing_list(Q, OtherTerms, in_ns(Focus))
		].
in_ns(NS, Term) :-
	atom_prefix(Term, NS).

tab(9000, _Q, Focus, 'Source (Text)', +source_text(Ret)) :-
	once(rdfpage(Ret, retr:finalResource, Focus)).

source_text(Ret, pre(H)) :-
	rdfpage_sub_uri(Page, _, Ret),
	rdfpage_filename(Page, data, DataFile),
	read_file_to_codes(DataFile, Codes, []),
	H=codes(Codes). 

tab(8731, _Q, Ret, 'Retrieval (Parse Errors)', +parse_errors(Ret)) :-
	once(ret_get(Ret, retr:parseErrors, literal(ErrorCount))),
	ErrorCount > 0.

parse_errors(Ret, pre(H)) :-
	ret_file(Ret, parse_errors, ErrorFile),
	read_file_to_codes(ErrorFile, Codes, []),
	H=codes(Codes). 

tab(9001, _Q, Focus, 'Upload (Text)', +upload_text(Focus)) :-
	rdfpage(Focus, rdf:type, retr:'SuccessfulUpload').

upload_text(Upload, pre(H)) :-
	rdfpage_sub_uri(Page, _, Upload),
	rdfpage_filename(Page, data, DataFile),
	read_file_to_codes(DataFile, Codes, []),
	H=codes(Codes).

tab(103, Q, Focus, 'List of Sources', +list_of_sources(Q)) :-
    list_of_sources_object(Focus).

list_of_sources_object('x-hack:list_of_sources').

web_server_path_view(list_of_sources, list_of_sources).

% group by host?!?
list_of_sources(Q, [table(border='1', Heading, Rows, More)]) :-
	Heading=tr(th('RDF Source Name'), th('Last&nbsp;Checked'), th('Triples'), th('Ontology?'), th('URI')), 
	setofsome(1000,
		  Done,
		  tr(td(+word([], Source)),
		     td(a(href= \self_uri(basic, Q, [focus=Ret]), +reltime(Time))),
		     td(align=right,int(Count)),
		     td(OntologyReason),
		     td(Source)
		    ),
		  (   address_latest_ret(Source, Ret),
		      rdfpage(Ret, retr:exchangingHeaders, literal(unixtime(Time))),
		      rdfpage(Ret, retr:triples, literal(Count)),
%		      (   
%		      ->  true
%	 	      ;   Count=0
%		      ),
		      (   rdfpage(Ret, retr:inference, Proof),
			  rdfpage(Ret, retr:chunk, Graph),
			  rdf(Graph, rdf:type, owl:'Ontology', Proof)
		      ->  OntologyReason=[yes, ' (', +link(Q, Proof, why), ')']
		      ;   OntologyReason=no
		      )
		  ),
		  Rows),
	(   Done
	->  More = ''
	;   More = p('(Listing stopped at 1000 entries.)')
	).

count_triples_in_graph(Graph, Count) :-
	rdf(Graph, triples, literal(Count), user), !,
	debug(sv, 'remembered Graph ~a Triples ~q', [Graph, Count]).
count_triples_in_graph(Graph, Count) :-
	debug(sv, 'computing Graph ~a', [Graph]),
	atom(Graph),
	findall(rdf(S,P,O),
		rdf(S,P,O,Graph),
		Triples),
	length(Triples, Count),
	debug(sv, 'computed Graph ~a Triples ~q', [Graph, Count]),
	rdf_assert(Graph, triples, literal(Count), user).
