package RISCOS::DynamicArea;

use RISCOS::SWI;
require Exporter;
use strict;
use vars qw (@ISA @EXPORT $VERSION %state $os_da $mask3 $mask2);

@ISA = qw(Exporter);
@EXPORT = qw(dynamic_areas name_dynamic_area hash_dynamic_areas
delete_dynamic_area);
$VERSION = 0.02;
# 0.02 uses map

$os_da = SWINumberFromString('XOS_DynamicArea');
$mask2 = &regmask([0,1],[8]);
$mask3 = &regmask([0,1],[1]);

sub dynamic_areas ()
{
    my ($num, $next, @result) = (-1, 'aaaa');

    while (1) {
	return () unless swix ($os_da, $mask3, 3, $num, $next);

	$num = unpack 'i', $next;
	return @result if $num == -1;
    
	push @result, $num;
    }
}
    
sub _name_dynamic_area ($)
{
    my $name = 'aaaa';
    return undef unless swix ($os_da, $mask2, 2, 0+$_[0], $name);
    unpack 'p', $name;
}

sub name_dynamic_area 
{
    return &_name_dynamic_area unless wantarray;	# Pass on @_
    map  { &_name_dynamic_area $_ } @_;
}

sub hash_dynamic_areas
{
    my $hash = {};
    
    foreach (@_) {
	my $name = _name_dynamic_area $_;
	if (defined $name)
	{
	    # If it's already there mark its number as -1
	    $hash->{$name} = defined ($hash->{$name}) ? -1
						      : $_;
	}
    }
    $hash;
}

sub _delete_dynamic_area ($) {
    defined (kernelswi ($os_da, 1, 0+$_[0])) ? 1 : 0;
}

sub delete_dynamic_area 
{
    return &_delete_dynamic_area unless wantarray;	# Pass on @_
    map {  &_delete_dynamic_area } @_;
}


$os_da;

__END__

=head1 NAME

RISCOS::DynamicArea -- routines to manipulate Dynamic Area

=head1 SYNOPSIS

    use RISCOS::DynamicArea(dynamic_areas,name_dynamic_area);
    
    print join "\n", name_dynamic_area dynamic_areas';
    
=head1 DESCRIPTION

C<RISCOS::DynamicArea> provides routines to list and manipulate dynamic areas.

=head2 Methods

=over 4

=item dynamic_areas

C<dynamic_areas> returns an list of the numbers of dynamic areas.

=item name_dynamic_area <number>, ...

C<name_dynamic_area> converts dynamic area numbers to names. In scalar context
it returns the name of the dynamic area given by the first argument. In array
context it returns a list of dynamic area names corresponding to the argument
list of dynamic area numbers.

=item hash_dynamic_areas

C<hash_dynamic_areas> returns a reference to a hash of dynamic areas, keyed by
name. If a name is unique to one dynamic area then the hash value is that
dynamic area's number. If more than one dynamic area uses the same name, then
the hash value for that area is C<undef>. Use C<exists> (see <perlfunc/exists>)
to distinguish between names used for 0 or for multiple areas.

=item delete_dynamic_area

C<delete_dynamic_area> deletes dynamic areas by number. In scalar context it
attempts to delete a single area, returning 1 on success, 0 on failure. In array
context it returns a list of the results of attempting to the list of area
numbers passed to it.

=back

=head1 BUGS

None known.

=head1 AUTHOR

Nicholas Clark <F<nick@unfortu.net>>
