eval {
	use Fcntl;
	use AnyDBM_File;
};

&error("You don't have the required modules installed: $@") if ($@);

tie(%users,'AnyDBM_File',"$tokens{data_dir}/dbm/users",O_CREAT | O_RDWR,0666) || &error("Can't open user database: $!");
tie(%users_data,'AnyDBM_File',"$tokens{data_dir}/dbm/users_data",O_CREAT | O_RDWR,0666) || &error("Can't open user data database: $!");
tie(%indexes,'AnyDBM_File',"$tokens{data_dir}/dbm/indexes",O_CREAT | O_RDWR,0666) || &error("Can't open index database: $!");
tie(%bandwidth,'AnyDBM_File',"$tokens{data_dir}/dbm/bandwidth",O_CREAT | O_RDWR,0666) || &error("Can't open bandwidth database: $!");

my @indexed = ('email','category','package','status');

my %columns = ();

sub user_create {
	my ($user,%user) = @_;

	$user{status} ||= 0;

	foreach (@indexed) {
		&index_create($_,$user{$_},$user);
	}

	$user{password} = crypt($user{password},'as');

	my @user = ();
	foreach (keys(%user)) { push(@user,"$_=$user{$_}"); }
	$users{$user} = join("\t",@user);
}

sub user_display {
	my ($user) = @_;

	my %user = ();

	foreach (split(/\t/,$users{$user})) {
		my @line = split(/=/,$_,2);
		$user{$line[0]} = $line[1];
	}

	my @time = localtime();
	$user{bandwidth_month} = $bandwidth{"$time[5],$time[4],$user"};
	$user{bandwidth_today} = $bandwidth{"$time[5],$time[4],$time[3],$user"};

	return %user;
}

sub user_display_one {
	my ($user,$column) = @_;

	if ($columns{"$user,$column"}) {
		return $columns{"$user,$column"};
	} else {
		return $columns{"$user,$column"} = ($users{$user} =~ /(^|\t)$column\=(.*?)(\t|$)/si)[1];
	}
}

sub user_modify {
	my ($user,%data) = @_;

	my %user = &user_display($user);

	foreach (@indexed) {
		&index_modify($_,$user{$_},$data{$_},$user);
	}

	if ($data{status} == 1 && $user{status} != 1) {
		foreach (grep(&file_read("$tokens{data_dir}/validation/$_") eq $user,&dir_read("$tokens{data_dir}/validation"))) {
			unlink("$tokens{data_dir}/validation/$_");
		}
	}

	$data{password} = crypt($data{password},'as') if (exists($data{password}));

	foreach (keys(%data)) { $user{$_}=$data{$_}; }

	my @user = ();
	foreach (keys(%user)) { push(@user,"$_=$user{$_}"); }
	$users{$user} = join("\t",@user);
}

sub user_remove {
	my ($user) = @_;

	my %user = &user_display($user);

	foreach (@indexed) {
		&index_remove($_,$user{$_},$user);
	}

	delete $users{$user};
	delete $users_data{$user};

	foreach (grep($_ =~ /\,$user$/,keys(%bandwidth))) {
		delete $bandwidth{$_};
	}

	foreach (grep(&file_read("$tokens{data_dir}/validation/$_") eq $user,&dir_read("$tokens{data_dir}/validation"))) {
		unlink("$tokens{data_dir}/validation/$_");
	}

	&dir_remove("$tokens{root_dir}/$user");
}

sub user_exist {
	my ($user) = @_;

	return (1) if ($users{$user});
	return ();
}

sub index_display {
	my ($type,$key)=@_;

	return split(/\t/,$indexes{"$type\:$key"});
}

sub index_create {
	my ($type,$key,@values)=@_;

	my %values = map { $_ => 1 } (split(/\t/,$indexes{"$type\:$key"}),@values);

	$indexes{"$type\:$key"} = join("\t",keys(%values));
}

sub index_modify {
	my ($type,$key_old,$key,@values) = @_;

	if (length($key) > 0 && $key_old ne $key) {
		&index_remove($type,$key_old,@values);
		&index_create($type,$key,@values);
	}
}

sub index_remove {
	my ($type,$key,@values)=@_;

	my %values;
	@values{@values}=@values;

	$indexes{"$type\:$key"} = join("\t",grep(!$values{$_},split(/\t/,$indexes{"$type\:$key"})));
}

1;