package Lire::UI::Widget;

use strict;

use Carp;
use Curses::UI::Common;
use Lire::Utils qw/ check_object_param /;

use base qw/ Curses::UI::Widget /;

use vars qw/@CARP_NOT/;
@CARP_NOT = qw/Curses::UI::Container/;

=pod

=head1 NAME

Lire::UI::Widget - Views for Lire::Config::Value object.

=head1 SYNOPSIS

  use Curses::UI;
  use Lire::Config;

  Lire::Config->init();
  my $ui = new Curses::UI();
  my $window = $ui->add( 'window', 'Window' );
  my $widget = $window->add( 'widget', 'Lire::UI::Widget',
                             'value' => Lire::Config->get_var( 'name' ));

=head1 DESCRIPTION

Lire::UI::Widget defines Curses::UI::Widget subclasses that can be
used to edit Lire::Config::Value object.

=cut

use vars qw/ %widget_table /;

%widget_table = ( 'Lire::Config::BooleanSpec' => 'Lire::UI::BoolWidget',
                  'Lire::Config::ChartSpec' => 'Lire::UI::CompoundWidget',
                  'Lire::Config::ChartTypeSpec' => 'Lire::UI::PluginWidget',
                  'Lire::Config::CommandSpec' => 'Lire::UI::CommandWidget',
                  'Lire::Config::DirectorySpec'=>'Lire::UI::DirectoryWidget',
                  'Lire::Config::DlfAnalyserSpec' => 'Lire::UI::PluginWidget',
                  'Lire::Config::DlfConverterSpec' => 'Lire::UI::PluginWidget',
                  'Lire::Config::DlfSchemaSpec' => 'Lire::UI::SelectWidget',
                  'Lire::Config::DlfStreamSpec' => 'Lire::UI::CompoundWidget',
                  'Lire::Config::ExecutableSpec'=>'Lire::UI::ExecutableWidget',
                  'Lire::Config::FileSpec' => 'Lire::UI::FileWidget',
                  'Lire::Config::IntegerSpec' => 'Lire::UI::IntegerWidget',
                  'Lire::Config::ListSpec' => 'Lire::UI::ListWidget',
                  'Lire::Config::ObjectSpec' => 'Lire::UI::CompoundWidget',
                  'Lire::Config::OutputFormatSpec' => 'Lire::UI::PluginWidget',
                  'Lire::Config::PluginSpec' => 'Lire::UI::PluginWidget',
                  'Lire::Config::RecordSpec' => 'Lire::UI::CompoundWidget',
                  'Lire::Config::ReferenceSpec' => 'Lire::UI::SelectWidget',
                  'Lire::Config::ReportSectionSpec' => 'Lire::UI::ReportSectionWidget',
                  'Lire::Config::ReportSpec' => 'Lire::UI::CompoundWidget',
                  'Lire::Config::SelectSpec' => 'Lire::UI::SelectWidget',
                  'Lire::Config::XMLSpecListSpec' => 'Lire::UI::XMLSpecListWidget',
                  'Lire::Config::StringSpec' => 'Lire::UI::StringWidget',
                );

=pod

=head2 new( %args, 'value' => $value, [ onvaluechanged => $handler ] )

The new() method is really a factory method which instantiate a proper
Lire::UI::Widget subclass based on the type of the Lire::Config::Value
$value. The onvaluechanged is an event that will be trigger whenever
the Lire::Config::Value is modified by the user.

=cut

sub new {
    my $class = shift;
    my %userargs = @_;
    keys_to_lowercase(\%userargs);

    check_object_param( $userargs{'value'}, 'value', 'Lire::Config::Value' );

    my $spec_type = ref( $userargs{'value'}->spec() );
    croak "no widget type defined for values of type '$spec_type'"
      unless exists( $widget_table{$spec_type} );

    my $widget_class = $widget_table{$spec_type};
    eval "use $widget_class;";
    die if $@;

    return $widget_class->new( %userargs );
}

=pod

=head2 value()

Returns the Lire::Config::Value object which is edited by this view.

=cut

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

=pod

=head2 onValueChanded( $code )

Changes the event handler connected to the 'onvaluechanged' event.
This event is trigger whenever the Lire::Config::Value associated to
this widget is modified.

=cut

sub onValueChanged {
    my ( $self, $handler ) = @_;
    $self->set_event( 'onvaluechanged', $handler );
    return;
}

=pod

=head2 refresh_view()

This method can be called to update the view to reflect modifications
to the underlying Lire::COnfig::Value.

=cut

sub refresh_view {
    croak "unimplemented refresh_view() in ", ref $_[0];
}

package Lire::UI::DummyWidget;

$INC{'Lire/UI/DummyWidget.pm'} = __FILE__;

use base qw/Curses::UI::TextViewer/;

use Carp;

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

    return $class->SUPER::new( %args, '-text' => $args{'value'}->get() );
}

sub refresh_view {
    $_[0]->text( $_[0]->{'value'}->get() );
}

# keep perl happy
1;

__END__

=pod

=head1 SEE ALSO

  Lire::UI(3pm), Curses::UI(3pm)

=head1 VERSION

$Id: Widget.pm,v 1.27 2006/07/23 13:16:32 vanbaal Exp $

=head1 AUTHORS

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

=head1 COPYRIGHT

Copyright (C) 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
