#!/usr/bin/perl

use warnings;
use CGI::Pretty;
use RDFcloud;
use LWP::Simple;
use CGI::Carp qw(fatalsToBrowser);

$page = new CGI;
$test = RDFcloud->new();
$test->add_ns ({'test'=>'http://change.me/please#'});
my $earl = $test->{ns}{'earl'};
$earl =~ s/#/.n3/;
$content = LWP::Simple::get($earl);
$test->add($content);
my $td = $test->{ns}{'td'};
$td =~ s/#//;
$content = LWP::Simple::get($td);
$test->add($content);
&add_stuff;
$test->add($page->param('_rdf_code'));
$test->parse;

print 
  $page->header('text/html'),
  $page->start_html(-title=>'create test file',
		    -style=>{-src=>'http://www.w3.org/StyleSheets/base'}), 
  $page->h2('create your own test file'),
  $page->strong('(without having to edit n3 by hand)'),
  $page->start_form,  

  $page->h3('create test case');
  $page->start_p,
  $page->div($page->textfield(-name=>'_internal_name').'internal name');
foreach my $class ('rdf:Property', 'td:DisplayedProperty', 'td:GroupProperty') {
  foreach my $property ($test->get_filtered_properties($class, 'rdfs:domain', 'earl:TestCase')) {
    my $label = $test->get_property($class, $property, 'rdfs:label');
    my $comment = $test->get_property($class, $property, 'rdfs:comment');
    print $page->div($page->textfield(-name=>$property).
		     '('.$test->contract($property).')'.
		     $page->strong($label).
		     ':'.$comment);
  }
}
print $page->submit(-name=>'_submit', -value=>'add your test case');
print $page->hidden('_status', 'TestCase');
print $page->hidden('_rdf_code');
print $page->end_p;
print $page->end_form;

print   $page->start_form,
  $page->h3('add a property'),
  $page->div($page->textfield(-name=>'_internal_name').'internal name'),
  $page->div($page->popup_menu(-name=>'_property_type',
			       -values=>['rdf:Property', 'td:GroupProperty', 'td:DisplayedProperty']).'property type'),
  $page->div($page->popup_menu(-name=>'rdfs:domain',
			       -values=>['earl:TestCase', 'earl:TestSubject', 'earl:Assertor']).'domain'),
  $page->div($page->popup_menu(-name=>'rdfs:range',
			       -values=>['', 'rdfs:Literal', 'rdfs:Resource']).'range'); 
foreach ('rdfs:label', 'rdfs:value', 'rdfs:comment') {
  print $page->div($page->textfield(-name=>$_) . $_);
}
print $page->submit(-name=>'_submit', -value=>'add your property');
print $page->hidden('_status', 'Property');
print $page->hidden('_rdf_code');
print $page->end_p, $page->end_form;

print $page->start_form,
  $page->h3('add a result property'),
  $page->div($page->textfield(-name=>'_internal_name').'internal name');
foreach ('rdfs:label', 'rdfs:comment') {
  print $page->div($page->textfield(-name=>$_) . $_);
}
my %hrm = ('earl:validity' => 'earl:ValidityState', 'earl:confidence' => 'earl:ConfidenceLevel');
foreach my $var (keys %hrm) {
  my ($names, $info) = $test->get_incidence($hrm{$var});
  print $page->div($page->popup_menu(-name=>$var,
				     -values=>['', map {$test->contract($_)} @$names])."($var)");
}
print $page->submit(-name=>'_submit', -value=>'add your result property');
print $page->hidden('_status', 'ResultProperty');
print $page->hidden('_rdf_code');
print $page->end_form;

print $page->start_form;
print $page->h3('edit rdf yourself');
print $page->div($page->textarea(-name=>'_rdf_code', -default=>$page->param('_rdf_code'), -rows=>30, -columns=>100));
print $page->submit(-name=>'_submit', -value=>'make changes');
print $page->hidden('_status', '_make_changes');
print $page->end_form;
print $page->end_html;

sub add_stuff {
  if (!$page->param) {
    &initialize;
    return;
  }
  my $status = $page->param('_status');
  my $rdf_code = $page->param('_rdf_code');
  $rdf_code = &add_TestCase($rdf_code) if ($status eq 'TestCase');
  $rdf_code = &add_Property($rdf_code) if ($status eq 'Property');
  $rdf_code = &add_ResultProperty($rdf_code) if ($status eq 'ResultProperty');
  $page->delete_all();
  $page->param('_rdf_code', $rdf_code);
}

sub initialize {
  my $ns_declare = '';
	
#	foreach (keys %{$test->{rev_ns}}) {
#		my $name = $test->{rev_ns}{$_};
#		$ns_declare .= "\@prefix $name: <$_> .\n";
#	}

  if (!$ns_declare) {
    foreach (keys %{$test->{ns}}) {
      $ns_declare .= "\@prefix $_: <$test->{ns}{$_}> .\n";
    }
  }
  $page->param('_rdf_code', $ns_declare);
}

sub add_TestCase {
  my $rdf_code = $_[0] . "\n\n";
  $rdf_code .= 'test:'.$page->param('_internal_name')." a earl:TestCase";
  foreach ($page->param) {
    next if ($_ =~ /^_/);
    my $val = $page->param($_);
    next unless ($val);
    $rdf_code .= " ;\n\t".$test->n3contract($_)."\t".qualify($val);
  }
  $rdf_code .= ' .';
  return $rdf_code;
}

sub add_ResultProperty {
  my $rdf_code = $_[0] . "\n\n";
  $rdf_code .= 'test:'.$page->param('_internal_name')." a td:ResultProperty";
  foreach ($page->param) {
    next if ($_ =~ /^_/);
    my $val = $page->param($_);
    next unless ($val);
    $rdf_code .= " ;\n\t".$test->n3contract($_)."\t".qualify($val);
  }
  $rdf_code .= ' .';
  return $rdf_code;
}

sub add_Property {
  my $rdf_code = $_[0] . "\n\n";
  $rdf_code .= 'test:'.$page->param('_internal_name')." a ".$test->n3contract($page->param('_property_type'));
  
  foreach $p ($page->param) {
    next if ($p =~ /^_/);
    my $val = $page->param($p);
    next unless ($val);
    if (grep $_ eq $p, ('rdfs:domain', 'rdfs:range')) {
      $rdf_code .=  " ;\n\t".$test->n3contract($p)."\t".$val;
    } else {
      $rdf_code .= " ;\n\t".$test->n3contract($p)."\t".qualify($val);
    }
  }
  $rdf_code .= ' .';
  return $rdf_code;
}

sub qualify {
  my ($val) = @_;
  if ($val =~ 'http://') {
    return '<'.$val.'>';
  } elsif ($val =~ '"') {
    return '"""'.$val.'"""';
  } else {
    return '"'.$val.'"';
  }
}
