package com.beem.project.beem.ui;

import android.app.Activity;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
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.BeemApplication;
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.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.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 class OnChatListener extends IChatManagerListener.Stub {

	@Override
	public void chatCreated(IChat chat, boolean locally) throws RemoteException {
	    Log.i("LOG", "chatCreated");
	}

    }

    private class OnMessageListener extends IMessageListener.Stub {

	@Override
	public void processMessage(IChat chat, Message msg) throws RemoteException {

	    if (chat != mChat)
		return;
	    final Message m = msg;
	    mHandler.post(new Runnable() {

		@Override
		public void run() {
		    if (m.getBody() != null) {
			if (!mSpeak)
			    mText.append(m.getBody() + "\n");
			else
			    mText.append(mContact.getJID() + " " + getString(R.string.SendIMSays) + m.getBody() + "\n");
			mSpeak = false;
			mScrolling.fullScroll(View.FOCUS_DOWN);
			mToSend.requestFocus();
		    }
		}
	    });
	}

	@Override
	public void stateChanged(IChat chat) throws RemoteException {
	    // TODO: a integrer dans l'ui
	    // Log.d(TAG, "state changed");
	}
    }

    private static final String  TAG      = "SEND_IM";
    private EditText             mToSend;
    private SendIMDialogSmiley   mSmyDialog;
    private SharedPreferences    mSet;
    private BeemApplication      mBeemApplication;
    private Handler              mHandler;
    private IXmppFacade          mService = null;
    private Contact              mContact;
    private IChatManager         mChatManager;
    private IChatManagerListener mChatManagerListener;
    private IMessageListener     mMessageListener;
    private IChat                mChat;
    private TextView             mText;
    private TextView             mLogin;

    private ScrollView           mScrolling;

    private boolean              mSpeak;

    /**
     * Constructor.
     */
    public SendIM() {
	super();
    }

    /**
     * Abstract method inherited from OnClickListener
     */
    public void onClick(View view) {
	sendText();
    }

    /**
     * Overload of onCreate() Activity inherited function
     */
    @Override
    public void onCreate(Bundle saveBundle) {
	super.onCreate(saveBundle);
	mHandler = new Handler();
	mChatManagerListener = new OnChatListener();
	mMessageListener = new OnMessageListener();
	mBeemApplication = BeemApplication.getApplication(this);
	setContentView(R.layout.sendim);
	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);
	mContact = getIntent().getParcelableExtra("contact");
	setViewHeader();
	mText = (TextView) findViewById(R.id.sendimlist);
	mScrolling = (ScrollView) findViewById(R.id.sendimscroll);
    }

    /**
     * Callback for menu creation.
     * 
     * @param The
     *            created menu
     * @return true on success, false otherwise
     */
    @Override
    public final boolean onCreateOptionsMenu(Menu menu) {
	super.onCreateOptionsMenu(menu);
	MenuInflater inflater = getMenuInflater();
	inflater.inflate(R.menu.sendimmenu, menu);
	return true;
    }

    @Override
    protected void onDestroy() {

	if (mChatManager != null) {
	    try {
		mChatManager.removeChatCreationListener(mChatManagerListener);
		mChatManager.destroyChat(mChat);
	    } catch (RemoteException e) {
		Log.e(TAG, "mchat manager and SendIM destroy", e);
	    }
	}
	super.onDestroy();
    }

    /**
     * Abstract method inherited from OnKeyListener
     */
    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;
	    }
	}
	return false;
    }

    @Override
    public final boolean onOptionsItemSelected(MenuItem item) {
	switch (item.getItemId()) {
	case R.id.sendim_smiley:
	    mSmyDialog.show();
	    return true;
	default:
	    return false;
	}
    }

    @Override
    protected void onPause() {
	Log.d(TAG, "onPause");
	try {
	    mChat.setOpen(false);
	} catch (RemoteException e) {
	    Log.d(TAG, "mchat open false", e);
	}
	super.onPause();
	finish();
    }

    @Override
    protected void onResume() {
	super.onResume();
	mBeemApplication = BeemApplication.getApplication(this);
	if (!mBeemApplication.isConnected())
	    mBeemApplication.startBeemService();
	mBeemApplication.callWhenConnectedToServer(mHandler, new Runnable() {

	    @Override
	    public void run() {
		mService = mBeemApplication.getXmppFacade();
		try {
		    mChatManager = mService.getChatManager();
		    mChatManager.addChatCreationListener(mChatManagerListener);
		    mChat = mChatManager.createChat(mContact, mMessageListener);
		    String text = mChat.getLastMessages();
		    if (!"".equals(text)) {
			mText.append(mContact.getJID() + " " + getString(R.string.SendIMSays));
			mText.append(text);
			// mChat.clearLastMessages();
		    }
		    mChat.setOpen(true);
		} catch (RemoteException e) {
		    Log.e(TAG, "Error during chat manager creation", e);
		}
	    }
	});

    }

    @Override
    public void onStart() {
	super.onStart();
	// TODO cancel the notification if any
	if (mContact == null)
	    mContact = getIntent().getParcelableExtra("contact");
	mService = mBeemApplication.getXmppFacade();
	setViewHeader();

    }

    @Override
    protected void onStop() {

	Log.d(TAG, "onStop");
	try {
	    mChat.setOpen(false);
	} catch (RemoteException e) {
	    Log.d(TAG, "mchat open false", e);
	}
	mBeemApplication.unbindBeemService();
	super.onStop();
    }

    /**
     * This method send a message to the server over the XMPP connection and display it on activity
     * view TODO : Exception si la connexion se coupe pendant la conversation
     */
    private void sendText() {
	if (mSpeak)
	    mSpeak = false;
	String text = mToSend.getText().toString();
	if (!text.equals("")) {
	    Message msg = new Message(mContact.getJID(), Message.MSG_TYPE_CHAT);
	    msg.setBody(text);
	    try {
		mChat.sendMessage(msg);
	    } catch (RemoteException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	    }
	    if (!mSpeak)
		mText.append(getString(R.string.SendIMYouSay) + text + "\n");
	    else
		mText.append(text + "\n");
	    mToSend.setText(null);
	    mScrolling.fullScroll(View.FOCUS_DOWN);
	    mToSend.requestFocus();
	    mSpeak = true;
	}
    }

    private void setViewHeader() {
	Drawable avatar = getResources().getDrawable(R.drawable.avatar);
	ImageView imgV = (ImageView) findViewById(R.id.sendimavatar);
	imgV.setImageDrawable(avatar);
	mLogin = (TextView) findViewById(R.id.sendimlogin);
	mLogin.setText(mContact.getJID());
	TextView status = (TextView) findViewById(R.id.sendimstatus);
	status.setTextSize(12);
	mLogin.setTextColor(getResources().getColor(R.color.white));
	String statmsg = mContact.getMsgState();
	if (statmsg != null)
	    status.setText(statmsg);
	;
    }
}
