package BDSM::Util;

use strict;
use warnings;
use include;

use Exporter;
our @ISA = ("Exporter");
our @EXPORT = qw(
  fix_coords vi_dirs keycoord dircoord compass_dirs oppdir is_vert is_horiz
  is_diag
);

# Reversify the coordinates if they need reversifying. Modifies them in place,
# so no passing in constants!
sub fix_coords {
  ($_[0], $_[1]) = ($_[1], $_[0]) if $_[0] > $_[1];
}

# (Vi) Returns a list of the 8 directions in Vi-key format.
sub vi_dirs {
  return qw(h j k l y u b n);
}

# (Compass) Returns a list of the 4 orthogonal compass directions.
sub compass_dirs {
  return qw(N S W E);
}

# (Vi) Changes and returns the coordinates to reflect one move in the specified
# direction.
sub keycoord {
  my ($dir, $y, $x) = @_;
  $dir = lc $dir;
  $y--       if $dir eq "k";
  $y++       if $dir eq "j";
  $x--       if $dir eq "h";
  $x++       if $dir eq "l";
  $y--, $x-- if $dir eq "y";
  $y--, $x++ if $dir eq "u";
  $y++, $x-- if $dir eq "b";
  $y++, $x++ if $dir eq "n";
  return ($y, $x);
}

# (Compass) Changes and returns the coordinates to reflect one move in the
# specified direction. Only 4 directions since compass directions are for walls.
sub dircoord {
  my ($dir, $y, $x) = @_;
  $dir = lc $dir;
  $y-- if $dir eq "n";
  $y++ if $dir eq "s";
  $x-- if $dir eq "w";
  $x++ if $dir eq "e";
  return ($y, $x);
}

# (Compass) Returns the opposite orthogonal direction.
sub oppdir {
    return {
      N => "S",
      S => "N",
      W => "E",
      E => "W"
    }->{ uc shift() };
}

# (Compass) Determines if the direction is vertical.
sub is_vert {
  return 1 if shift() =~ m/[ns]/i;
}

# (Compass) Determines if the direction is horizontal.
sub is_horiz {
  return 1 if shift() =~ m/[we]/i;
}

# (Vi) Determines if the direction is a diagonal.
sub is_diag {
  return 1 if shift() =~ m/[yubn]/i;
}

42;
