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.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.beem.project.beem.BeemService;
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;
import com.beem.project.beem.utils.Status;

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

    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 final Handler connectionHandler = new Handler();
    private ProgressDialog progressDialog = null;

    private boolean mIsConnected = false;
    private final ServiceConnection mServConn = new BeemServiceConnection();
    private IXmppFacade xmppFacade = null;

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

    /**
     * Create Login activity
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.login);
	Button button = (Button) findViewById(R.id.log_as_settings);
	button.setOnClickListener(new OnClickListener() {

	    @Override
	    public void onClick(View v) {
		startActivity(new Intent(Login.this, EditSettings.class));
	    }

	});
	button = (Button) findViewById(R.id.log_as_login);
	button.setOnClickListener(new OnClickListener() {

	    @Override
	    public void onClick(View v) {
		bindService(Login.SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
	    }

	});
	progressDialog = new ProgressDialog(this);
    }

    @Override
    protected void onDestroy() {
	super.onDestroy();
	if (mIsConnected || xmppFacade == null) {
	    unbindService(mServConn);
	}
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onStart() {
	super.onStart();
	Log.e("LOGIN", "BINDSERVICE");
	bindService(Login.SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
    }

    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 {
	    Log.e("Login", "CONNECTIONCLOSED");
	}

	@Override
	public void connectionClosedOnError() throws RemoteException {
	    Log.e("Login", "CONNECTIONCLOSEONERROR");
	}

	@Override
	public void connectionFailed(String errorMsg) throws RemoteException {
	    mIsConnected = false;
	    if (xmppFacade != null) {
		Login.this.unbindService(mServConn);
		Login.this.stopService(SERVICE_INTENT);
	    }
	    connectionHandler.post(new ErrorRunnable(errorMsg));
	    dismissProgressDialog();
	    showToast(errorMsg);
	}

	private void showToast(final String errorMsg) {
	    connectionHandler.post(new Runnable() {
		@Override
		public void run() {
		    Toast.makeText(Login.this, errorMsg, Toast.LENGTH_LONG).show();
		    TextView labelError = (TextView) findViewById(R.id.log_as_msg);
		    labelError.setText(errorMsg);
		}
	    });
	}

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

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

	@Override
	public void onConnect() throws RemoteException {
	    mIsConnected = true;
	    dismissProgressDialog();
	    Log.i(getString(R.string.login_tag), "Connected.");
	    xmppFacade.changeStatus(Status.CONTACT_STATUS_AVAILABLE, null);
	    startActivity(new Intent(Login.this, ContactList.class));
	    finish();
	}

	@Override
	public void reconnectingIn(int seconds) throws RemoteException {
	    mIsConnected = true;

	}

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

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

    private class BeemServiceConnection implements ServiceConnection {
	private IXmppConnection xmppConnection = null;

	@Override
	public void onServiceConnected(ComponentName name, IBinder service) {
	    mIsConnected = true;
	    xmppFacade = IXmppFacade.Stub.asInterface(service);
	    try {
		xmppConnection = xmppFacade.createConnection();
		xmppConnection.addConnectionListener(new BeemConnectionListener());
		if (!xmppConnection.isAuthentificated()) {
		    connectionHandler.post(new Runnable() {

			@Override
			public void run() {
			    progressDialog.setMessage("Connecting. Please wait...");
			    progressDialog.show();
			}
		    });
		    Login.this.startService(Login.SERVICE_INTENT);
		} else {
		    startActivity(new Intent(Login.this, ContactList.class));
		    finish();
		}
	    } catch (RemoteException e) {
		Log.e(getString(R.string.login_tag), "REMOTE EXCEPTION $" + e.getMessage());
	    }
	}

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

}
