package dict;
use strict;
use warnings;

use Lib;
use L;

use Exporter;
use base 'Exporter';
our @EXPORT = qw(dict);

use constant { KEYS => 0, VALUES => 1, INDEX => 2 };

# dict receives the initial values as a sub not an array, for some reason I
# forget!  It allows calculations before returning the values, anyway.

sub dict (&) {
	my @list = $_[0]->();
	my $keys = odds(\@list);
	my $values = evens(\@list);
	my $dict = bless [$keys, $values], __PACKAGE__;
#	$dict->make_index;
	return $dict;
}

sub make_index {
	my ($dict) = @_;
	my %index;
	for1 { push @{$index{$a}}, $_ } @{$dict->[KEYS]};
	$dict->[INDEX] = \%index;
}

sub for (&$) {
	my ($sub, $dict) = @_;
	for2 \&$sub, @{$dict->[KEYS]}, @{$dict->[VALUES]};
}

sub print {
	my ($dict) = @_;
	dict::for { say "$a: $b" } $dict;
	say;
}

sub keys {
	my ($dict) = @_;
	return may_deref($dict->[KEYS]);
}

sub values {
	my ($dict) = @_;
	return may_deref($dict->[VALUES]);
}

sub get {
	my ($dict, $key) = @_;
	$dict->make_index if !$dict->[INDEX];
	my @slice = @{$dict->[VALUES]}[@{$dict->[INDEX]{$key}}];
	return may_deref(\@slice);
}

sub test {
	my $x = dict {
		animal => 'cow',
		class => 'mammal',
		legs => 4,
		sound => 'moo',
		sound => 'mwoooooh',
		eats => 'grass',
		use => 'milk',
		use => 'meat',
		meat => 'beef',
		child => 'calf',
		female => 'cow',
		male => 'bull',
	};
	$x->print;
	say $x->keys;
	say $x->values;	

	say;
	dict::for { say "$_. $a: $b"; } $x;
	say;

	say $x->get('sound');
}

1
