// I don't like this one

class SpiralMatrix {
    companion object {
        fun ofSize(x: Int): Array<IntArray> {
            return Easy320.generateSpiral(x, clockwise = Clockwise.CLOCKWISE)
        }
    }
}

internal enum class Direction {
    UP, RIGHT, DOWN, LEFT
}

internal enum class Clockwise {
    CLOCKWISE, COUNTER_CLOCKWISE
}

internal object Easy320 {
    @JvmStatic fun main(args: Array<String>) {
        val board = generateSpiral(30, Clockwise.COUNTER_CLOCKWISE)
        printBoard(board, 30)
    }

    // length     -- Length of spiral
    // clockwise  -- Direction of sprial (clockwise, counter-clockwise)
    fun generateSpiral(length: Int, clockwise: Clockwise): Array<IntArray> {
        var x = 0
        var y = 0  // (y, x) Position to place index
        var index = 1
        var direction = if (clockwise == Clockwise.CLOCKWISE) Direction.RIGHT else Direction.DOWN

        val board = Array(length) { IntArray(length) }

        while (index <= length * length) {
            board[y][x] = index++ // arrays are wierd

            // When moving the position, X is the position on the X-axis,
            // Y is the position on the Y-axis.
            if (direction == Direction.RIGHT) {
                if (x == length - 1 || board[y][x + 1] != 0) {
                    if (clockwise == Clockwise.CLOCKWISE) {
                        direction = Direction.DOWN
                        y++
                    } else {
                        direction = Direction.UP
                        y--
                    }
                } else {
                    x++
                }
            } else if (direction == Direction.DOWN) {
                if (y == length - 1 || board[y + 1][x] != 0) {
                    if (clockwise == Clockwise.CLOCKWISE) {
                        direction = Direction.LEFT
                        x--
                    } else {
                        direction = Direction.RIGHT
                        x++
                    }
                } else {
                    y++
                }
            } else if (direction == Direction.LEFT) {
                if (x == 0 || board[y][x - 1] != 0) {
                    if (clockwise == Clockwise.CLOCKWISE) {
                        direction = Direction.UP
                        y--
                    } else {
                        direction = Direction.DOWN
                        y++
                    }
                } else {
                    x--
                }
            } else if (direction == Direction.UP) {
                if (y == 0 || board[y - 1][x] != 0) {
                    if (clockwise == Clockwise.CLOCKWISE) {
                        direction = Direction.RIGHT
                        x++
                    } else {
                        direction = Direction.LEFT
                        x--
                    }
                } else {
                    y--
                }
            }
        }

        return board
    }

    fun printBoard(board: Array<IntArray>, length: Int) {
        val spaces = (length * length).toString().length + 1

        for (x in board) {
            for (y in x) {
                val lenY = y.toString().length
                System.out.printf("%s%d", genStr(spaces - lenY), y)
            }
            println()
        }
        println()
    }

    fun genStr(length: Int): String {
        var output = ""

        for (i in 0..length - 1) {
            output += " "
        }

        return output
    }
}