package edu.stanford.bmir.styledstring.swing;

import edu.stanford.bmir.styledstring.StyledString;

import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.util.ArrayList;
import java.util.List;

/**
 * Matthew Horridge
 * Stanford University
 * Bio-Medical Informatics Research Group
 * Date: 5th December 2014
 */
public class StyledStringLayout {


    private final List<TextLayoutCache> textLayoutLines = new ArrayList<TextLayoutCache>();

    public StyledStringLayout(StyledString styledString) {
        createLines(styledString);
    }


    private void createLines(StyledString styledString) {
        if (styledString.isEmpty()) {
            return;
        }
        String[] lines = styledString.getString().split("\\n");
        int lineStart = 0;
        int lineEnd = 0;
        final AttributedStringRenderer attributedStringRenderer = new AttributedStringRenderer();
        final AttributedCharacterIterator iterator = attributedStringRenderer.toAttributedString(styledString).getIterator();
        for (String line : lines) {
            lineEnd = lineStart + line.length();
            AttributedString attributedLine = new AttributedString(iterator, lineStart, lineEnd);
            textLayoutLines.add(new TextLayoutCache(attributedLine));
            lineStart = lineEnd + 1;
        }
    }


    public float getWidth(FontRenderContext fontRenderContext) {
        float maxWidth = 0;
        for (TextLayoutCache cache : textLayoutLines) {
            float visibleAdvance = cache.getVisibleAdvance(fontRenderContext);
            if (visibleAdvance > maxWidth) {
                maxWidth = visibleAdvance;
            }
        }
        return maxWidth;
    }

    public float getHeight(FontRenderContext fontRenderContext) {
        float height = 0;
        for (TextLayoutCache textLayoutCache : textLayoutLines) {
            height += textLayoutCache.getHeight(fontRenderContext);
        }
        return height;
    }

    public void draw(Graphics2D g2, float x, float y) {
        float yOffset = y;
        float leading = 0;
        float ascent = 0;
        float descent = 0;
        for (TextLayoutCache cache : textLayoutLines) {
            FontRenderContext frc = g2.getFontRenderContext();
            TextLayout textLayout = cache.getTextLayout(frc);
            leading = textLayout.getLeading();
            ascent = textLayout.getAscent();
            yOffset += leading + ascent + descent;
            textLayout.draw(g2, x, yOffset);
            descent = textLayout.getDescent();

        }

    }


}

@@ -36,24 +36,72 @@
 ing.swing;%0A%0A
+import com.google.common.collect.ImmutableList;%0A
 import edu.s
@@ -540,16 +540,25 @@
 e final 
+Immutable
 List%3CTex
@@ -590,43 +590,8 @@
 ines
- = new ArrayList%3CTextLayoutCache%3E()
 ;%0A%0A 
@@ -655,16 +655,34 @@
 %0A       
+ textLayoutLines =
  createL
@@ -721,20 +721,53 @@
 private 
-void
+static ImmutableList%3CTextLayoutCache%3E
  createL
@@ -856,16 +856,35 @@
   return
+ ImmutableList.of()
 ;%0A      
@@ -982,33 +982,8 @@
  0;%0A
-        int lineEnd = 0;%0A
     
@@ -1198,24 +1198,106 @@
 Iterator();%0A
+        ImmutableList.Builder%3CTextLayoutCache%3E builder = ImmutableList.builder();%0A
         for 
@@ -1328,24 +1328,28 @@
             
+int 
 lineEnd = li
@@ -1483,31 +1483,23 @@
         
-textLayoutLines
+builder
 .add(new
@@ -1576,24 +1576,56 @@
 ;%0A        %7D%0A
+        return builder.build();%0A
     %7D%0A%0A%0A    
@@ -2362,20 +2362,16 @@
  leading
- = 0
 ;%0A      
@@ -2380,28 +2380,24 @@
 float ascent
- = 0
 ;%0A        fl

Tidy of StyledStringLayout