package Lire::Config::Value;

use strict;

use Carp;

use Lire::Utils qw/ deep_copy check_object_param /;

# Load subclasses
use Lire::Config::Scalar;
use Lire::Config::List;
use Lire::Config::Dictionary;
use Lire::Config::ConfigFile;
use Lire::Config::Object;
use Lire::Config::Plugin;

=pod

=head1 NAME

Lire::Config::Value - Lire value containers for configuration variables

=head1 SYNOPSIS

  use base qw/ Lire::Config::Value /;

=head1 DESCRIPTION

Value containers for configuration variables. This is the abstract
superclass for the other Lire::Config::Value classes.

=head2 new( ['spec' => $spec], ... )

This is the constructor for the value object. Lire::Config::Value
objects should be instantiated from the instance() method defined in
the TypeSpec object.

=cut

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

    if ( ref $class ) {
        check_object_param( $class, 'proto', 'Lire::Config::Value' );
        return $class->clone();
    } else {
        check_object_param( $args{'spec'}, 'spec', 'Lire::Config::TypeSpec' );

        return bless {
                      'spec' => $args{'spec'},
                     }, $class;
    }
}

=pod

=head2 name()

Returns this configuration parameter's name.

=cut

sub name {
    return $_[0]->{'spec'}->name();
}

=pod

=head2 spec()

Returns the specification for this parameter.

=cut

sub spec {
    return $_[0]{'spec'};
}

=pod

=head2 summary()

Returns the specification's summary for this value.

=cut

sub summary {
    return $_[0]->{'spec'}->summary();
}

=pod

=head2 description()

Returns the specification's description for this value.

=cut

sub description {
    return $_[0]->{'spec'}->description();
}

=pod

=head2 text_description()

Returns the specification's description (formatted in plain text) for this
value.

=cut

sub text_description {
    return $_[0]->{'spec'}->text_description();
}

=pod

=head2 as_value()

Returns this value as a perl native value. This will be either a
scalar value, or an hash or array references. The returned values
should be normalized.

=cut

sub as_value {
    croak ref $_[0], "::as_value is unimplemented";
}

=pod

=head2 as_label()

Return the label of this object for displaying in GUI's.

=cut

sub as_label {
    croak ref $_[0], "::as_label is unimplemented";
}

=pod

=head2 as_shell_var()

Returns this configuration variable's value in a form that can be
evaled in a shell script.

=cut

sub as_shell_var {
    return $_[0]->name() . q{="Variable's type not supported in shell"};
}

=pod

=head2 clone()

Return a deep_copie'd value of this instance. The reference to the spec is
kept but is not copied.

=cut

sub clone {
    return deep_copy( $_[0], [ 'Lire::Config::TypeSpec' ] );
}

=pod

=head2 is_equals( $param )

Returns if the $param instance is identifcal to this one.

=cut

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

    check_object_param( $param, 'param', 'Lire::Config::Value' );

    return 1 if $param eq $self;
    return $self->{'spec'} eq $param->{'spec'};
}

=pod

=head2 is_valid()

Checks that the current value is valid according to the specification.

=cut

sub is_valid {
    croak("is_valid() method not implemented in ", ref $_[0] );
}

=pod

=head2 is_default()

Returns true if this value is equals to its specification's default.

=cut

sub is_default {
    my $self = $_[0];

    return $self->{'spec'}->has_default() &&
      $self->is_equals( $self->{'spec'}->default() );
}

=pod

=head2 save_xml( $fh )

Writes an XML  configuration of the variable recursively on $fh.

=cut

sub save_xml {
    my ( $self, $fh, $indent, $xmlns ) = @_;

    $indent ||= 0;
    $xmlns ||= '';

    return if $self->is_default() || $self->spec()->obsolete();

    print $fh '  'x$indent, "<${xmlns}param name=\"", $self->name() , '">', "\n";
    $self->save_value( $fh, $indent, $xmlns );
    print $fh '  'x$indent, "</${xmlns}param>\n";

    return;
}

1; # whine, whine

__END__

=pod

=head1 AUTHORS

  Wessel Dankers <wsl@logreport.org>
  Francis J. Lacoste <flacoste@logreport.org>
  Wolfgang Sourdeau <wolfgang@logreport.org>

=head1 VERSION

$Id: Value.pm,v 1.18 2008/03/09 19:27:31 vanbaal Exp $

=head1 COPYRIGHT

Copyright (C) 2002-2004 Stichting LogReport Foundation LogReport@LogReport.org

This file is part of Lire.

Lire 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 (see COPYING); if not, check with
http://www.gnu.org/copyleft/gpl.html.

=cut
