package com.magnet.wru;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.magnet.mmx.client.api.MMXChannel;
import com.magnet.mmx.client.api.MMXMessage;
import com.magnet.mmx.util.Base64;
import com.magnet.mmx.util.DisposableFile;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MessageListFragment extends Fragment {
private static final String TAG = MessageListFragment.class.getSimpleName();
static final String KEY_MESSAGE_TEXT = "textContent";
static final String KEY_MESSAGE_SENDER = "messageSender";
static final String KEY_ATTACHMENT = "attachment";
static final String KEY_ATTACHMENT_MIME_TYPE = "attachmentMimeType";
private DisposableFile mPickedFile = null;
private ImageButton mGalleryButton = null;
private ImageButton mSendButton = null;
private EditText mSendText = null;
private ListView mMessageListView = null;
private MessageListAdapter mMessageListAdapter = null;
private MyMessageStore.OnChangeListener mMessageListListener = new MyMessageStore.OnChangeListener() {
public void onChange() {
getActivity().runOnUiThread(new Runnable() {
public void run() {
mMessageListAdapter.notifyDataSetChanged();
mMessageListView.smoothScrollToPosition(mMessageListAdapter.getCount());
}
});
}
};
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_message_list, container);
mSendText = (EditText) view.findViewById(R.id.message_text);
mSendButton = (ImageButton) view.findViewById(R.id.btn_send);
mGalleryButton = (ImageButton) view.findViewById(R.id.btn_attach);
mMessageListView = (ListView) view.findViewById(R.id.message_list_view);
mMessageListAdapter = new MessageListAdapter(getActivity(), MyMessageStore.getMessageList());
mMessageListView.setAdapter(mMessageListAdapter);
mSendText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (event != null
&& event.getKeyCode() == KeyEvent.KEYCODE_ENTER
|| actionId == EditorInfo.IME_ACTION_DONE) {
doSendMessage();
}
return false;
}
});
MyMessageStore.registerListener(mMessageListListener);
return view;
}
@Override
public void onDestroyView() {
MyMessageStore.unregisterListener(mMessageListListener);
super.onDestroyView();
}
public void doAttach() {
MediaUtil.startImagePickerActivityWithResult(this);
}
public void doSendMessage() {
final String messageText = mSendText.getText().toString();
if (messageText.isEmpty()) {
//don't send an empty message
return;
}
WRU wru = WRU.getInstance(getActivity());
final HashMap<String, String> content = new HashMap<>();
content.put(KEY_MESSAGE_TEXT, messageText);
content.put(KEY_MESSAGE_SENDER, wru.getUsername());
MMXChannel chatChannel = WRU.getInstance(getActivity()).getJoinedTopicChat();
if (mPickedFile != null) {
try {
content.put(KEY_ATTACHMENT, Base64.encodeFromFile(mPickedFile.getAbsolutePath()));
content.put(KEY_ATTACHMENT_MIME_TYPE, "image/jpeg");
//TODO: Figure out the MIME type
} catch (IOException e) {
Log.e(TAG, "doSendMessage(): exception caught while attaching file" + e);
Toast.makeText(getActivity(), "Unable to attach file: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
String messageID = chatChannel.publish(content, new MMXMessage.OnFinishedListener<String>() {
public void onSuccess(String s) {
Toast.makeText(getActivity(), "Message sent.", Toast.LENGTH_LONG).show();
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mSendText.setText(null);
}
});
if (mPickedFile != null) {
mPickedFile.finish();
mPickedFile = null;
}
updateViewState();
}
public void onFailure(MMXMessage.FailureCode failureCode, Throwable throwable) {
Log.e(TAG, "doSendMessage() failure: " + failureCode, throwable);
Toast.makeText(getActivity(), "Exception: " + throwable.getMessage(), Toast.LENGTH_LONG).show();
}
});
MyMessageStore.addMessage(messageID, content, new Date(), false);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
mPickedFile = MediaUtil.getDisposableImageFromActivityResult(getActivity(), resultCode, data);
updateViewState();
} catch (IOException e) {
Log.e(TAG, "onActivityResult(): caught exception", e);
Toast.makeText(getActivity(), "Unable to attach file: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
public void doFragmentClick(View view) {
if (view == mGalleryButton) {
doAttach();
} else if (view == mSendButton) {
doSendMessage();
}
}
private class MessageListAdapter extends BaseAdapter {
private final int[] COLOR_IDS = {R.color.chat_1, R.color.chat_2, R.color.chat_3, R.color.chat_4, R.color.chat_5, R.color.chat_6};
private static final int TYPE_ME = 0;
private static final int TYPE_THEM = 1;
private List<MyMessageStore.Message> mMessageList = null;
private Context mContext;
private LayoutInflater mInflater;
private DateFormat mFormatter = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT);
private ExecutorService mExecutors = Executors.newFixedThreadPool(3);
public MessageListAdapter(Context context, List<MyMessageStore.Message> messageList) {
mContext = context;
mMessageList = messageList;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public View getView(int position, View convertView, ViewGroup parent) {
int type = getItemViewType(position);
int colorResId = 0;
String datePostedStr = null;
String messageStr = null;
final MyMessageStore.Message message = getItem(position);
final Map<String, String> messageContent = message.getContent();
switch (type) {
case TYPE_ME:
if (convertView == null) {
convertView = mInflater.inflate(R.layout.message_list_item_me, null);
}
colorResId = R.color.chat_me;
datePostedStr = mFormatter.format(message.getTimestamp());
messageStr = messageContent.get(KEY_MESSAGE_TEXT);
break;
case TYPE_THEM:
if (convertView == null) {
convertView = mInflater.inflate(R.layout.message_list_item_them, null);
}
//set author and color
String authorStr = messageContent.get(KEY_MESSAGE_SENDER);
colorResId = COLOR_IDS[Math.abs(authorStr.hashCode() % COLOR_IDS.length)];
TextView author = (TextView) convertView.findViewById(R.id.author);
author.setText(authorStr + " - ");
datePostedStr = mFormatter.format(message.getTimestamp());
Object textObj = messageContent.get(KEY_MESSAGE_TEXT);
messageStr = textObj != null ? textObj.toString() : "<no text>";
break;
}
boolean hasAttachment = messageContent.containsKey(KEY_ATTACHMENT);
TextView datePosted = (TextView) convertView.findViewById(R.id.datePosted);
datePosted.setText(datePostedStr);
TextView messageText = (TextView) convertView.findViewById(R.id.messageText);
LinearLayout messageBubble = (LinearLayout) convertView.findViewById(R.id.messageBubble);
final ImageView imageView = (ImageView) convertView.findViewById(R.id.image);
imageView.setVisibility(View.GONE);
messageBubble.setBackgroundResource(colorResId);
messageText.setText(messageStr);
convertView.setOnClickListener(null);
if (hasAttachment) {
if (MyMessageStore.isBitmapCached(message.getId())) {
Bitmap bitmap = MyMessageStore.getBitmap(message.getId(), null);
setupDrawableView(imageView, bitmap);
} else {
mExecutors.execute(new Runnable() {
public void run() {
String attachment = messageContent.get(KEY_ATTACHMENT);
//String mimeType = messageContent.get(KEY_ATTACHMENT_MIME_TYPE);
//TODO: Do something with the MIME type
Bitmap bitmap = MyMessageStore.getBitmap(message.getId(), attachment);
setupDrawableView(imageView, bitmap);
}
});
}
}
return convertView;
}
private void setupDrawableView(final ImageView imageView, final Bitmap bitmap) {
Activity activity = getActivity();
if (activity != null) {
activity.runOnUiThread(new Runnable() {
public void run() {
imageView.setImageBitmap(bitmap);
imageView.setVisibility(View.VISIBLE);
imageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
showImageDialog(mContext, bitmap);
}
});
}
});
}
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public int getItemViewType(int position) {
MyMessageStore.Message message = getItem(position);
if (!message.isIncoming()) {
//me
return TYPE_ME;
} else {
//them
return TYPE_THEM;
}
}
@Override
public int getCount() {
return mMessageList.size();
}
@Override
public MyMessageStore.Message getItem(int position) {
return mMessageList.get(position);
}
@Override
public long getItemId(int position) {
return 0l;
}
private void showImageDialog(Context context, Bitmap bitmap) {
LinearLayout imageLayout = (LinearLayout) mInflater.inflate(R.layout.dialog_image, null);
ImageView imageView = (ImageView) imageLayout.findViewById(R.id.image);
BitmapDrawable bitmapDrawable = new BitmapDrawable(getActivity().getResources(), bitmap);
imageView.setImageDrawable(bitmapDrawable);
AlertDialog dialog = new AlertDialog.Builder(context)
.setView(imageLayout)
.create();
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(dialog.getWindow().getAttributes());
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.MATCH_PARENT;
dialog.show();
dialog.getWindow().setAttributes(lp);
}
}
/**
* This can be called from anywhere to make sure that the view is updated.
*/
private void updateViewState() {
getActivity().runOnUiThread(new Runnable() {
public void run() {
if (mPickedFile != null) {
mGalleryButton.setBackgroundColor(getResources().getColor(android.R.color.holo_green_light));
} else {
mGalleryButton.setBackgroundColor(getResources().getColor(android.R.color.transparent));
}
}
});
}
}