package es.sandbox.spike.connectn;

import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.Objects;

/**
 * Created by jeslopalo on 11/3/16.
 */
public class BoardPrinter {

    private static final char VERTICAL = '║';
    private static final char HORIZONTAL = '═';
    private static final char TOP_LEFT_CORNER = '╔';
    private static final char TOP_RIGHT_CORNER = '╗';
    private static final char BOTTOM_LEFT_CORNER = '╚';
    private static final char BOTTOM_RIGHT_CORNER = '╝';

    private final Board board;

    BoardPrinter(Board board) {
        Objects.requireNonNull(board, "Board may be not null");

        this.board = board;
    }

    public void printTo(OutputStream outputStream) {

        final PrintWriter writer = new PrintWriter(outputStream, true);
        final Deque<String> rows = calculateRows();

        writer.println(border(rows.peek().length(), TOP_LEFT_CORNER, TOP_RIGHT_CORNER));
        rows.stream().forEach(row -> writer.format("%1$c%2$s  %1$c\n", VERTICAL, row));
        writer.println(border(rows.peek().length(), BOTTOM_LEFT_CORNER, BOTTOM_RIGHT_CORNER));
        writer.println(this.board.getResult());
        writer.flush();
    }

    private Deque<String> calculateRows() {
        final Deque<String> rows = new ArrayDeque<>();

        this.board.dimensions().forEachPositionInRows(positions -> {
            final StringBuilder row = new StringBuilder();

            positions.forEach(position -> {
                final String color = this.board.chipAt(position)
                        .map(chip -> chip.color().name())
                        .orElse("-");
                row.append(String.format("%3s", color.substring(0, 1).toUpperCase()));
            });

            rows.push(row.toString());
        });
        return rows;
    }

    private String border(int length, char left, char right) {
        final char[] border = new char[length + 2];
        Arrays.fill(border, HORIZONTAL);
        return String.format("%c%s%c", left, new String(border), right);
    }
}

@@ -908,25 +908,25 @@
 s = 
-calculate
+stringify
 Rows();%0A
 %0A   
@@ -921,25 +921,24 @@
 Rows();%0A
-%0A
         
 writer.p
@@ -933,174 +933,126 @@
     
-writer.println(border(rows.peek().length(), TOP_LEFT_CORNER, TOP_RIGHT_CORNER));%0A        rows.stream().forEach(row -%3E writer.format(%22%251$c%252$s  %251$c%5Cn%22, VERTICAL
+final int rowLength = rows.peek().length();%0A%0A        writeBorderTop(writer, rowLength);%0A        writeRows(writer
 , row
-)
+s
 );%0A 
@@ -1067,135 +1067,67 @@
 rite
-r.println(border(rows.peek().length(), BOTTOM_LEFT_CORNER, BOTTOM_RIGHT_CORNER));%0A        writer.println(this.board.get
+BorderBottom(writer, rowLength);%0A        write
 Result(
-)
+writer
 );%0A 
@@ -1186,17 +1186,17 @@
 ng%3E 
-calculate
+stringify
 Rows
@@ -1617,16 +1617,195 @@
 .append(
+formatColor(color));%0A            %7D);%0A%0A            rows.push(row.toString());%0A        %7D);%0A        return rows;%0A    %7D%0A%0A    private String formatColor(String color) %7B%0A        return 
 String.f
@@ -1857,98 +1857,595 @@
 e())
-)
 ;%0A    
+%7D%0A%0A
     
-    %7D);%0A%0A            rows.push(row.toString());%0A        %7D
+private void writeBorderTop(PrintWriter writer, int rowLength) %7B%0A        writer.println(border(rowLength, TOP_LEFT_CORNER, TOP_RIGHT_CORNER));%0A    %7D%0A%0A    private void writeRows(PrintWriter writer, Deque%3CString%3E rows) %7B%0A        rows.stream().forEach(row -%3E writer.format(%22%251$c%252$s  %251$c%5Cn%22, VERTICAL, row));%0A    %7D%0A%0A    private void writeBorderBottom(PrintWriter writer, int rowLength) %7B%0A        writer.println(border(rowLength, BOTTOM_LEFT_CORNER, BOTTOM_RIGHT_CORNER)
 );%0A    
+%7D%0A%0A
     
-return rows
+private void writeResult(PrintWriter writer) %7B%0A        writer.println(this.board.getResult())
 ;%0A  

Reformat BoardPrinter