|
1 package org.hedgewars.hedgeroid.netplay; |
|
2 |
|
3 import java.util.Date; |
|
4 import java.util.LinkedList; |
|
5 import java.util.List; |
|
6 |
|
7 import org.hedgewars.hedgeroid.R; |
|
8 |
|
9 import android.content.Context; |
|
10 import android.graphics.Color; |
|
11 import android.graphics.Typeface; |
|
12 import android.text.Html; |
|
13 import android.text.Spannable; |
|
14 import android.text.SpannableString; |
|
15 import android.text.SpannableStringBuilder; |
|
16 import android.text.Spanned; |
|
17 import android.text.TextUtils; |
|
18 import android.text.format.DateFormat; |
|
19 import android.text.style.ForegroundColorSpan; |
|
20 import android.text.style.RelativeSizeSpan; |
|
21 import android.text.style.StyleSpan; |
|
22 import android.util.Log; |
|
23 |
|
24 public class MessageLog { |
|
25 private static final int BACKLOG_CHARS = 10000; |
|
26 |
|
27 private static final int INFO_COLOR = Color.GRAY; |
|
28 private static final int CHAT_COLOR = Color.GREEN; |
|
29 private static final int MECHAT_COLOR = Color.CYAN; |
|
30 private static final int WARN_COLOR = Color.RED; |
|
31 private static final int ERROR_COLOR = Color.RED; |
|
32 |
|
33 private final Context context; |
|
34 private List<Observer> observers = new LinkedList<Observer>(); |
|
35 |
|
36 private SpannableStringBuilder log = new SpannableStringBuilder(); |
|
37 private List<Integer> lineLengths = new LinkedList<Integer>(); |
|
38 |
|
39 public MessageLog(Context context) { |
|
40 this.context = context; |
|
41 } |
|
42 |
|
43 private Spanned makeLogTime() { |
|
44 String time = DateFormat.getTimeFormat(context).format(new Date()); |
|
45 return withColor("[" + time + "] ", INFO_COLOR); |
|
46 } |
|
47 |
|
48 private static Spanned span(CharSequence s, Object o) { |
|
49 Spannable spannable = new SpannableString(s); |
|
50 spannable.setSpan(o, 0, s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); |
|
51 return spannable; |
|
52 } |
|
53 |
|
54 private static Spanned withColor(CharSequence s, int color) { |
|
55 return span(s, new ForegroundColorSpan(color)); |
|
56 } |
|
57 |
|
58 private static Spanned bold(CharSequence s) { |
|
59 return span(s, new StyleSpan(Typeface.BOLD)); |
|
60 } |
|
61 |
|
62 private void append(CharSequence msg) { |
|
63 SpannableStringBuilder ssb = new SpannableStringBuilder(); |
|
64 ssb.append(makeLogTime()).append(msg).append("\n"); |
|
65 appendRaw(ssb); |
|
66 } |
|
67 |
|
68 private void appendRaw(CharSequence msg) { |
|
69 lineLengths.add(msg.length()); |
|
70 log.append(msg); |
|
71 while(log.length() > BACKLOG_CHARS) { |
|
72 log.delete(0, lineLengths.remove(0)); |
|
73 } |
|
74 for(Observer o : observers) { |
|
75 o.textChanged(log); |
|
76 } |
|
77 } |
|
78 |
|
79 void appendPlayerJoin(String playername) { |
|
80 append(withColor("***" + context.getResources().getString(R.string.log_player_join, playername), INFO_COLOR)); |
|
81 } |
|
82 |
|
83 void appendPlayerLeave(String playername, String partMsg) { |
|
84 String msg = "***"; |
|
85 if(partMsg != null) { |
|
86 msg += context.getResources().getString(R.string.log_player_leave_with_msg, playername, partMsg); |
|
87 } else { |
|
88 msg += context.getResources().getString(R.string.log_player_leave, playername); |
|
89 } |
|
90 append(withColor(msg, INFO_COLOR)); |
|
91 } |
|
92 |
|
93 void appendChat(String playerName, String msg) { |
|
94 if(msg.startsWith("/me ")) { |
|
95 append(withColor("*"+playerName+" "+msg, MECHAT_COLOR)); |
|
96 } else { |
|
97 Spanned name = bold(playerName+": "); |
|
98 Spanned fullMessage = withColor(TextUtils.concat(name, msg), CHAT_COLOR); |
|
99 append(fullMessage); |
|
100 } |
|
101 } |
|
102 |
|
103 void appendMessage(int type, String msg) { |
|
104 switch(type) { |
|
105 case JnaFrontlib.NETCONN_MSG_TYPE_ERROR: |
|
106 append(withColor("***"+msg, ERROR_COLOR)); |
|
107 break; |
|
108 case JnaFrontlib.NETCONN_MSG_TYPE_WARNING: |
|
109 append(withColor("***"+msg, WARN_COLOR)); |
|
110 break; |
|
111 case JnaFrontlib.NETCONN_MSG_TYPE_PLAYERINFO: |
|
112 // TODO better formatting or different way to display |
|
113 append(msg); |
|
114 break; |
|
115 case JnaFrontlib.NETCONN_MSG_TYPE_SERVERMESSAGE: |
|
116 appendRaw(span(TextUtils.concat("\n", Html.fromHtml(msg), "\n\n"), new RelativeSizeSpan(1.5f))); |
|
117 break; |
|
118 default: |
|
119 Log.e("MessageLog", "Unknown messagetype "+type); |
|
120 } |
|
121 } |
|
122 |
|
123 void clear() { |
|
124 log.clear(); |
|
125 lineLengths.clear(); |
|
126 } |
|
127 |
|
128 public void observe(Observer o) { |
|
129 observers.add(o); |
|
130 } |
|
131 |
|
132 public void unobserve(Observer o) { |
|
133 observers.remove(o); |
|
134 } |
|
135 |
|
136 public static interface Observer { |
|
137 void textChanged(Spanned text); |
|
138 } |
|
139 } |