package xmpp.client.ui.adapter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import xmpp.client.R;
import xmpp.client.service.chat.ChatMessage;
import xmpp.client.service.chat.MessageType;
import xmpp.client.service.user.User;
import xmpp.client.service.user.contact.Contact;
import xmpp.client.ui.extras.SmileyHandler;
import xmpp.client.ui.provider.ChatProvider;
import xmpp.client.ui.provider.ContactProvider;
import android.content.Context;
import android.graphics.Color;
import android.net.Uri;
import android.text.Layout.Alignment;
import android.text.SpannableStringBuilder;
import android.text.format.DateFormat;
import android.text.style.AlignmentSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.QuickContactBadge;
import android.widget.TextView;
public class ChatAdapter extends BaseAdapter {
private static boolean sameDay(Date date1, Date date2) {
// TODO Do it without deprecated functions and also compare month and
// year
return date1.getDate() == date2.getDate();
}
private final HashMap<Integer, View> viewCache;
private View lastView;
private int cachedSize;
private final Context mContext;
private final ChatProvider mChatProvider;
private final ContactProvider mContactProvider;
public ChatAdapter(Context context, ChatProvider chatProvider,
ContactProvider contactProvider) {
mContext = context;
mChatProvider = chatProvider;
mContactProvider = contactProvider;
viewCache = new HashMap<Integer, View>();
cachedSize = -1;
}
private void drawMessages(ViewGroup parent,
final ArrayList<ChatMessage> msgs, final boolean itsMe,
final LayoutInflater layoutInflater, final LinearLayout container) {
for (final ChatMessage chatMessage : msgs) {
final CharSequence seq = SmileyHandler.getSmiledText(
chatMessage.getText(), mContext);
View temp = null;
if (itsMe) {
((SpannableStringBuilder) seq).setSpan(new AlignmentSpan() {
@Override
public Alignment getAlignment() {
return Alignment.ALIGN_OPPOSITE;
}
}, 0, seq.length(), 0);
temp = layoutInflater.inflate(
R.layout.chat_entry_outgoing_message, parent, false);
} else {
temp = layoutInflater.inflate(
R.layout.chat_entry_incoming_message, parent, false);
}
final TextView time = (TextView) temp.findViewById(R.id.msg_time);
time.setText(DateFormat.getTimeFormat(mContext).format(
chatMessage.getDate()));
final TextView text = (TextView) temp.findViewById(R.id.msg_text);
text.setText(seq);
container.addView(temp);
}
}
@Override
public int getCount() {
return getGroupedMessages().size() + 1;
}
private ArrayList<ArrayList<xmpp.client.service.chat.ChatMessage>> getGroupedMessages() {
final ArrayList<ArrayList<xmpp.client.service.chat.ChatMessage>> list = new ArrayList<ArrayList<xmpp.client.service.chat.ChatMessage>>();
String lastUser = null;
Date lastDate = null;
for (int i = 0; i < mChatProvider.size(); i++) {
final xmpp.client.service.chat.ChatMessage msg = mChatProvider
.getMessage(i);
switch (msg.getType()) {
case MultiUserChat:
case SingleUserChat:
if (lastUser == null || !lastUser.equals(msg.getFrom())
|| !sameDay(lastDate, msg.getDate())) {
lastUser = msg.getFrom();
lastDate = msg.getDate();
list.add(new ArrayList<xmpp.client.service.chat.ChatMessage>());
}
list.get(list.size() - 1).add(msg);
break;
case Info:
list.add(new ArrayList<xmpp.client.service.chat.ChatMessage>());
list.get(list.size() - 1).add(msg);
break;
default:
break;
}
}
return list;
}
@Override
public Object getItem(int position) {
if (position == mChatProvider.size()) {
return 0;
}
return getGroupedMessages().get(position);
}
@Override
public long getItemId(int position) {
return getItem(position).hashCode();
}
@Override
public View getView(int position, View view, ViewGroup parent) {
final ArrayList<ArrayList<ChatMessage>> msgss = getGroupedMessages();
final boolean itsLastChat = position == msgss.size() - 1;
final boolean itsLast = (position == msgss.size());
final ArrayList<ChatMessage> msgs = itsLast ? null : msgss
.get(position);
final boolean itsMe = itsLast ? false : mContactProvider
.getMeUserLogin().equals(msgs.get(0).getFrom());
final boolean itsStatus = itsLast
|| (msgs.get(0).getType() == MessageType.Info || msgs.get(0)
.getType() == MessageType.UserState);
if (viewCache.containsKey(position)
&& !(itsLastChat && cachedSize != mChatProvider.size())) {
view = viewCache.get(position);
} else if (!itsLast) {
final LayoutInflater layoutInflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (itsMe) {
view = layoutInflater.inflate(
R.layout.chat_entry_outgoing_base, parent, false);
} else if (itsStatus) {
view = layoutInflater.inflate(R.layout.chat_entry_status,
parent, false);
} else {
view = layoutInflater.inflate(
R.layout.chat_entry_incoming_base, parent, false);
}
if (!itsStatus) {
final TextView day = (TextView) view.findViewById(R.id.msg_day);
day.setText(DateFormat.format(mContext
.getText(R.string.datelayout_daymonth), msgs.get(0)
.getDate()));
final LinearLayout container = (LinearLayout) view
.findViewById(R.id.lst_msgs);
drawMessages(parent, msgs, itsMe, layoutInflater, container);
}
}
if (!itsStatus) {
final TextView user = (TextView) view.findViewById(R.id.msg_user);
final QuickContactBadge q = (QuickContactBadge) view
.findViewById(R.id.contact_badge);
String userContact = null;
final Contact contact = null; // Only because it does not work!
if (contact != null) {
userContact = contact.getUserContact();
}
if (userContact != null) {
q.assignContactUri(Uri.parse(userContact));
}
if (contact != null) {
user.setText(contact.getUserName());
q.setImageBitmap(contact.getBitmap(mContext,
(mChatProvider.isMUC() && !itsMe)));
} else {
user.setText(msgs.get(0).getFrom());
/*
* q.setImageBitmap(msgs.get(0).getUser() .getBitmap(mContext,
* (mChatProvider.isMUC() && !itsMe)));
*/
}
} else if (!itsLast) {
final TextView status = (TextView) view
.findViewById(R.id.status_text);
status.setVisibility(View.VISIBLE);
status.setText(msgs.get(0).getText());
}
if (itsLast) {
if (lastView == null) {
final LayoutInflater layoutInflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
lastView = layoutInflater.inflate(R.layout.chat_entry_status,
parent, false);
}
Log.d("ChatAdapter", "Render lastView");
if (!mChatProvider.isMUC() && mChatProvider.getUsers().size() > 0) {
Log.d("ChatAdapter", "Render lastView[isSingle!]");
final User u = mChatProvider.getUsers().get(0);
if (!mContactProvider
.getContact(mChatProvider.getUsers().get(0))
.getUserState().isOnline()) {
Log.d("ChatAdapter", "Render lastView[isOffline!]");
final TextView v = (TextView) lastView
.findViewById(R.id.status_text);
v.setText(mContext.getText(R.string.chat_offline)
.toString().replace("$(name)", u.getDisplayName()));
v.setTextColor(Color.parseColor(mContext
.getString(android.R.color.holo_red_dark)));
v.setVisibility(View.VISIBLE);
} else {
Log.d("ChatAdapter", "Render lastView[isOnline!]");
final TextView v = (TextView) lastView
.findViewById(R.id.status_text);
v.setVisibility(View.GONE);
}
}
view = lastView;
} else {
viewCache.put(position, view);
if (itsLastChat) {
cachedSize = mChatProvider.size();
}
}
return view;
}
}