package usda.weru.wmrm;


import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import com.klg.jclass.cell.JCCellInfo;
import com.klg.jclass.cell.JCLightCellRenderer;
import com.klg.jclass.cell.Utilities;
import java.awt.Font;
import java.awt.FontMetrics;
import java.util.StringTokenizer;

/**
 *
 * @author Ryan
 */
public class WmrmWordWrapCellRenderer implements JCLightCellRenderer{
    
    private static final long serialVersionUID = 1L;
    protected Utilities   utilities = new Utilities();
    protected boolean     drawClipArrowOutline = true;
    
    @Override
    public void draw(Graphics gc, JCCellInfo cellInfo, Object o, boolean selected) {
        if (o == null) {
		return;
        }
	String display = o.toString();

	if (display == null || display.length() == 0) {
		return;
        }

	Rectangle cell_size = cellInfo.getDrawingArea();
	gc.setFont(cellInfo.getFont());
	FontMetrics fm = gc.getFontMetrics();
	gc.setColor(selected ? cellInfo.getSelectedForeground() :
				cellInfo.getForeground());

        int hAlign = cellInfo.getHorizontalAlignment();
        int vAlign = cellInfo.getVerticalAlignment();
	display = wordWrap(display, fm, cell_size.width, (hAlign != JCCellInfo.RIGHT));

        int h = fm.getHeight();
        int offset_x = 0, offset_y = h - 4;
	if (display.indexOf('\n') != -1) {

            int height = getHeight(fm, display);
            if (vAlign == JCCellInfo.CENTER) {
                offset_y += (cell_size.height - height) / 2;
            }
            else if (vAlign == JCCellInfo.BOTTOM) {
                offset_y += cell_size.height - height;
            }

            StringTokenizer tokenizer = new StringTokenizer(display, "\n", false);
            while (tokenizer.hasMoreTokens()) {
                String token = tokenizer.nextToken().trim();
                if (hAlign == JCCellInfo.CENTER) {
                    offset_x = (cell_size.width - fm.stringWidth(token)) / 2;
                }
                else if (hAlign == JCCellInfo.RIGHT) {
                    offset_x = cell_size.width - fm.stringWidth(token);
                }

                gc.drawString(token, offset_x, offset_y);
                offset_y += h;
            }
	}
	else {
            // Adjust for horizontal alignment
            if (hAlign == JCCellInfo.RIGHT) {
                offset_x += cell_size.width - fm.stringWidth(display);
            }
            else if (hAlign == JCCellInfo.CENTER) {
                offset_x += (cell_size.width - fm.stringWidth(display)) / 2;
            }

            // Adjust for vertical alignment
            if (vAlign == JCCellInfo.CENTER) {
                offset_y += (cell_size.height - fm.getHeight()) / 2;
            }
            else if(vAlign == JCCellInfo.BOTTOM) {
                offset_y += cell_size.height - fm.getHeight();
            }
            

            gc.drawString(display, offset_x, offset_y);
        }

    // Arrows are drawn using the current foreground color
    Dimension ps = getPreferredSize(gc, cellInfo, display);
    if ((ps.width > cell_size.width || ps.height > cell_size.height) &&
        cellInfo.getClipHints() != JCCellInfo.SHOW_NONE) {
        Utilities.drawClipArrows(gc, cellInfo, ps, 
            Utilities.DEFAULT_CLIP_ARROW_SIZE, 
            drawClipArrowOutline);
	}
    }

    @Override
    public Dimension getPreferredSize(Graphics gc, JCCellInfo cellInfo, Object o) {
        if (o == null) {
            return(null);
        }

        Font f = cellInfo.getFont();
        if (gc != null && f != null) {
            gc.setFont(f);
        }

        String display = o.toString();
        if (display == null || display.length() == 0) {
            return(new Dimension(0,0));
        }

        FontMetrics fm = gc.getFontMetrics();
        int width = cellInfo.getDrawingArea().width;

        int hAlign = cellInfo.getHorizontalAlignment();
        display = wordWrap(display, fm, width, (hAlign != JCCellInfo.RIGHT));
        return(new Dimension(getWidth(fm, display), getHeight(fm, display)));
    }
    
    public int getHeight(FontMetrics fm, String s) {
	if (s == null || s.length() == 0) {
		return(0);
    }
	int lines = 1;
	for (int i = 0; i < s.length(); i++) {
		if (s.charAt(i) == '\n') {
            lines++;
        }
    }

	return(fm.getHeight() * lines);
    }
    
    public int getWidth(FontMetrics fm, String text){
	if (text == null || text.length() == 0) {
		return(0);
        }

            // Manually calculate width of multi-line string
            if (text.indexOf('\n') != -1) {
                    int start = 0, end = 0, width = 0;
                    while ((end = text.indexOf('\n', start)) != -1) {
                            width = Math.max(width, fm.stringWidth(text.substring(start, end)));
                start = end + 1;
            }
                    return(Math.max(width,
                            fm.stringWidth(text.substring(start, text.length()))));
            }
            else {
                    return(fm.stringWidth(text));
            }
        }

    private String wordWrap(String text, FontMetrics fm, int width, boolean isLeftAligned) {
        if (width < 10) {
        return(text);
        }

        if (text == null || text.length() == 0) {
            return(text);
        }

        // Return the input string if its length is less than the wrap width
        if (fm.stringWidth(text) < width) {
            return(text);
        }

        int char_width = 0;
        int line_width  = 0;
        StringBuffer buffer = new StringBuffer(text.length());

        // Create a string tokenizer using space as the delimiter
        //StringTokenizer tokenizer = new StringTokenizer(text, " ", true);
        int i = 0;
        while (i < text.length()) {
            String character = text.substring(i, i + 1);
            char_width = fm.stringWidth(character);
            if (line_width + char_width > width) {
                buffer.append("\n");
                buffer.append(character);
                line_width = char_width;
            }
            else {
                buffer.append(character);
                line_width += char_width;
            }
            i++;
        }
        return(buffer.toString());
    }
}
