package EPrints::Plugin::Export::OAI_DRIVER_DIDL;

# OAI DRIVER DIDL export plug-in
#
# DRIVER 1.1 (DARE 2.3.1), extends EPrints::Plugin::OAI_DRIVER_Export
# 
# 10-01-2008, Arnoud Jippes, University of Twente, NL
#
# Waiting for validating report
# See: http://www.driver-support.eu/documents/DRIVER_guidelines_annexes_1_1_1.pdf
#
# 18-2-2008, refactored with OAI_DRIVER_Export abstract class
#
# TODO:
#
# - Debug after DRIVER report


use Unicode::String qw( utf8 );
#use EPrints::OpenArchives;

use EPrints::Plugin::Export::OAI_DRIVER_Export;

@ISA = ( "EPrints::Plugin::Export::OAI_DRIVER_Export" );

use strict;

sub new
{
	my( $class, %opts ) = @_;

	my $self = $class->SUPER::new( %opts );

	$self->{name} = "OAI DRIVER_DIDL v1.1";
	$self->{accept} = [ 'dataobj/eprint' ];
	$self->{visible} = "all";
	$self->{suffix} = ".xml";
	$self->{mimetype} = "text/xml";

	$self->{xmlns} = "urn:mpeg:mpeg21:2002:02-DIDL-NS",
	$self->{schemaLocation} = "http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-21_schema_files/did/didmodel.xsd";

	return $self;
}


sub xml_dataobj
{
	my( $plugin, $eprint ) = @_;

	# Persistent URL can be defined in /cfg.d
	my $PURL = $eprint->get_url;
	my $base_purl = $plugin->{session}->get_repository->get_conf( "base_purl" );
	$PURL = $base_purl . $eprint->get_value( "eprintid" ) if defined $base_purl;
	
	# URN can be defined in /cfg.d, URN:NBN recommended for EU
	my $URN = $PURL;
	my $base_urn = $plugin->{session}->get_repository->get_conf( "base_urn" );
	$URN = $base_urn . $eprint->get_value( "eprintid" ) if defined $base_urn;
	
  my $didl = $plugin->make_didl_element();
  $plugin->fill_didl_element($eprint, $didl, $PURL, $URN);

	return $didl;

	# my $oai2_id = $plugin->{session}->get_repository->get_conf( "oai", "v2", "archive_id" );
	# EPrints::OpenArchives::to_oai_identifier( $oai2_id, $eprint->get_id )
}


sub output_dataobj
{
	my( $plugin, $dataobj ) = @_;

	my $didl = $plugin->xml_dataobj( $dataobj );

	return EPrints::XML::to_string( $didl );
}


#DIDL element
sub make_didl_element
{
	my( $plugin ) = @_;
 
 	my $didl = $plugin->{session}->make_element( 
	"didl:DIDL",
	# "DIDLDocumentId"=>?, DocumentId is optional, can not be equal to dii:Identifier!
	"xmlns:didl"=>"urn:mpeg:mpeg21:2002:02-DIDL-NS",
	"xmlns:dii"=>"urn:mpeg:mpeg21:2002:01-DII-NS",
	"xmlns:dip"=>"urn:mpeg:mpeg21:2005:01-DIP-NS",
	"xmlns:dcterms"=>"http://purl.org/dc/terms/",
	"xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance",
	"xsi:schemaLocation"=>"
		urn:mpeg:mpeg21:2002:02-DIDL-NS http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-21_schema_files/did/didl.xsd 
		urn:mpeg:mpeg21:2002:01-DII-NS http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-21_schema_files/dii.xsd/dii.xsd
		urn:mpeg:mpeg21:2005:01-DIP-NS http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-21_schema_files/dip/dip.xsd
	");

	return $didl;
}


sub fill_didl_element
{
	my ( $plugin, $eprint, $didl, $PURL, $URN ) = @_;
	
	my $top_item = $plugin->{session}->make_element( "didl:Item" );
	$didl->appendChild( $top_item );
	
	$top_item->appendChild( $plugin->desc_identifier( $eprint, $URN ) );
	$top_item->appendChild( $plugin->desc_modified( $eprint ) );
	$top_item->appendChild( $plugin->com_resource( $eprint, $PURL ) );
	$top_item->appendChild( $plugin->item_metadata( $eprint ) );
	$top_item->appendChild( $plugin->item_intermediate_page( $eprint, $PURL ) );
	foreach my $doc ( $eprint->get_all_documents() )	{
		my %files = $doc->files; 
		foreach my $filename ( keys %files ) {
			$top_item->appendChild( $plugin->item_resource_location( $eprint, $doc, $filename) )
		}
	}
}


#ITEMS
sub desc_identifier
{
	my( $plugin, $eprint, $URN ) = @_;

	#DESC IDENTIFIER (main identifier, none for the sub-items)
	my $desc = $plugin->{session}->make_element( "didl:Descriptor" );
	my $stat = $plugin->{session}->make_element( "didl:Statement", mimeType=>"application/xml" );
	my $elem = $plugin->{session}->make_element( "dii:Identifier" );
	$elem->appendChild( $plugin->{session}->make_text( $URN ) );
	$stat->appendChild( $elem );
	$desc->appendChild( $stat );
	return $desc
}

sub desc_modified
{
	my( $plugin, $eprint ) = @_;

	my $desc = $plugin->{session}->make_element( "didl:Descriptor" );
	my $stat = $plugin->{session}->make_element( "didl:Statement", mimeType=>"text/xml" );
	my $elem = $plugin->{session}->make_element( "dcterms:modified" );
	my $lastmod = $eprint->get_value( "lastmod" ) || $eprint->get_value( "datestamp" ) ;
	my $zulu_lastmod = '0001-01-01T00:00:00Z'; #default..
	if ( EPrints::Utils::is_set( $lastmod ) )
	{
		my( $date, $time ) = split( " ", $lastmod );
		$time = '00:00:00' if $time eq '';
		$zulu_lastmod = $date."T".$time."Z";
	}
	$elem->appendChild( $plugin->{session}->make_text( $zulu_lastmod ) );
	$stat->appendChild( $elem );
	$desc->appendChild( $stat );
	return $desc;
}
	
sub com_resource
{
	my( $plugin, $eprint, $PURL ) = @_;
	my $comp = $plugin->{session}->make_element( "didl:Component" );
	my $res = $plugin->{session}->make_element( "didl:Resource", mimeType=>"text/html", ref=>$PURL );
	$comp->appendChild( $res );
	return $comp;
}  

sub item_metadata
{
	my( $plugin, $eprint ) = @_;

	my $item = $plugin->{session}->make_element( "didl:Item" );

	my $desc = $plugin->{session}->make_element( "didl:Descriptor" );
	my $stat = $plugin->{session}->make_element( "didl:Statement", mimeType=>"application/xml" );
	my $elem = $plugin->{session}->make_element( "dip:ObjectType" );
	$elem->appendChild( $plugin->{session}->make_text( "info:eu-repo/semantics/descriptiveMetadata" ) );
	$stat->appendChild( $elem );
	$desc->appendChild( $stat );
	$item->appendChild( $desc );

	my $comp = $plugin->{session}->make_element( "didl:Component" );
	my $res = $plugin->{session}->make_element( "didl:Resource", mimeType=>"text/xml" );
#	$elem = $plugin->{session}->plugin( "Export::OAI_DRIVER_DC" );
	$res->appendChild( $plugin->xml_dc( $eprint ) ); 
	$comp->appendChild( $res );
	$item->appendChild( $comp );
	return $item;
}

sub item_resource_location
{
	my( $plugin, $eprint, $doc, $filename ) = @_;

	#objectFile
	my $item = $plugin->{session}->make_element( "didl:Item" );
	my $desc = $plugin->{session}->make_element( "didl:Descriptor" );
	my $stat = $plugin->{session}->make_element( "didl:Statement", mimeType=>"application/xml");
	my $elem = $plugin->{session}->make_element( "dip:ObjectType" );
	$elem->appendChild( $plugin->{session}->make_text( "info:eu-repo/semantics/objectFile" ) );
	$stat->appendChild( $elem );
	$desc->appendChild( $stat );
	$item->appendChild( $desc );

	#modified
	my @fd= gmtime((stat( $doc->local_path."/".$filename ))[9]);
	my $zulu_file_date = sprintf("%4d-%02d-%02dT%02d:%02d:%02dZ", 1900+$fd[5],$fd[4]+1,$fd[3],$fd[2],$fd[1], $fd[0]);
	$desc = $plugin->{session}->make_element( "didl:Descriptor" );
	$stat = $plugin->{session}->make_element( "didl:Statement", mimeType=>"text/xml" );
	$elem = $plugin->{session}->make_element( "dcterms:modified" );
	$elem->appendChild( $plugin->{session}->make_text( $zulu_file_date ) );
	$stat->appendChild( $elem );
	$desc->appendChild( $stat );
	$item->appendChild( $desc );

	#file mime-type
	my $comp = $plugin->{session}->make_element( "didl:Component" );
	my $res = $plugin->{session}->make_element( "didl:Resource", ref=>$doc->get_url( $filename ) );
	$res->setAttribute( "mimeType", $plugin->mimetype( $doc, $filename ) );
	$comp->appendChild( $res );
	$item->appendChild( $comp );
	
	return $item
}

sub item_intermediate_page
{
	my( $plugin, $eprint, $PURL ) = @_;

	my $item = $plugin->{session}->make_element( "didl:Item" );

	my $desc = $plugin->{session}->make_element( "didl:Descriptor" );
	my $stat = $plugin->{session}->make_element( "didl:Statement", mimeType=>"application/xml" );
	my $elem = $plugin->{session}->make_element( "dip:ObjectType" );
	$elem->appendChild( $plugin->{session}->make_text( "info:eu-repo/semantics/humanStartPage" ) );
	$stat->appendChild( $elem );
	$desc->appendChild( $stat );
	$item->appendChild( $desc );

	my $comp = $plugin->{session}->make_element( "didl:Component" );
	my $res = $plugin->{session}->make_element( "didl:Resource",
			mimeType=>"text/html",
			ref=>$PURL );
	$comp->appendChild( $res );

	$item->appendChild( $comp );

	return $item;
}


1;
