package Lire::SimpleStat;

use strict;

use base qw/ Lire::Aggregate /;

use Carp;

use Lire::DataTypes qw/ is_numeric_type format_numeric_type /;
use Lire::Utils qw/ check_param /;

=pod

=head1 Lire::SimpleStat

This class provides common implementation for the operator that
implement common statistical operation on one DLF field.

Subclasses don't have to override xml_attrs() nor the print() method.

=head2 init( %params )

Subclasses should provide an additional parameter to the init()
method.

=over

=item field

The DLF field's name on which the statistic is computed.

=back

=cut

sub init {
    my ( $self, %args ) = @_;

    $self->SUPER::init( %args );

    check_param( $args{'field'}, 'field' );

    $self->field( $args{'field'} );

    return;
}

=pod

=head2 field( [$new_field] )

Returns the name of the DLF field on which the statistic will be
computed.

If the $new_field is set, the field's attribute is changed to this new
value. It must be a valid field name for the schema of the current
report specification.

=cut

sub field {
    my ( $self, $field ) = @_;

    if ( @_ == 2 ) {
        check_param( $field, 'field',
                     sub { return is_numeric_type( $self->report_spec()->field( $field )->type() ) },
                     "'field' parameter should be a numerical field" );
	croak "'$field' isn't a defined field in the specification's schemas"
	    unless $self->report_spec()->has_field( $field );

	$self->{'field'} = $field;
    }

    return $self->{'field'};
}

=pod

=head2 dlf_field()

Returns the field onto which we are computing a statistic as a
Lire::Field object.

=cut

sub dlf_field {
    $_[0]->report_spec()->field( $_[0]->field() );
}

# Implementats Lire::Aggregate::create_numerical_info
sub create_numerical_info {
    my ( $self, $group_info ) = @_;

    $group_info->create_column_info( $self->name(), 'numerical',
                                     $self->dlf_field()->type(),
                                     $self->label() );
}

# ------------------------------------------------------------------------
# Method xml_attrs()
#
# Implementation required by Lire::Aggregate
sub xml_attrs {
    return qq{ field="$_[0]{'field'}"};
}

# Implements Lire::Aggregate::sql_required_fields
sub sql_required_fields {
    return [ $_[0]{'field'} ];
}

# Implements Lire::Aggregate::create_value()
sub create_value {
    my ( $self, $group, $row ) = @_;

    my %value;
    my $name = $self->name();

    $value{'content'} =
      format_numeric_type( $row->{$name}, $self->dlf_field()->type() );
    $value{'value'} = $row->{$name};

    $self->set_missing_cases_value( $row, \%value );

    return \%value;
}

# Implements Lire::Aggregate::data2dlf()
sub data2dlf {
    my ($self, $data) = @_;

    my $name = $self->name();
    return { "$name" => $$data,
             "_lr_${name}_mc" => $self->missing_cases( $data ),
           };
}

1;
