
use TestXWord;
sub deperiodize { map { tr/./ /; $_ } @_ }

# Takes an array of strings.
# Returns array of two-element arrays: [all but last char, last char]
sub strip_last_char { map { [substr( $_, 0, length($_)-1 ),
                             substr( $_, length($_)-1, 1 )] } @_ }

# @empty_square and @full_square broken up in that fashion

# Takes an array of strings such as sample_puzzle.
# Returns a 2D array of numbers representing that grid:
#  -1 means full.
#   0 means empty and unnumbered.
#   n >= 1 means empty and numbered n.
sub compute_numbers {
  my $running_number = 1;
  my @lines = ();
  my $num;
  for $y (0..$#_) {
    my @line = ();
    for $x (0..length($_[0])-1) {
      if (substr( $_[$y], $x, 1 ) eq ".") {
        if ($x == 0 ||
            $y == 0 ||
            $line[$x-1] == -1 ||
            $lines[$y-1][$x] == -1) {
          $num = $running_number++;
        } else {
          $num = 0;
        }
      } else {
        $num = -1;
      }
      push @line, $num;
    }
    push @lines, \@line;
  }
  return @lines;
}

# Computes a piece of one line of the output, for the $line_numth horizontal
# line of a square with number $number.
sub piece {
  my ($line_num, $number) = @_;
  my $square = ($number == -1 ? \@UL_full_square : \@UL_empty_square);
  my $piece = $square->[$line_num][0];
  if ($number > 0 && $line_num == 1) {
    $len_num = length $number;
    die "Insufficient space for numbers" unless $piece =~ s/ {$len_num}/$number/;
  }
  $piece;
}

# Produces the $ith output line of $input_line, which is a reference
# to one row of numbers as specified above.
sub layout_line {
  my ($i, $input_line) = @_;
  my @pieces = map { piece( $i, $_ ) } @$input_line;
  push @pieces, substr( piece( $i, $input_line->[-1] ), 0, 1 );
  my $output_line = (join '', @pieces);
}

sub layout_crossword {
  @UL_empty_square = strip_last_char( deperiodize( @empty_square ) );
  @UL_full_square = strip_last_char( deperiodize( @full_square ) );
  my $square_height = @UL_empty_square;
  my @lines = ();
  my @numbers = compute_numbers( @_ );
  for my $input_line (@numbers) {
    for my $i (0.. $square_height-2) {
      push @lines, layout_line( $i, $input_line );
    }
  }
  push @lines, layout_line( $square_height-1, $numbers[-1] );
  return @lines;
}

