package Indyvoter::RDF;

use strict;
use RDF::Simple::Serialiser;
# interface to generate RDF for input into the ObjectDB

sub new { return bless $_[0], {}; }
 
sub make_rdf {
	my ($self) = @_;
	# (rdf) name of class - or alias / lookup?
	my @objects = $self->objects;
	foreach (@objects)
		my $class = $_->class;
		# hash of properties
		my $props = $self->properties;
	my $id = $self->serialiser->genid;
	my @triples = map { [ $id,$_,$props->{$_} ] } keys %$props;
	push @triples, [ $id,'rdf:type',$class ];
	my $rdf = $self->serialiser->serialise(@triples);
	return $rdf;	
}

sub serialiser {
	my $self = shift;
	return $self->{_serialiser} if $self->{_serialiser};
	$self->{_serialiser} = RDF::Simple::Serialiser->new;
}

# OWL and RDFS schema awareness - local model

# web interface - mod_perl handler, TT ?

# interface to the objectDB to import RDF - schemas for the Class class, and instance data for the instance classes.

package Indyvoter::RDF::Import;

use strict;
use RDF::Simple::Parser;
use RDF::UL1;
use Indyvoter::Store;

sub import_rdf {
    	my ($self,$rdf) = @_;
	my $ns = $self->parser->ns;
    	my @triples = $self->parser->parse_rdf($rdf);
    	@triples = map {Indyvoter::RDF::Triple->new($_)} @triples;
    
    	# special case - owl:Class or owl:Property (or its subclasses?)
    	my @classes = grep { $_->predicate eq $ns->uri('rdf:type') } @triples;
	my @id = map {$_->subject} @classes;  
	my @create;
	
	my %objects;
	my %links;
 
	foreach my $c (@classes) {
		my $uri = $c->subject;
		my ($class,$properties);
		my $type = $ns->qname($c->object);	
		my @props = grep {
                        ($_->subject eq $c->subject)
                         and 
                        ($_->predicate eq $ns->uri('rdf:type')
                         and (
                                ($_->object eq $ns->uri('rdfs:Property'))
                                or ($_->object eq $ns->uri('owl:Property')
                              )
                        )
                )} @triples;
		

		foreach my $p (@props) {
			my ($link) = grep {$_ eq $p->subject} @id;
			if ($link) {
				$links{$uri}->{$p->predicate} = $link;
			}
			else {
				my $rdf_name = $p->predicate;
				my ($name) = $rdf_name =~ /.+\/(\w+)/;
				# aliasing from schema? 	
			
				$properties->{$name} = $p->object;
			}
		}

		if ($type eq 'owl:Class' or ($type eq 'rdfs:Class') {
			$class = 'Class';	
		}
		else {
			my ($type) = grep {$_->predicate eq $ns->uri('rdf:type')} @props;
			if ($type) {
			    $type = ${$class->[2]} if $type;
			    $class =~ s//.+\/(\w+)/ 
	    		}
		}
		# create db object  
		my $object = Indyvoter::Store->create($class,$properties);
		$objects{$uri} = $object;	
	}
        # what about relations / references?
	foreach my $key (keys %links) {
		my $linked = $links{$key};

		my $this = $objects{$key};

		foreach my $link_type (keys %$linked) {
		my $this_uri = $linked->{$link_type};
			my $object = $objects{$this_uri};	
			$this->$link_type($object);
		}	
	}
	
}

sub Indyvoter::RDF::Triple::new {
    my ($type, @triple) = @_;
    bless \@triple, $type;
}

sub Indyvoter::RDF::Node::new {
    my ($type, $string) = @_;
    if ($string =~ m/^\w+\:/) {
        return Indyvoter::RDF::URI->new($string);
    }
    return $string;
}

sub Indyvoter::RDF::Triple::subject   { my $c = $_[0]; ${ $c->[0] } }

sub Indyvoter::RDF::Triple::predicate { my $c = $_[0]; ${ $c->[1] } }  
sub Indyvoter::RDF::Triple::object    { my $c = $_[0]; return $c->[2] if (not ref $c->[2]); ${$c->[2]
};  }

sub Indyvoter:RDF::URI::new {
    my ($type, $var) = @_;
    bless \$var, $type;
}

1;


