/*
    BEEM is a videoconference application on the Android Platform.

    Copyright (C) 2009 by Frederic-Charles Barthelery,
                          Jean-Manuel Da Silva,
                          Nikita Kozlov,
                          Philippe Lago,
                          Jean Baptiste Vergely,
                          Vincent Veronis.

    This file is part of BEEM.

    BEEM is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    BEEM is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.

    Please send bug reports with examples or suggestions to
    contact@beem-project.com or http://dev.beem-project.com/

    Epitech, hereby disclaims all copyright interest in the program "Beem"
    written by Frederic-Charles Barthelery,
               Jean-Manuel Da Silva,
               Nikita Kozlov,
               Philippe Lago,
               Jean Baptiste Vergely,
               Vincent Veronis.

    Nicolas Sadirac, November 26, 2009
    President of Epitech.

    Flavien Astraud, November 26, 2009
    Head of the EIP Laboratory.

*/
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 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;

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

    /* (non-Javadoc)
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @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());
    }

    /* (non-Javadoc)
     * @see android.app.Activity#onStart()
     */
    @Override
    protected void onStart() {
	super.onStart();
	mLogo.startAnimation(mRotateAnim);
    }

    /* (non-Javadoc)
     * @see android.app.Activity#onResume()
     */
    @Override
    protected void onResume() {
	super.onResume();
	if (mTask == null)
	    mTask = new LoginTask();
	if (mXmppFacade == null)
	    bindService(LoginAnim.SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
    }

    /* (non-Javadoc)
     * @see android.app.Activity#onPause()
     */
    @Override
    protected void onPause() {
	super.onPause();
	if (mXmppFacade != null) { // and async task not en cours
	    unbindService(mServConn);
	    mXmppFacade = null;
	}
    }

    /* (non-Javadoc)
     * @see android.app.Activity#onKeyDown(int, android.view.KeyEvent)
     */
    @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);
    }

    /**
     * Click event listener on cancel button.
     */
    private class ClickListener implements OnClickListener {

	/**
	 * Constructor.
	 */
	ClickListener() {
	}

	@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();
	    }
	}
    }

    /**
     * Asynchronous class for connection.
     */
    class LoginTask extends AsyncTask<IXmppFacade, Void, Boolean> {

	private IXmppConnection mConnection;
	private String mMsg;

	/**
     * Constructor.
     */
	LoginTask() {
	}

	/* (non-Javadoc)
	 * @see android.os.AsyncTask#doInBackground(Params[])
	 */
	@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)
			mMsg = mConnection.getErrorMessage();
		}
	    } catch (RemoteException e) {
		mMsg = "Exception during connection";
		result = false;
	    }
	    return result;
	}

	/* (non-Javadoc)
	 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
	 */
	@Override
	protected void onPostExecute(Boolean result) {

	    if (result == null || !result) { // Task cancelled or exception
		if (!result) {
		    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 {
		mCancelBt.setEnabled(false);
		LoginAnim.this.startService(LoginAnim.SERVICE_INTENT);
		LoginAnim.this.setResult(Activity.RESULT_OK);
		LoginAnim.this.finish();
	    }
	}

	/* (non-Javadoc)
	 * @see android.os.AsyncTask#onCancelled()
	 */
	@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);
	}

    }

    /**
     * The service connection used to connect to the Beem service.
     */
    private class LoginServiceConnection implements ServiceConnection {

	/**
	 * Constructor.
	 */
	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) {
	    mXmppFacade = null;
	}
    }
}
