package com.beem.project.beem.ui;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;

import com.beem.project.beem.R;
import com.beem.project.beem.service.aidl.IXmppConnection;
import com.beem.project.beem.service.aidl.IXmppFacade;

/**
 * This class is an activity which display an animation during the connection with the server.
 * @author Da Risk <darisk972@gmail.com>
 */
public class LoginAnim extends Activity {

    private static final String TAG = "LoginAnim";
    private static final Intent SERVICE_INTENT = new Intent();
    static {
	SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
    }
    private ImageView mLogo;
    private Animation mRotateAnim;
    private final ServiceConnection mServConn = new LoginServiceConnection();
    private IXmppFacade mXmppFacade;
    private AsyncTask<IXmppFacade, Void, Boolean> mTask;
    private Button mCancelBt;
    private ProgressBar mProgressBar;

    /**
     * Constructor.
     */
    public LoginAnim() {
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
	// TODO use onBackPressed on Eclair (2.0)
	if (keyCode == KeyEvent.KEYCODE_BACK && mTask.getStatus() != AsyncTask.Status.FINISHED) {
	    if (!mTask.cancel(true)) {
		Log.d(TAG, "Can't interrupt the connection");
	    }
	    setResult(Activity.RESULT_CANCELED);
	}
	return super.onKeyDown(keyCode, event);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.login_anim);
	mLogo = (ImageView) findViewById(R.id.loginanim_logo_anim);
	mRotateAnim = AnimationUtils.loadAnimation(this, R.anim.rotate_and_scale);
	mCancelBt = (Button) findViewById(R.id.loginanim_cancel_button);
	mCancelBt.setOnClickListener(new ClickListener());
	mProgressBar = (ProgressBar) findViewById(R.id.loginanim_progressbar);
	mProgressBar.setIndeterminate(true);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onStart() {
	super.onStart();
	mLogo.startAnimation(mRotateAnim);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onResume() {
	super.onResume();
	if (mTask == null) {
	    mTask = new LoginTask();
	}
	if (mXmppFacade == null) {
	    bindService(LoginAnim.SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
	}
    }

    @Override
    protected void onPause() {
	super.onPause();
	if (mXmppFacade != null) { // and async task not en cours
	    unbindService(mServConn);
	    mXmppFacade = null;
	}
    }

    private class ClickListener implements OnClickListener {

	@Override
	public void onClick(View v) {
	    if (v == mCancelBt) {
		if (!mTask.cancel(true)) {
		    Log.d(TAG, "Can't interrupt the connection");
		}
		setResult(Activity.RESULT_CANCELED);
		finish();
	    }
	}
    }

    class LoginTask extends AsyncTask<IXmppFacade, Void, Boolean> {

	private IXmppConnection mConnection;
	private String mMsg;

	@Override
	protected Boolean doInBackground(IXmppFacade... params) {
	    Log.d(TAG, "Launch the task");
	    boolean result = true;
	    IXmppFacade facade = params[0];
	    try {
		mConnection = facade.createConnection();
		if (!mConnection.isAuthentificated()) {
		    result = mConnection.connectSync();
		    if (!result)
			mMsg = mConnection.getErrorMessage();
		}
	    } catch (RemoteException e) {
		Log.d(TAG, "Error while connecting", e);
		mMsg = "Exception during connection";
		result = false;
	    }
	    Log.d(TAG, "Connection result? " + result);
	    return result;
	}

	@Override
	protected void onPostExecute(Boolean result) {

	    if (result == null || !result) { // Task cancelled on exception
		Log.d(TAG, "Exception or cancelation of the connection");
		if (result == false) {
		    Intent i = new Intent();
		    i.putExtra("message", mMsg);
		    LoginAnim.this.setResult(Activity.RESULT_CANCELED, i);
		} else
		    LoginAnim.this.setResult(Activity.RESULT_CANCELED);
		LoginAnim.this.finish();
	    } else {
		LoginAnim.this.startService(LoginAnim.SERVICE_INTENT);
		LoginAnim.this.setResult(Activity.RESULT_OK);
		LoginAnim.this.finish();
	    }
	}

	@Override
	protected void onCancelled() {
	    try {
		if (mConnection != null && mConnection.isAuthentificated()) {
		    mConnection.disconnect();
		}
	    } catch (RemoteException e) {
		Log.d(TAG, "Remote exception", e);
	    }
	    LoginAnim.this.stopService(LoginAnim.SERVICE_INTENT);
	}

    }

    private class LoginServiceConnection implements ServiceConnection {

	public LoginServiceConnection() {
	}

	@Override
	public void onServiceConnected(ComponentName name, IBinder service) {
	    mXmppFacade = IXmppFacade.Stub.asInterface(service);
	    if (mTask.getStatus() == AsyncTask.Status.PENDING)
		mTask = mTask.execute(mXmppFacade);
	}

	@Override
	public void onServiceDisconnected(ComponentName name) {
	    Log.d(TAG, "Service disconnected.");
	    mXmppFacade = null;
	}
    }
}
