package LinuxIsdn::Ring;
use strict;
use warnings;

use base qw(Exporter);
use fields(debug local_number remote_number rings octet3 octet3a service
           connected generation outgoing);
use fields::accessor qw(local_number	$
                        remote_number	$
                        debug		$
                        rings		$
                        service		$
			octet3a		$
                        octet3	        $
                        outgoing	$
                        connected	$
                        generation	.
                        );

our @number_type = ("unknown",     "international",
                    "national",    "network specific",
                    "subscriber",  "resreved",
                    "abbreviated", "reserved");
our @number_plan = ("reserved") x 16;
$number_plan[0] = "unknown";
$number_plan[1] = "ISDN/telephony";
$number_plan[3] = "data numbering";
$number_plan[4] = "telex numbering";
$number_plan[8] = "national standard";
$number_plan[9] = "private numbering";

our @presentation_indicator = ("allowed", "restricted",
                               "not available due to internetworking",
                               "reserved");
our @screening_indicator = ("user-provided, not screened",
                            "user-provided, verified and passed",
                            "user-provided, verified and failed",
                            "network-provided");

our $VERSION   = "0.0";
our @EXPORT    = qw();
our @EXPORT_OK = qw(number_types @number_type number_plans @number_plan
                    presentation_indicators @presentation_indicator
                    screening_indicators @screening_indicator);

sub number_types {
    return @number_type;
}

sub number_type {
    my LinuxIsdn::Call $call = shift;
    croak "number_type has no meaning before on_ring"  unless
        defined($call->{octet3});
    my $nr = ($call->{octet3} & 0x70) >> 4;
    return $nr if $_[0];
    return $number_type[$nr];
}

sub number_plans {
    return @number_plan;
}

sub number_plan {
    my LinuxIsdn::Call $call = shift;
    croak "number_plan has no meaning before on_ring" unless
        defined($call->{octet3});
    my $nr = $call->{octet3} & 0x0f;
    return $nr if $_[0];
    return $number_plan[$nr];
}

sub presentation_indicators {
    return @presentation_indicator;
}

sub presentation_indicator {
    my LinuxIsdn::Call $call = shift;
    croak "presentation_indicator has no meaning before on_ring" unless
        defined($call->{octet3a});
    my $nr = ($call->{octet3a} & 0x60) >> 5;
    return $nr if $_[0];
    return $presentation_indicator[$nr];
}

sub screening_indicators {
    return @screening_indicator;
}

sub screening_indicator {
    my LinuxIsdn::Call $call = shift;
    croak "screening_indicator has no meaning before on_ring" unless
        defined($call->{octet3a});
    my $nr = $call->{octet3a} & 0x03;
    return $nr if $_[0];
    return $screening_indicator[$nr];
}

sub string {
    my LinuxIsdn::Ring $ring = shift;
    my $str = "";
    $str .= "Remote number          $ring->{remote_number}\n" if
        $ring->{remote_number};
    $str .= "Local  number          $ring->{local_number}\n"  if
        $ring->{local_number};
    $str .= "Number type            " . ucfirst($ring->number_type()) . "\n" if
        defined($ring->{octet3});
    $str .= "Number plan            " . ucfirst($ring->number_plan()) . "\n" if
        defined($ring->{octet3});
    $str .= "Presentation indicator " .
        ucfirst($ring->presentation_indicator()) . "\n" if
            defined($ring->{octet3a});
    $str .= "Screening indicator    " .
        ucfirst($ring->screening_indicator()) . "\n" if
            defined($ring->{octet3a});
    $str .= "Service type           $ring->{service}\n" if
        defined($ring->{service});
    $str .= "Rings                  $ring->{rings}\n"   if
        defined($ring->{rings});
    $str .= "Call direction         " . (!defined($ring->{outgoing}) ? "Undefined" : $ring->{outgoing} ? "Outgoing" : "Incoming") . "\n";
    $str .= "Connected              " . (!defined($ring->{connected}) ? "Unknown" : $ring->{connected} ? "Yes" : "No") . "\n";
    return $str;
}
