package X10::Network;
use vars qw(@ISA);
@ISA = qw(X10::Controller);

# this is an X10::Controller-type object, used to control X10 devices
# via a process running an X10::Server object somewhere else

use Storable qw(thaw);
use IO::Socket;

use strict;

use X10::Controller;

### constructors

sub new
{
   my $type = shift;

   my $self = new X10::Controller( @_ );
   bless $self, $type;

   $self->{socket} = new IO::Socket(
        Domain => &AF_INET,
        Proto => 'tcp',
        PeerAddr => $self->{server} || 'x10',
        PeerPort => $self->{server_port} || 2020,
        );

   unless ($self->{socket})
   {
      warn "Problem connecting socket: ", $!;
      return undef;
   }

   return $self;
}


### public methods (most overriding parent class)

sub select_fds
{
   my $self = shift;
   return ($self->{socket}->fileno);
}

sub handle_input
{
   my $self = shift;

   $self->get_event;
}

sub send
{
   my $self = shift;
   foreach (@_)
   {
      $self->send_one($_);
   }
}

sub send_one
{
   my $self = shift;
   my $event = shift;
   my $packet = $event->nfreeze;
   $self->{socket}->syswrite(chr(length($packet)), 1);
   $self->{socket}->syswrite($packet, length($packet));
}

sub get_event
{
   my $self = shift;

   my $size;
   my $bytes_read = $self->{socket}->sysread($size, 1);

   unless ($bytes_read == 1)
   {
      $self->{socket}->close;
      die "Lost connection to X10 server: ", $!;
   }

   $size = ord($size);

   my $packet = '';
   $bytes_read = $self->{socket}->sysread($packet, $size);

   unless ($bytes_read == $size)
   {
      $self->{socket}->close;
      die "Lost connection to X10 server: ", $!;
   }

   my $event = thaw($packet);

   next undef unless $event;

   unless ($event->isa('X10::Event'))
   {
      warn "Unknown packet type: ", ref $event;
      return undef;
   }

   $self->got_event($event);

   return $event;
}

### mostly-private methods...

sub DESTROY
{
   my $self = shift;
   $self->{socket}->close;
}

### utility functions -- not called as methods



1;

