package com.beem.project.beem.ui;
import java.util.List;
import org.jivesoftware.smack.util.StringUtils;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.text.util.Linkify;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;
import com.beem.project.beem.BeemService;
import com.beem.project.beem.R;
import com.beem.project.beem.service.Contact;
import com.beem.project.beem.service.Message;
import com.beem.project.beem.service.PresenceAdapter;
import com.beem.project.beem.service.aidl.IBeemRosterListener;
import com.beem.project.beem.service.aidl.IChat;
import com.beem.project.beem.service.aidl.IChatManager;
import com.beem.project.beem.service.aidl.IChatManagerListener;
import com.beem.project.beem.service.aidl.IMessageListener;
import com.beem.project.beem.service.aidl.IRoster;
import com.beem.project.beem.service.aidl.IXmppFacade;
/**
* This activity class provides the view for instant messaging after selecting a correspondant.
* @author barbu
*/
public class SendIM extends Activity implements OnClickListener, OnKeyListener {
private static final String TAG = "SEND_IM";
private EditText mToSend;
private SendIMDialogSmiley mSmyDialog;
private SharedPreferences mSet;
private Handler mHandler;
private Contact mContact;
private String mContactName;
private IChatManager mChatManager;
private IChatManagerListener mChatManagerListener;
private IMessageListener mMessageListener;
private IChat mChat;
private TextView mText;
private TextView mLogin;
private TextView mChatState;
private ScrollView mScrolling;
private char mSpeak;
private final ServiceConnection mServConn = new BeemServiceConnection();
private IXmppFacade xmppFacade;
public IRoster mRoster;
private TextView mStatusText;
/**
* Constructor.
*/
public SendIM() {
super();
}
/**
* {@inheritDoc}
*/
@Override
public void onClick(View view) {
sendText();
}
/**
* {@inheritDoc}
*/
@Override
protected void onCreate(Bundle saveBundle) {
super.onCreate(saveBundle);
setTheme(R.style.OldTheme);
setContentView(R.layout.sendim);
mHandler = new Handler();
mChatManagerListener = new OnChatListener();
mMessageListener = new OnMessageListener();
mToSend = (EditText) findViewById(R.id.userText);
mSet = getSharedPreferences("lol", MODE_PRIVATE);
mSmyDialog = new SendIMDialogSmiley(this, mSet);
mToSend.setOnClickListener(this);
mToSend.setOnKeyListener(this);
mLogin = (TextView) findViewById(R.id.sendimlogin);
mChatState = (TextView) findViewById(R.id.sendimchatstate);
try {
mContact = new Contact(getIntent().getData());
if (mRoster != null)
mContact = mRoster.getContact(mContact.getJID());
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mText = (TextView) findViewById(R.id.sendimlist);
mScrolling = (ScrollView) findViewById(R.id.sendimscroll);
mStatusText = (TextView) findViewById(R.id.sendimstatus);
setViewHeader();
}
/**
* Set the header information in the window.
*/
private void setViewHeader() {
Drawable avatar = getResources().getDrawable(R.drawable.avatar);
ImageView imgV = (ImageView) findViewById(R.id.sendimavatar);
imgV.setImageDrawable(avatar);
mStatusText.setTextSize(12);
mContactName = mContact.getName();
if (mContactName == null || "".equals(mContactName)) {
mContactName = mContact.getJID();
mContactName = StringUtils.parseName(mContactName);
if ("".equals(mContactName))
mContactName = mContact.getJID();
}
mLogin.setText(mContactName);
}
/**
* {@inheritDoc}
*/
@Override
public final boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.sendimmenu, menu);
return true;
}
/**
* {@inheritDoc}
*/
@Override
protected void onDestroy() {
super.onDestroy();
if (mChatManager != null) {
try {
mChatManager.removeChatCreationListener(mChatManagerListener);
// TODO trouver quand detruire le chat
// mChatManager.destroyChat(mChat);
} catch (RemoteException e) {
Log.e(TAG, "mchat manager and SendIM destroy", e);
}
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
sendText();
return true;
default:
return false;
}
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
mContact = new Contact(intent.getData());
try {
if (mRoster != null)
mContact = mRoster.getContact(mContact.getJID());
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setViewHeader();
}
/**
* {@inheritDoc}
*/
@Override
public final boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.sendim_smiley:
mSmyDialog.show();
return true;
default:
return false;
}
}
/**
* {@inheritDoc}
*/
@Override
protected void onPause() {
super.onPause();
try {
if (mChat != null)
mChat.setOpen(false);
} catch (RemoteException e) {
Log.d(TAG, "Error while closing chat", e);
}
unbindService(mServConn);
}
/**
* {@inheritDoc}
*/
@Override
protected void onResume() {
super.onResume();
bindService(new Intent(this, BeemService.class), mServConn, BIND_AUTO_CREATE);
mScrolling.fullScroll(ScrollView.FOCUS_DOWN);
}
/**
* {@inheritDoc}
*/
@Override
protected void onStart() {
super.onStart();
// TODO cancel the notification if any
try {
if (mRoster != null)
mContact = mRoster.getContact(mContact.getJID());
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setViewHeader();
}
private class BeemServiceConnection implements ServiceConnection {
BeemRosterListener mBeemRosterListener = new BeemRosterListener();
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
xmppFacade = IXmppFacade.Stub.asInterface(service);
try {
if (mChatManager == null) {
mChatManager = xmppFacade.getChatManager();
mChatManager.addChatCreationListener(mChatManagerListener);
}
mRoster = xmppFacade.getRoster();
if (mRoster != null) {
mRoster.addRosterListener(mBeemRosterListener);
// mContact.setStatus(mRoster.getPresence(mContact.getJID()));
if (mRoster.getContact(mContact.getJID()) != null) {
mContact = mRoster.getContact(mContact.getJID());
mStatusText.setText(mContact.getMsgState());
}
}
switchChat(mContact);
} catch (RemoteException e) {
Log.e(TAG, "Error during chat manager creation", e);
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
xmppFacade = null;
try {
mRoster.removeRosterListener(mBeemRosterListener);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
/**
* Send a message to the contact over the XMPP connection. Also display it on activity view. TODO : Gerer
* l'exception si la connexion se coupe pendant la conversation
*/
private void sendText() {
String text = mToSend.getText().toString();
if (!text.equals("")) {
Message msg = new Message(mContact.getJID(), Message.MSG_TYPE_CHAT);
msg.setBody(text);
try {
// TODO: PAs connecter au serveur BING grosse Error !
// INTERDICTION !
mChat.sendMessage(msg);
if (mSpeak != 1)
mText.append(getString(R.string.SendIMYouSay, text));
else
mText.append(getString(R.string.SendIMSameSpeaker, text));
mToSend.setText(null);
mScrolling.fullScroll(ScrollView.FOCUS_DOWN);
mToSend.requestFocus();
mSpeak = 1;
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* Show the message history.
* @param messages list of message to display
*/
private void showMessageList(List<Message> messages) {
mText.setText("");
mSpeak = 0;
for (Message message : messages) {
String from = message.getFrom();
if (from == null) {
if (mSpeak != 1)
mText.append(getString(R.string.SendIMYouSay, message.getBody()));
else
mText.append(getString(R.string.SendIMYouSay, message.getBody()));
mSpeak = 1;
} else {
if (mSpeak != 2)
mText.append(getString(R.string.SendIMSays, mContactName, message.getBody()));
else
mText.append(getString(R.string.SendIMSameSpeaker, message.getBody()));
mSpeak = 2;
}
}
mScrolling.fullScroll(ScrollView.FOCUS_DOWN);
}
/**
* Change the correspondant of the chat.
* @param newContact New contact to chat with
* @throws RemoteException if an errors occurs in the connection with the service
*/
private void switchChat(Contact newContact) throws RemoteException {
if (mChat != null)
mChat.setOpen(false);
mChat = mChatManager.createChat(newContact, mMessageListener);
showMessageList(mChat.getMessages());
mChat.setOpen(true);
mContact = newContact;
mToSend.requestFocus();
}
/**
* Listener for chat creation. (maybe not necessary)
* @author darisk
*/
private class OnChatListener extends IChatManagerListener.Stub {
/**
* {@inheritDoc}
*/
@Override
public void chatCreated(IChat chat, boolean locally) throws RemoteException {
Log.i("LOG", "chatCreated");
}
}
private class BeemRosterListener extends IBeemRosterListener.Stub {
@Override
public void onEntriesAdded(List<String> addresses) throws RemoteException {
// TODO Auto-generated method stub
}
@Override
public void onEntriesDeleted(List<String> addresses) throws RemoteException {
// TODO Auto-generated method stub
}
@Override
public void onEntriesUpdated(List<String> addresses) throws RemoteException {
// TODO Auto-generated method stub
}
@Override
public void onPresenceChanged(PresenceAdapter presence) throws RemoteException {
if (mContact.getJID().equals(StringUtils.parseBareAddress(presence.getFrom()))) {
mContact.setStatus(mRoster.getPresence(StringUtils.parseBareAddress(presence.getFrom())));
mHandler.post(new RunnableChange());
}
}
private class RunnableChange implements Runnable {
@Override
public void run() {
mStatusText.setText(mContact.getMsgState());
Linkify.addLinks(mStatusText, Linkify.WEB_URLS);
}
}
@Override
public void onEntryDeleteFromGroup(String group, String jid) throws RemoteException {
// TODO Auto-generated method stub
}
}
/**
* Listener for new chat messages.
* @author darisk
*/
private class OnMessageListener extends IMessageListener.Stub {
/**
* {@inheritDoc}
*/
@Override
public void processMessage(IChat chat, Message msg) throws RemoteException {
if (chat != mChat)
return;
final Message m = msg;
Log.d("Message Type", "Le type du message : " + m.getType());
mHandler.post(new Runnable() {
@Override
public void run() {
if (m.getBody() != null) {
if (m.getType() == Message.MSG_TYPE_ERROR) {
mText.append(getString(R.string.SendIMErrorMsg, m.getBody()));
mSpeak = 0;
} else if (mSpeak == 2)
mText.append(getString(R.string.SendIMSameSpeaker, m.getBody()));
else
mText.append(getString(R.string.SendIMSays, mContactName, m.getBody()));
mScrolling.fullScroll(ScrollView.FOCUS_DOWN);
mToSend.requestFocus();
mSpeak = 2;
}
}
});
}
/**
* {@inheritDoc}
*/
@Override
public void stateChanged(IChat chat) throws RemoteException {
if (chat != mChat)
return;
final String state = chat.getState();
Log.d("ChatState", "Action du correspondant : <--- " + chat.getState() + " --->");
mHandler.post(new Runnable() {
@Override
public void run() {
mChatState.setText(state);
}
});
}
}
}