package com.beem.project.beem.ui;

import android.app.Activity;
import android.content.ServiceConnection;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.os.AsyncTask;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View.OnClickListener;
import android.view.View;
import android.widget.Button;
import android.view.animation.Animation;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ProgressBar;
import android.view.animation.AnimationUtils;
import com.beem.project.beem.R;
import android.util.Log;
import com.beem.project.beem.service.aidl.IXmppFacade;
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 TextView mErrorLabel;
    private final ServiceConnection mServConn = new LoginServiceConnection();
    private IXmppFacade mXmppFacade;
    private AsyncTask<IXmppFacade, Void, Boolean>mTask;
    private Button mCancelBt;
    private ProgressBar mProgressBar;

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

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.login_anim);
	mLogo = (ImageView) findViewById(R.id.loginanim_logo_anim);
	mErrorLabel = (TextView) findViewById(R.id.loginanim_error_label);
	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;
	}
    }

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

	private IXmppConnection mConnection;

	@Override
	protected Boolean doInBackground(IXmppFacade ... params) {
	    boolean result = true;
	    IXmppFacade facade = params[0];
	    try {
		mConnection = facade.createConnection();
		if (!mConnection.isAuthentificated()) {
		    result = mConnection.connectSync();
		    if (!result) {
			// set bad message ?
		    }
		}
	    } catch (RemoteException e) {
		Log.d(TAG, "Error while connecting", e);
		// set bad message ?
		result = false;
	    }
	    Log.d(TAG, "Connection result? " + result);
	    return result;
	}

	@Override
	protected void onPostExecute(Boolean result) {
	    if (result == null || !result) { // Task cancelled on exception
		String msg;
		Log.d(TAG, "Exception or cancelation of the connection");
		try {
		    if (!result)
			msg = mConnection.getErrorMessage();
		    else
			msg = "Exception during connection";
		} catch (RemoteException e) {
		    Log.d(TAG, "Exception or cancelation of the connection");
		    msg = "Remote Exception";
		}
		//TODO create an intent and store the error msg in. Return this intent on result.
		LoginAnim.this.mErrorLabel.setText("Error !!!\n" + msg);
		LoginAnim.this.setResult(Activity.RESULT_CANCELED);
		LoginAnim.this.finish();
	    } else {
		LoginAnim.this.startService(LoginAnim.SERVICE_INTENT);
		//LoginAnim.this.startActivity(new Intent(LoginAnim.this, ContactList.class));
		LoginAnim.this.setResult(Activity.RESULT_OK);
		LoginAnim.this.finish();
	    }
	}

	@Override
	protected void onCancelled() {
	    mCancelBt.setText("Cancelled. Retry");
	    try {
		if (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);
	    Log.d(TAG, "Launch the task");
	    if (mTask.getStatus() == AsyncTask.Status.PENDING)
		mTask = mTask.execute(mXmppFacade);
	}
	
	@Override
	public void onServiceDisconnected(ComponentName name) {
	    Log.d(TAG, "Service disconnected.");
	    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();
	    }
	}
    }
}
