###########################################################################
#
# List.pm --
# A component of the Greenstone digital library software
# from the New Zealand Digital Library Project at the 
# University of Waikato, New Zealand.
#
# Copyright (C) 1999 New Zealand Digital Library Project
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
###########################################################################

# simple list classifier plugin 
# to see the options, run "perl -S classinfo.pl List"

use BasClas;
package List;

use sorttools;

sub BEGIN {
    @ISA = ('BasClas');
}

my $arguments = 
    [ { 'name' => "metadata",
	'desc' => "{List.metadata}",
	'type' => "metadata",
	'reqd' => "no" },
      { 'name' => "buttonname",
  	'desc' => "{BasClas.buttonname}",
	'type' => "string",
	'deft' => "{BasClas.metadata.deft}",
	'reqd' => "no" },
      { 'name' => "sort",
	'desc' => "{List.sort}",
	'type' => "string",
	'deft' => "{BasClas.metadata.deft}",
	'reqd' => "no" } ];

my $options = { 'name'     => "List",
		'desc'     => "{List.desc}",
		'abstract' => "no",
		'inherits' => "yes",
		'args'     => $arguments };


sub new {
    my $class = shift (@_);
    my $self = new BasClas($class, @_);

    # 14-05-02 To allow for proper inheritance of arguments - John Thompson
    my $option_list = $self->{'option_list'};
    push( @{$option_list}, $options );

    if ($self->{'info_only'}) {
	# created from classinfo.pl - don't need to parse the arguments
	return bless $self, $class;
    }

    my ($metadata, $title, $sortname, $list);

    if (!parsargv::parse(\@_, 
			 q^metadata/.*/^, \$metadata,
			 q^buttonname/.*/^, \$title,
			 q^sort/.*/^, \$sortname,
			 "allow_extra_options")) {
	
	print STDERR "\nIncorrect options passed to $class, check your collect.cfg file\n";
	$self->print_txt_usage("");  # Use default resource bundle
	die "\n";
    }
    my @meta_list;
    my $meta1;
    
    if ($metadata) {
	@meta_list = split(/,/, $metadata);
	$meta1 = $meta_list[0];
    } else {
	$metadata = undef;
	$meta1=undef;
	@meta_list = undef;
    }

    if (!$title) {
	if (defined ($meta1)) {
	    $title = $meta1;
	} else {
	    $title = 'List';
	}
    }

    # sortname is handled a bit differently - kjdon
    # undef means to sort, but use the metadata value from -metadata
    # because there is no one metadata value to get for sorting when 
    # we have a list of possible metadata
    # to get no sorting, set sortname = 'nosort'
    if (!$sortname) {
	if (defined ($metadata)) {
	    $sortname = undef;
	} else {
	    $sortname = "nosort";
	}
    }
    
    if (defined $sortname && $sortname eq "nosort") {
	$list = [];
    } else {
	$list = {};
    }
    
    $self->{'list'} = $list;
    if (defined $metadata) {
	$self->{'meta_list'} = \@meta_list;
    }
    $self->{'title'} = $title;
    $self->{'sortname'} = $sortname;

    return bless $self, $class;
}

sub init {
    my $self = shift (@_);

}

sub classify {
    my $self = shift (@_);
    my ($doc_obj) = @_;

    my $doc_OID = $doc_obj->get_OID();

    # are we sorting the list??
    my $nosort = 0;
    if (defined $self->{'sortname'} && $self->{'sortname'} eq "nosort") {
	$nosort = 1;
    }
    
    my $metavalue;
    my $metaname;
    if (defined $self->{'meta_list'}) {
	# find the first available metadata
	foreach $m (@{$self->{'meta_list'}}) {
	    $metavalue = $doc_obj->get_metadata_element($doc_obj->get_top_section(), $m);
	    $metaname = $m;
	    last if defined $metavalue;
	} 
	#if we haven't found a metavalue here, then the doc shouldn't be included
	return unless defined $metavalue;
    }
    
    # we know the doc should be included, add it now if we are not sorting
    if ($nosort) {
	push (@{$self->{'list'}}, $doc_OID);
	return;
    }

    #check for a sort element other than our metadata
    if (defined $self->{'sortname'}) {
	my $sortmeta;
	if ($self->{'sortname'} =~ /^filename$/i) {
	    $sortmeta = $doc_obj->get_source_filename();
	} else {
	    $sortmeta = $doc_obj->get_metadata_element($doc_obj->get_top_section(), $self->{'sortname'});
	    if (defined $sortmeta) {
		$sortmeta = $self->format_metadata_for_sorting($self->{'sortname'}, $sortmeta, $doc_obj);
	    }
	}
	$sortmeta = "" unless defined $sortmeta;
	$self->{'list'}->{$doc_OID} = $sortmeta;
    } else {
	# we add to the list based on metadata value
	# but we need to do the same formatting as for sort value
	($metavalue) = $self->format_metadata_for_sorting($metaname, $metavalue, $doc_obj);
	$self->{'list'}->{$doc_OID} = $metavalue;
    }
}


sub get_classify_info {
    my $self = shift (@_);
    my ($no_thistype) = @_;
    $no_thistype = 0 unless defined $no_thistype;

    my @list = ();
    if (defined $self->{'sortname'} && $self->{'sortname'} eq "nosort") {
	@list = @{$self->{'list'}};
    } else {
	if (keys %{$self->{'list'}}) {
	    @list = sort {$self->{'list'}->{$a} 
			  cmp $self->{'list'}->{$b};} keys %{$self->{'list'}};
	}	
    }

    # organise into classification structure
    my %classifyinfo = ('childtype'=>'VList',
			'Title'=>$self->{'title'},
			'contains'=>[]);
    $classifyinfo{'thistype'} = 'Invisible' unless $no_thistype;

    foreach $OID (@list) {
	push (@{$classifyinfo{'contains'}}, {'OID'=>$OID});
    }

    return \%classifyinfo;
}


1;




