package GO::Object::Reference;

=head1 NAME

GO::Object::Reference       - represents a GO reference

=cut

use strict;
use Data::Dumper;
use Exporter;

#use GO::MiniTests qw/:std/;
use lib '/Users/gwg/go/scratch/tools';
use vars qw(@ISA);
use base qw(GO::Object::Generic); #GO::MiniTests);
use GO::Object::Xref;
use GO::TestSet qw(dfv_test);


sub _specification {
	my $self = shift;
	
	return (
		# required
		"go_ref_id", {
			test => qr/^GO_REF:\d+$/,
			required => 1,
		},
		"title", {
			test => dfv_test('is_a_string_p'),
			required => 1,
		},
		"author", {
			test => dfv_test('is_a_string_p'),
			required => 1,
		},
		"year", {
			test => qr/^\d{4}$/,
			required => 1,
		},
		"abstract", {
			test => dfv_test('is_a_string_p'),
#			required => 1,
		},
		"xref", {
#		"external_accession", {
			type => 'GO::Object::Xref',
			allow_multiple => 1,
			test => dfv_test('is_a_subclass_of_p', { class => 'GO::Object::Xref', this => 1 } ),
		},
		"comment", {
			test => dfv_test('is_a_string_p'),
		},
		"is_obsolete", {
			test => qr/^(1|true)$/,
		},
		"alt_id", {
			allow_multiple => 1,
			test => qr/^GO_REF:\d+$/,
#			test => \&GO::TestSet::is_a_string_p,
		},
	);
}



sub transform_parsed_data {
	my $self = shift;
	my $arg_h = shift;
	my $data_h = $arg_h->{data};
	my $spec_h;

	$self->startme();
	$self->debugme("parsed data: ".Dumper($data_h));
	
	## do any transformations here
	foreach ('external_accession', 'citation')
	{	if ($data_h->{$_})
		{	$self->debugme("Found $_");
			my $temp;
			if (!$spec_h->{xref_spec})
			{	$spec_h->{xref_spec} = GO::Object::Xref->get_spec();
				$spec_h->{xref_dfv_profile} = GO::Object::Xref->dfv_profile();
			}
	
			# convert them into lists for easy manipulation
			if (! ref $data_h->{$_})
			{	$data_h->{$_} = [ $data_h->{$_} ];
			}
			foreach my $xref (@{$data_h->{$_}})
			{	$self->debugme("this is $xref");
				# we want these to be GO::Object::Xrefs
				my $results = GO::Object::Xref->new({
					data => {
						xref => $xref,
					},
					object_spec => $spec_h->{xref_spec},
					dfv_profile => $spec_h->{xref_dfv_profile},
					check_input => $arg_h->{check_input} || undef,
					return_as => 'success_hash',
				});
				
				$self->debugme("results: ".Dumper($results));
				
				push @{$data_h->{xref}}, $results->{OBJECT} if $results->{SUCCESS};
	
				if ($results->{ERROR_LIST})
				{	$self->add_message($results->{ERROR_LIST});
				}
			}
			delete $data_h->{$_};
		}
	}
	
	$self->debugme("data after preparation:".Dumper($data_h));

	return $data_h;
}


sub add_xref {
	my $self = shift;
	my $arg_h = shift;
	if (! ref $arg_h)
	{	# we have a string as the argument
		$arg_h = { data => { xref => $arg_h } };
	}
	
	my $results = GO::Object::Xref->new({
		%$arg_h,
		return_as => 'success_hash',
	});

	if ($results->{SUCCESS})
	{	# hurrah!
		if (!$arg_h->{add_as})
		{	$arg_h->{add_as} = 'xref';
		}
		push @{$self->{ $arg_h->{add_as} }}, $results->{OBJECT};
	}
	
	if ($results->{ERROR_LIST})
	{	$self->add_message($results->{ERROR_LIST});
	}
}



1;