package uk.co.littlemike.editree.text;

import uk.co.littlemike.editree.language.statements.Assignment;
import uk.co.littlemike.editree.language.statements.Statement;
import uk.co.littlemike.editree.language.statements.StatementVisitor;
import uk.co.littlemike.editree.language.statements.VariableDeclaration;
import uk.co.littlemike.editree.language.statements.control.WhileLoop;

public class StatementRenderer {
    private final ExpressionRenderer expressionRenderer = new ExpressionRenderer();

    public String render(Statement statement) {
        return renderWithContext(statement, new StatementRenderContext());
    }

    private String renderWithContext(Statement statement, StatementRenderContext context) {
        statement.visit(new StatementVisitor() {
            @Override
            public void visit(VariableDeclaration declaration) {
                renderToString(declaration, context);
            }
            @Override
            public void visit(WhileLoop loop) {
                renderToString(loop, context);
            }

            @Override
            public void visit(Assignment assignment) {
                renderToString(assignment, context);
            }
        });
        return context.getRenderedText();
    }

    private void renderToString(Assignment assignment, StatementRenderContext context) {
        context.appendLine(
                assignment.getVariableName() +
                " = " +
                expressionRenderer.render(assignment.getValue()) +
                ";"
        );
    }

    private void renderToString(VariableDeclaration declaration, StatementRenderContext context) {
        if (declaration.hasInitialValue()) {
            context.appendLine(
                    declaration.getType().getName() +
                    " " +
                    declaration.getName() +
                    " = " +
                    expressionRenderer.render(declaration.getInitialValue().get()) +
                    ";"
            );
        }
        else {
            context.appendLine(
                    declaration.getType().getName() +
                    " " +
                    declaration.getName() +
                    ";"
            );
        }
    }

    private void renderToString(WhileLoop loop, StatementRenderContext context) {
        context.appendLine(String.format(
                "while (%s) {",
                expressionRenderer.render(loop.getCondition())
        ));

        for (Statement statement : loop.getStatements()) {
            context.increaseIndent();
            renderWithContext(statement, context);
            context.decreaseIndent();
        }
        context.appendLine("}");
    }
}

@@ -1364,32 +1364,74 @@
 text.appendLine(
+String.format(%0A                %22%25s = %25s;%22,
 %0A               
@@ -1463,34 +1463,9 @@
 me()
- +%0A                %22 = %22 +
+,
 %0A   
@@ -1525,18 +1525,16 @@
 Value())
- +
 %0A       
@@ -1534,36 +1534,17 @@
         
-        %22;%22%0A        
+)
 );%0A    %7D
@@ -1724,62 +1724,22 @@
 ine(
-%0A                    declaration.getType().getName() +
+String.format(
 %0A   
@@ -1748,36 +1748,45 @@
                %22
- %22 +
+%25s %25s = %25s;%22,
 %0A               
@@ -1794,32 +1794,42 @@
     declaration.
+getType().
 getName() +%0A    
@@ -1813,34 +1813,33 @@
 Type().getName()
- +
+,
 %0A               
@@ -1847,15 +1847,30 @@
     
-%22 = %22 +
+declaration.getName(),
 %0A   
@@ -1948,21 +1948,17 @@
 ).get())
- +%0A  
+%0A
         
@@ -1961,38 +1961,17 @@
         
-      %22;%22%0A            
+)
 );%0A     
@@ -2025,62 +2025,22 @@
 ine(
-%0A                    declaration.getType().getName() +
+String.format(
 %0A   
@@ -2061,12 +2061,16 @@
    %22
- %22 +
+%25s %25s;%22,
 %0A   
@@ -2090,32 +2090,42 @@
     declaration.
+getType().
 getName() +%0A    
@@ -2121,10 +2121,9 @@
 me()
- +
+,
 %0A   
@@ -2143,11 +2143,29 @@
     
-%22;%22
+declaration.getName()
 %0A   
@@ -2173,16 +2173,17 @@
         
+)
 );%0A     

Use String.format