package com.beem.project.beem.ui;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

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

/**
 * This class represents an activity which allows the user to connect to an XMPP server with his
 * username/password
 * 
 * @author dasilvj
 */
public class Login extends Activity {

    private class BeemConnectionListener extends IBeemConnectionListener.Stub {

	private class ErrorRunnable implements Runnable {

	    private final String mErrorMsg;

	    public ErrorRunnable(String errorMsg) {
		mErrorMsg = errorMsg;
	    }

	    @Override
	    public void run() {
		progressDialog.setMessage(mErrorMsg);
	    }

	}

	@Override
	public void connectionClosed() throws RemoteException {
	    mIsConnected = false;
	    beemApp.stopBeemService();
	}

	@Override
	public void connectionClosedOnError() throws RemoteException {
	    mIsConnected = false;
	    beemApp.stopBeemService();
	}

	@Override
	public void connectionFailed(String errorMsg) throws RemoteException {
	    Log.d(getString(R.string.login_tag), "connectionFailed");
	    connectionHandler.post(new ErrorRunnable(errorMsg));
	    beemApp.stopBeemService();
	    dismissProgressDialog();
	}

	private void dismissProgressDialog() {
	    connectionHandler.post(new Runnable() {

		@Override
		public void run() {
		    progressDialog.dismiss();
		}
	    });
	}

	@Override
	public void onConnect() throws RemoteException {
	    Log.d(getString(R.string.login_tag), "onConnect");
	    mIsConnected = true;
	    dismissProgressDialog();
	    startActivity(new Intent(Login.this, ContactList.class));
	}

	@Override
	public void reconnectingIn(int seconds) throws RemoteException {

	}

	@Override
	public void reconnectionFailed() throws RemoteException {
	    mIsConnected = false;
	}

	@Override
	public void reconnectionSuccessful() throws RemoteException {
	    mIsConnected = true;
	}
    }

    protected static final String   TAG               = "LOG_AS";
    private static final Intent     SERVICE_INTENT    = new Intent();
    static {
	SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
    }
    private BeemApplication         beemApp           = null;
    private IXmppConnection         xmppConnection    = null;
    private IXmppFacade             xmppFacade        = null;
    private final Handler           connectionHandler = new Handler();

    private ProgressDialog          progressDialog    = null;

    private boolean                 mIsConnected      = false;
    private final ServiceConnection mServConn         = new ServiceConnection() {

	                                                  @Override
	                                                  public void onServiceConnected(ComponentName name,
	                                                          IBinder service) {
		                                              xmppFacade = IXmppFacade.Stub.asInterface(service);
		                                              try {
		                                                  xmppConnection = xmppFacade.createConnection();
		                                                  xmppConnection
		                                                          .addConnectionListener(new BeemConnectionListener());
		                                              } catch (RemoteException e) {
		                                                  e.printStackTrace();
		                                              }
	                                                  }

	                                                  @Override
	                                                  public void onServiceDisconnected(ComponentName name) {
		                                              xmppFacade = null;
		                                              mIsConnected = false;
	                                                  }
	                                              };

    /**
     * Create an about "BEEM" dialog
     */
    public void createAboutDialog() {
	AlertDialog.Builder builder = new AlertDialog.Builder(this);
	builder.setTitle(R.string.login_about_title).setMessage(R.string.login_about_msg).setCancelable(false);
	builder.setNeutralButton(R.string.login_about_button, new DialogInterface.OnClickListener() {

	    public void onClick(DialogInterface dialog, int whichButton) {
		dialog.cancel();
	    }
	});
	AlertDialog aboutDialog = builder.create();
	aboutDialog.show();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.login);
	progressDialog = new ProgressDialog(this);
	progressDialog.setMessage("Loading. Please wait...");
	beemApp = BeemApplication.getApplication(this);
	this.bindService(Login.SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
	if (!mIsConnected)
	    progressDialog.show();
	beemApp.startBeemService();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
	MenuInflater mInflater = getMenuInflater();
	mInflater.inflate(R.menu.login, menu);
	return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onDestroy() {
	super.onDestroy();
	this.progressDialog.dismiss();
	progressDialog = null;
	this.unbindService(mServConn);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
	Intent i = null;

	switch (item.getItemId()) {
	case R.id.login_menu_settings:
	    i = new Intent(this, EditSettings.class);
	    startActivity(i);
	    return true;
	case R.id.login_menu_about:
	    createAboutDialog();
	    return true;
	}
	return false;
    }
}
