#!/usr/bin/perl
# Single axis <--> dual axis coordinate transformer
# Author: Dan Jacobson https://www.jidanni.org/
# Copyright: https://www.gnu.org/licenses/gpl.htm
# Created: 2024-07-10T22:23:48+0000
# Last-Updated: 2024-08-19T00:33:16+0000
#     Update #: 150
use strict;
use warnings q!all!;
use Getopt::Long;
my ( $axis, $direction, $quadrant, $x, $y, $h, $l, @n, $f, $X, $Y, $L, $H, );
GetOptions(
    "axis=s" => \$axis
    ,    # one of ⮠ ⮡ ⮢ ⮣ ⮤ ⮥ ⮦ ⮧., shortcut to set $direction and $quadrant.
##  "direction=s" =>    # n e s w ↑ → ↓ ←
##    \$direction,      # Following the single axis as its values increase,
    ## the direction of the single axis AFTER it passes the fold.
    "fold=f" => \$f,    # The value of the fold point on our single axis.
    "x=f"    => \$x,    # Cartesian x coordinate.
    "y=f"    => \$y,    # Cartesian y coordinate.
    "n=f"    => \@n,    # Unordered --n_lower and --n_higher
##  "n_lower=f"  => \$l,    # The lower valued coordinate of our single axis.
##  "n_higher=f" => \$h,    # The higher valued coordinate of our single axis.
##  "quadrant=s" => \$quadrant,    # nw sw se ne ◰ ◱ ◲ ◳ ◴ ◵ ◶ ◷

) or die("Error in command line arguments\n");

## for ($quadrant) {
##     next unless defined;
##          s/◰|◴/nw/
##       || s/◱|◵/sw/
##       || s/◲|◶/se/
##       || s/◳|◷/ne/;
## }

## for ($direction) {
##     next unless defined;
##          s/↑/n/
##       || s/→/e/
##       || s/↓/s/
##       || s/←/w/;
## }

if ($axis) {
    ## for (qw/quadrant direction/) {
    ##     die "cannot set both --axis and --$_." if eval "\$$_";
    ## }
    for ($axis) {
        s/轉/2/ || next;
        s/西/w/;
        s/北/n/;
        s/東/e/;
        s/南/s/;
    }
    if ( $axis eq "⮤" || $axis eq "w2n" ) {    # w2n: west to north
        $quadrant  = "ne";
        $direction = "n";
    }
    elsif ( $axis eq "⮥" || $axis eq "e2n" ) {
        $quadrant  = "nw";
        $direction = "n";
    }
    elsif ( $axis eq "⮠ " || $axis eq "s2w" ) {
        $quadrant  = "nw";
        $direction = "w";
    }
    elsif ( $axis eq "⮢ " || $axis eq "n2w" ) {
        $quadrant  = "sw";
        $direction = "w";
    }
    elsif ( $axis eq "⮡" || $axis eq "n2e" ) {
        $quadrant  = "ne";
        $direction = "e";
    }
    elsif ( $axis eq "⮣" || $axis eq "n2e" ) {
        $quadrant  = "se";
        $direction = "e";
    }
    elsif ( $axis eq "⮧." || $axis eq "e2s" ) {
        $quadrant  = "sw";
        $direction = "s";
    }
    elsif ( $axis eq "⮦ " || $axis eq "w2s" ) {
        $quadrant  = "se";
        $direction = "s";
    }
    else { die "unknown --axis \"$axis\"" }
}
else { die "didn't set --axus."; }
if ( $direction eq "n" ) {
    if ( $quadrant eq "ne" ) {    # ◳ ⮤
        $X = sub { $f - $l };
        $Y = sub { $h - $f };
        $L = sub { $f - $x };
        $H = sub { $y + $f };
    }
    elsif ( $quadrant eq "nw" ) {    # ◰ ⮥
        $X = sub { $l - $f };
        $Y = sub { $h - $f };
        $L = sub { $f + $x };
        $H = sub { $y + $f };
    }
    else { die "odd --quadrant for this --direction." }
}
elsif ( $direction eq "w" ) {
    if ( $quadrant eq "nw" ) {       # ◰ ⮠
        $X = sub { $f - $h };
        $Y = sub { $f - $l };
        $L = sub { $f - $y };
        $H = sub { $f - $x };
    }
    elsif ( $quadrant eq "sw" ) {    # ◱ ⮢
        $X = sub { $f - $h };
        $Y = sub { $l - $f };
        $L = sub { $f + $y };
        $H = sub { $f - $x };
    }
    else { die "odd --quadrant for this --direction." }
}
elsif ( $direction eq "s" ) {
    if ( $quadrant eq "sw" ) {       # ◱ ⮧
        $X = sub { $l - $f };
        $Y = sub { $f - $h };
        $L = sub { $f + $x };
        $H = sub { $f - $y };
    }
    elsif ( $quadrant eq "se" ) {    # ◲ ⮦
        $X = sub { $f - $l };
        $Y = sub { $f - $h };
        $L = sub { $f - $x };
        $H = sub { $f - $y };
    }
    else { die "odd --quadrant for this --direction." }
}
elsif ( $direction eq "e" ) {
    if ( $quadrant eq "se" ) {       # ◲ ⮣
        $X = sub { $h - $f };
        $Y = sub { $l - $f };
        $L = sub { $f + $y };
        $H = sub { $f + $x };
    }
    elsif ( $quadrant eq "ne" ) {    # ◳ ⮡
        $X = sub { $h - $f };
        $Y = sub { $f - $l };
        $L = sub { $f - $y };
        $H = sub { $f + $x };
    }
    else { die "odd --quadrant for this --direction." }
}
else { die "--direction not one of n, w, s, e." }
if (@n) {
    die "need --n n0 --n n1. Order doesn't matter." unless @n == 2;
    for (qw/n_lower n_higher/) {
        die "cannot set both --n and --$_." if eval "defined \$$_";
    }
    ( $l, $h ) = ( sort @n );
}
if ( defined $h || defined $l ) {
    die "--n_higher not defined." unless defined $h;
    die "--n_lower not defined."  unless defined $l;
    die "--n_lower bigger than --n_higher." if $l > $h;
    die "--n_higher less than --fold."      if $h < $f;
    die "--n_lower greater than --fold."    if $l > $f;
    printf "(x,y)=(%s,%s)$/", &$X, &$Y;
}
elsif ( defined $x || defined $y ) {
    die "--x not defined." unless defined $x;
    die "--y not defined." unless defined $y;
    printf "(n_lower,n_higher)=(%s,%s)$/", &$L, &$H;
}
else { die "need --x and --y, or --n_lower and --n_higher." }
