package Glade2::Widget;
use strict;
use warnings;

our $VERSION = "0.1";
use Gtk2::GladeXML;
use POE;
use POE::Session::GladeXML2;
use base qw(Gtk2::Widget);

sub _session_autoconnect_helper {
  my $name = $_[$#_]->{'name'} || '';
  my $poe_event_name = "$_[0]\_$name" if ($name);
  POE::Session::GladeXML2::_session_autoconnect_helper (@_, $poe_event_name);

}

=head1 CONSTRUCTOR

=head2 new

Creates a new widget from a .glade file. It accepts the following parameters.

=over 2

=item file => STRING

The full path name of the glade file to use.

=item widget => STRING

the name used in the glade file for the container widget to use.

=item name => STRING

A name for the widget. This is used to allow more than one widget to be
in the same session. The state names are then constructed by concatenating
the method name you pass in the states parameter with this name, seperated
by an underscore:

=over 8

$state = "$method\_$name";

=back

It is easy to use the widget name used for the custom widget in the
container glade file for this, as this is passed to your constructor.

=over 8

package FooWidget;
use base qw(Glade2::Widget);

 sub new {
 	my $class, $name, undef, undef, undef, undef) = @_;
 	my $self = {
 		...
 		name => $name,
 	};
 	...
 }

=back

The example above also shows that you get String1, String2, Int1 and Int2
fields you can specify in Glade in your constructor as well. Not exactly
a great API, but it can be useful for some things.

=item states => LISTREF

a list of extra POE states to register. These are registered as object
states, with the widget as the object.

=back

=cut

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

   my $g = Gtk2::GladeXML->new ($args{'file'}, $args{'widget'});

   my $widget = $g->get_widget ($args{'widget'});
   bless $widget, $class;

   my $name = $widget->{'name'} = $args{'name'};
   $widget->{'xml'} = $g;

   foreach my $handler (@{$args{'states'}}) {
        my $name = ($name ? "$handler\_$name" : "$handler");
   	$poe_kernel->state ($name, $widget, $handler);
   }

   $g->signal_autoconnect (
		  \&_session_autoconnect_helper,
		  $widget
	 );

   return $widget;
}

=head1 METHODS

=head2 yield (METHODNAME, ARGUMENTS)

This method is used to call a poe event METHODNAME with optional ARGUMENTS.
It is mainly useful for calling events on widgets that have more than
one instance in a session, as it turns METHODNAME into the proper event
name that was autogenerated to avoid duplication.

=cut

sub yield {
   my ($self, $method_name, @args) = @_;

  my $name = $self->{'name'} || '';
  my $poe_event_name .= $name ? "$method_name\_$name" : "$method_name";

  $poe_kernel->yield ($poe_event_name, @args);
}

sub _create_custom_widget {
   my ($xml, $class, @params) = @_;

   my $widget = $class->new (@params);
   return $widget;
}

Gtk2::Glade->set_custom_handler (\&_create_custom_widget);

1;
