
my $number_start;
sub layout_crossword {
    my(@crossword) = @_;
    $number_start = 1;

    my @puzzle;
    my @puzzle_lines;

    # Turn each line of the puzzle into an array reference
    # This array will be used later to determine if a box starts a word
    foreach my $row (@crossword) {
        my @puzzle_row = split //, $row;
        push(@puzzle, \@puzzle_row);
    }

    # Break each line for the boxes up into 2 strings, the left most
    # character and the rest of the box
    my @letter_box;
    my @filled_box;

    foreach my $row (@empty_square) {
        my $left = substr($row, 0, 1);
        my $rest = substr($row, 1);
        push(@letter_box, [$left, $rest]);
    }

    foreach my $row (@full_square) {
        my $left = substr($row, 0, 1);
        my $rest = substr($row, 1);
        push(@filled_box, [$left, $rest]);
    }

    my $box_height = scalar(@empty_square);

    # Only draw the top part of the boxes if this is the first row
    # Only draw the left part of the box if it is the first box in the row

    # Loop through the boxes
    for my $row (0..$#puzzle) {
        # Determine if this is the first row
        my $top_row = ($row == 0) ? 1 : 0;
        my $rows_to_add = $box_height-1;
        my @row_lines;
        for my $i (0..$rows_to_add) {
            $row_lines[$i] = "";
        }

        for my $column (0..scalar(@{$puzzle[$row]})-1) {
            my $box = $puzzle[$row][$column];
            my $left_column = ($column == 0) ? 1 : 0;
            if($box eq 'X') {
                # print a filled box
                if($top_row) {
                    if($left_column) {
                        $row_lines[0] .= $filled_box[0][0];
                    }
                    $row_lines[0] .= $filled_box[0][1];
                }
                for my $i (1..$rows_to_add) {
                    if($left_column) {
                        $row_lines[$i] .= $letter_box[$i][0];
                    }
                    $row_lines[$i] .= $filled_box[$i][1];
                }

            } elsif ($box eq '.') {
                # print a letter box
                # Do we print the top row
                if($top_row) {
                    if($left_column) {
                        $row_lines[0] .= $letter_box[0][0];
                    }
                    $row_lines[0] .= $letter_box[0][1];
                }
                # If the number, if there is one, goes in the topmost, leftmost
                # empty space of the box

                # Get number will either return the number to print in the
                # box or an empty string.
                my $number = getNumber($row, $column, \@puzzle);
                for my $i (1..$rows_to_add) {
                    if($left_column) {
                        $row_lines[$i] .= $letter_box[$i][0];
                    }
                    if($i == 1 && $number) {
                        my $numeral_length = length($number);
                        my $row_length = length($letter_box[$i][1]);
                        # Take one away from the row length for the right
                        # border
                        $row_length--;
                        if($numeral_length > $row_length) {
                            die("Too many words for box size given.\n");
                        } else {
                            # Substitute the line in.
                            $row_lines[$i] .= $number . substr($letter_box[$i][1], $numeral_length-$row_length-1);
                        }
                    } else {
                        $row_lines[$i] .= $letter_box[$i][1];
                    }
                }
            } else {
                die("Bad box input.\n");
                }
        }
        # Only print the top of the box for the first row
        unless($top_row) {
            my $dross = shift(@row_lines);
        }
        push(@puzzle_lines, @row_lines);
    }

    # Change . to space
    for my $i (0..$#puzzle_lines) {
        $puzzle_lines[$i] =~ tr/./ /;
    }

    return @puzzle_lines;
}

# Determines if the box is the start of a word
# This is only called for letter boxes
sub getNumber {
    my($row, $column, $layout) = @_;

    my $number = "";

    die("Bad row: $row.\n") if($row < 0);
    die("Bad column: $column.\n") if($column < 0);

    # Top row
    if($row == 0) {
        # top left corner, box can't be in the middle of a word
        if($column == 0) {
            $number = $number_start;
            $number_start++;
        } else {
            # To start a word on the top row, there needs to be a blank
            # below the square or a filled square to the left and a
            # letter square to the right
            if($layout->[$row][$column - 1] eq 'X' && # left square
               $layout->[$row][$column + 1] eq '.') {
                $number = $number_start;
                $number_start++;
            } elsif($layout->[$row+1][$column] eq '.') {
                $number = $number_start;
                $number_start++;
            }
        }
    } else {
        if($column == 0) {
            # Left most position, starts a word if left a letter to the right
            # or a letter below and a filled box above
            if($layout->[$row][$column + 1] eq '.') {
                $number = $number_start;
                $number_start++;
            } elsif($layout->[$row - 1][$column] eq 'X' && # above square
                    $layout->[$row + 1][$column] eq '.' # below square
                   ){
                $number = $number_start;
                $number_start++;
            }
        } else {
            # There needs to be a filled square to the left or above
            # the current square and a letter correspondingly in line
            if($layout->[$row - 1][$column] eq 'X' && # above square
               $layout->[$row + 1][$column] eq '.' # below square
              ){
                $number = $number_start;
                $number_start++;
            } elsif ($layout->[$row][$column - 1] eq 'X' && # left square
                     $layout->[$row][$column + 1] eq '.') {
                $number = $number_start;
                $number_start++;
            }
        }
    }

    return $number;
}





