package ru.denull.wire;
import java.awt.*;
import java.util.HashMap;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.text.View;
public class MessageLayout implements LayoutManager2 {
public static final String PHOTO = "photo";
public static final String BODY = "body";
public static final String DATE = "date";
public static final String ACTIONS = "actions";
public HashMap<String, Component> comps = new HashMap<String, Component>();
public boolean leftSide;
public String html;
public EmojiLabel label;
public int vmargin, hmargin;
public double bodyWeight = 0.7;
public int photoSideMargin = 4;
public int photoBottomMargin = 4;
public int photoMargin = 4;
public int messageBottomMargin = 3;
public int dateMargin = 4;
public int dateBottomMargin = 6;
public int actionsMargin = 4;
public JList list = null;
public MessageLayout(JList list, boolean leftSide) {
this.list = list;
this.leftSide = leftSide;
}
public void setHTMLBody(EmojiLabel label, int vmargin, int hmargin) {
//this.html = html;
this.label = label;
this.vmargin = vmargin;
this.hmargin = hmargin;
}
public void addLayoutComponent(String tag, Component comp) {
comps.put(tag, comp);
}
public void addLayoutComponent(Component comp, Object tag) {
comps.put((String) tag, comp);
}
public void removeLayoutComponent(Component comp) {
comps.values().remove(comp);
}
public void layoutContainer(final Container container) {
Component photo = comps.get(PHOTO);
Component body = comps.get(BODY);
Component date = comps.get(DATE);
Component actions = comps.get(ACTIONS);
Dimension size = container.getSize();
Insets insets = container.getInsets();
int pos = (leftSide ? insets.left : insets.right) + photoSideMargin;
if (photo != null) {
photo.setSize(photo.getPreferredSize());
photo.setLocation(leftSide ? pos : (size.width - pos - photo.getWidth()), size.height - insets.bottom - photo.getHeight() - photoBottomMargin);
pos += photo.getWidth() + photoMargin;
}
if (body != null) {
int width;
if (label != null) {
Dimension min = body.getMinimumSize();
width = Math.max((int) (size.width * bodyWeight), min.width);
int height = Math.max(getPreferredSize(html, true, width) + vmargin, min.height);
width = Math.max(Math.min(width + hmargin, body.getPreferredSize().width), min.width);
body.setBounds(leftSide ? pos : (size.width - pos - width), insets.top, width, height);
//System.out.println(width + "X" + height);
} else {
width = Math.min((int) (size.width * bodyWeight), body.getPreferredSize().width);
body.setBounds(leftSide ? pos : (size.width - pos - width), insets.top, width, width * body.getPreferredSize().height / body.getPreferredSize().width);
}
pos += width;
}
if (date != null) {
date.setSize(date.getPreferredSize());
date.setLocation(leftSide ? (pos + dateMargin) : (size.width - pos - dateMargin - date.getWidth()), size.height - insets.bottom - date.getHeight() - dateBottomMargin);
}
if (actions != null) {
actions.setSize(actions.getPreferredSize());
actions.setLocation(leftSide ? (pos + actionsMargin) : (size.width - pos - actionsMargin - actions.getWidth()), insets.top + (size.height - insets.top - insets.bottom - actions.getHeight()) / 2);
}
//container.setSize(size.width, insets.left + insets.right + getMaximumHeight(size.width));
}
public Dimension minimumLayoutSize(Container container) {
return new Dimension(list.getWidth(), getMinimumHeight());
}
public Dimension preferredLayoutSize(Container container) {
return new Dimension(list.getWidth(), getMaximumHeight(list.getWidth()));
}
public int getMaximumHeight(int width) {
Component photo = comps.get(PHOTO);
Component body = comps.get(BODY);
Component date = comps.get(DATE);
Component actions = comps.get(ACTIONS);
int height = 0;
if (photo != null) {
height = Math.max(height, photo.getPreferredSize().height + photoBottomMargin);
}
if (body != null) {
if (label != null) {
Dimension min = body.getMinimumSize();
height = Math.max(height, Math.max(getPreferredSize(html, true, Math.max((int) (width * bodyWeight), min.width)) + vmargin, min.height) + messageBottomMargin);
//System.out.println("width: " + width + ", h" + Math.max(getPreferredSize(html, true, Math.max((int) (width * bodyWeight), min.width)).height + vmargin, min.height));
} else {
int w = Math.min((int) (width * bodyWeight), body.getPreferredSize().width);
height = Math.max(height, w * body.getPreferredSize().height / body.getPreferredSize().width + messageBottomMargin);
}
}
if (date != null || actions != null) {
height = Math.max(height, (date != null ? date.getPreferredSize().height + dateBottomMargin : 0) + (actions != null ? actions.getPreferredSize().height : 0));
}
return height;
}
public int getMinimumHeight() {
Component photo = comps.get(PHOTO);
Component body = comps.get(BODY);
Component date = comps.get(DATE);
Component actions = comps.get(ACTIONS);
int height = 0;
if (photo != null) {
height = Math.max(height, photo.getPreferredSize().height);
}
if (body != null) {
if (label != null) {
Dimension min = body.getMinimumSize();
height = Math.max(height, min.height);
} else {
height = Math.max(height, 10);
}
}
if (date != null || actions != null) {
height = Math.max(height, (date != null ? date.getPreferredSize().height : 0) + (actions != null ? actions.getPreferredSize().height : 0));
}
return height;
}
//private static final JLabel resizer = new JLabel();
/**
* Returns the preferred size to set a component at in order to render an html string. You can
* specify the size of one dimension.
*/
public int getPreferredSize(String html, boolean width, int prefSize) {
/*
resizer.setText(html);
//Utils.fixEmoji(resizer);
View view = (View) resizer.getClientProperty("html");
view.setSize(width ? prefSize : 0, width ? 0 : prefSize);
float w = view.getPreferredSpan(View.X_AXIS);
float h = view.getPreferredSpan(View.Y_AXIS);
return new java.awt.Dimension((int) Math.ceil(w), (int) Math.ceil(h));
*/
return width ? label.getHeightForWidth(prefSize) : label.getMaximalWidth();
}
@Override
public float getLayoutAlignmentX(Container container) {
return 0;
}
@Override
public float getLayoutAlignmentY(Container container) {
return 0;
}
@Override
public void invalidateLayout(Container container) {
}
public Dimension maximumLayoutSize(Container container) {
return new Dimension(list.getWidth(), getMaximumHeight(0));
}
}