use strict;
our (@empty_square, @full_square);

use warnings;

my @xword = qw(
X.....X.....X
.X.X.X.X.X.X.
.......X.....
.X.X.X.X.X.X.
.....X.......
.XXX....XX.X.
X.....X.....X
.X.XX....XXX.
.......X.....
.X.X.X.X.X.X.
.....X.......
.X.X.X.X.X.X.
X.....X.....X
); # or whatever

my @out_puzzle;
layout_crossword (\@xword, \@empty_square, \@full_square);
print "$_\n" for @out_puzzle;

sub layout_crossword {
# Get the parameters:
#my ($puzzle, $e_square, $f_square) = @_;
my @puzzle = @_;
my @e_square = @empty_square;
my @f_square = @full_square;

# Make sure full square symbol is 'X'
s/[^.]/X/g for @puzzle;

# Declare a few variables:
my @new_puzzle;
my $sq_width = length $e_square[0];
my $sq_height = @e_square;
my $filler = substr $f_square[1], 1, 1;
my $border = substr $e_square[0], 0, 1;
my $long_line = $border x (($sq_width - 1) * (length $puzzle[0]) + 1);

# Mark squares to be numbered ('.' -> 'n'):
find_number(@puzzle); # Mark 'across' words to be numbered
rev(@puzzle); # Change vertical <-> horizontal;
find_number(@puzzle); # Mark 'down' words to be numbered
rev(@puzzle); # Change it back

# Construct the output:
my $num = 1;
for (@puzzle) {
  push @new_puzzle, $long_line;
  for my $j (1..($#e_square)) {
    my $i = 0;
    my $temp = $border;
    while (substr $_, $i, 1 ne '') {
      if ((substr $_, $i, 1) eq 'n' and $j == 1) {
        $temp .= $num.(' ' x ($sq_width - 2 - length $num));
        $num++;
        die "Number too long to fit in square" if (length $num) > ($sq_width - 2);
      }
      elsif ((substr $_, $i, 1) eq 'X') {
        $temp .= $filler x ($sq_width - 2);
      } else {
        $temp .= ' ' x ($sq_width - 2);
      }
    $temp .= $border;
    $i++;
    }
    push @new_puzzle, $temp;
  }
}
push @new_puzzle, $long_line;

@out_puzzle = @new_puzzle;

sub find_number{
  for (@_) {
    my $numbered;
    my @temp = split //;
    for my $i (0..$#temp){
      if ($temp[$i] eq 'X') {
        $numbered = '';
        next;
      }
      next if $numbered;
      if (exists $temp[$i + 1] and $temp[$i + 1] ne 'X') {
        $temp[$i] = 'n';
        $numbered = 'y';
      }
    }
    $_ = join '', @temp;
  }
}

sub rev{
  my @temp;
  for my $j (0..((length $_[0]) - 1)) {
    my $temp;
    for my $k (0..$#_) {
      $temp .= substr $_[$k], $j, 1;
    }
    push @temp, $temp;
  }
  @puzzle = @temp;
}
}



