package com.beem.project.beem.ui;

import java.util.ArrayList;
import java.util.List;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
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.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.AdapterView.OnItemClickListener;

import com.beem.project.beem.BeemService;
import com.beem.project.beem.R;
import com.beem.project.beem.service.PrivacyListItem;
import com.beem.project.beem.service.aidl.IPrivacyListListener;
import com.beem.project.beem.service.aidl.IPrivacyListManager;
import com.beem.project.beem.service.aidl.IXmppFacade;
import com.beem.project.beem.utils.BeemBroadcastReceiver;

/**
 * This class represents an activity which allows the user to manage his privacy lists.
 * @author Jean-Manuel Da Silva <dasilvj at beem-project dot com>
 */
public class PrivacyList extends ListActivity {

    private static final String TAG = "PrivacyList";
    private static final Intent SERVICE_INTENT = new Intent();
    static {
	SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
    }
    private Handler mHandler = new Handler();

    private ArrayAdapter<String> mAdapter;
    private final List<String> mPrivacyListNames = new ArrayList<String>();

    private final ServiceConnection mConn = new BeemServiceConnection();
    private BeemBroadcastReceiver mBroadcastReceiver;

    private IPrivacyListManager mPrivacyListManager;
    private IPrivacyListListener mPrivacyListListener;

    /**
     * Constructor.
     */
    public PrivacyList() {
	super();
    }

    /**
     * {@inheritDoc}.
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	Log.d(TAG, "BEGIN onCreate.");
	setContentView(R.layout.privacy_list);

	mHandler = new Handler();

	mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mPrivacyListNames);
	setListAdapter(mAdapter);

	this.getListView().setOnItemClickListener(new OnItemClickListener() {
	    @Override
	    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
	    }
	});

	mPrivacyListListener = new PrivacyListListener();
	mBroadcastReceiver = new BeemBroadcastReceiver(mConn);
	this.registerReceiver(mBroadcastReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED));

	Log.d(TAG, "END onCreate.");
    }

    /**
     * {@inheritDoc}.
     */
    @Override
    protected void onDestroy() {
	super.onDestroy();

	Log.v(TAG, "BEGIN onDestroy.");
	this.unregisterReceiver(mBroadcastReceiver);
	if (mPrivacyListManager != null) {
	    try {
		mPrivacyListManager.removePrivacyListListener(mPrivacyListListener);
	    } catch (RemoteException e) {
		Log.e(TAG, e.getMessage());
	    }
	}
	Log.v(TAG, "END onDestroy.");
    }

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

	Log.v(TAG, "BEGIN onStart.");
	bindService(new Intent(this, BeemService.class), mConn, BIND_AUTO_CREATE);
	Log.v(TAG, "END onStart.");
    }

    /**
     * {@inheritDoc}.
     */
    @Override
    protected void onStop() {
	super.onStop();

	Log.v(TAG, "BEGIN onStop.");
	if (mBroadcastReceiver.isBinded()) {
	    unbindService(mConn);
	}
	Log.v(TAG, "END onStop.");
    }

    /**
     * {@inheritDoc}.
     */
    @Override
    public final boolean onCreateOptionsMenu(Menu menu) {
	super.onCreateOptionsMenu(menu);

	MenuInflater inflater = getMenuInflater();
	inflater.inflate(R.menu.privacy_list, menu);
	return true;
    }

    /**
     * {@inheritDoc}.
     */
    @Override
    public final boolean onOptionsItemSelected(MenuItem item) {
	switch (item.getItemId()) {
	    case R.id.privacy_list_menu_create:
		createCreatePrivacyListDialog();
		return true;
	    default:
		return false;
	}
    }

    private final class BeemServiceConnection implements ServiceConnection {

	private IXmppFacade mXmppFacade;

	@Override
	public void onServiceConnected(ComponentName name, IBinder service) {
	    Log.v(TAG, "BEGIN onServiceConnected.");
	    mXmppFacade = IXmppFacade.Stub.asInterface(service);
	    mBroadcastReceiver.setBinded(true);
	    try {
		mPrivacyListManager = mXmppFacade.getPrivacyListManager();
		mPrivacyListManager.addPrivacyListListener(mPrivacyListListener);
		mPrivacyListNames.addAll(mPrivacyListManager.getPrivacyLists());
		mAdapter.notifyDataSetChanged();
	    } catch (RemoteException e) {
		Log.e(TAG, e.getMessage());
	    }
	    Log.v(TAG, "END onServiceConnected.");
	}

	@Override
	public void onServiceDisconnected(ComponentName name) {
	    Log.v(TAG, "BEGIN onServiceDisconnected.");
	    mXmppFacade = null;
	    mBroadcastReceiver.setBinded(false);
	    try {
		mPrivacyListManager.removePrivacyListListener(mPrivacyListListener);
	    } catch (RemoteException e) {
		Log.e(TAG, e.getMessage());
	    }
	    Log.v(TAG, "END onServiceDisconnected.");
	}
    }

    private class PrivacyListListener extends IPrivacyListListener.Stub {

	@Override
	public void setPrivacyList(String listName, List<PrivacyListItem> listItem) throws RemoteException {
	    Log.d(TAG, "BEGIN PrivacyListListener >> setPrivacyList.");
	    Log.d(TAG, "> " + listName + " has been setted.");
	    Log.d(TAG, "END PrivacyListListener >> setPrivacyList.");
	}

	@Override
	public void updatedPrivacyList(final String listName) throws RemoteException {
	    Log.d(TAG, "BEGIN PrivacyListListener >> updatedPrivacyList.");
	    mHandler.post(new Runnable() {
		@Override
		public void run() {
		    try {
			mPrivacyListNames.clear();
			// Not that much lists and require some server queries to know if the list has been
			// updated/deleted or set to default/active by this activity or another IM client.
			mPrivacyListNames.addAll(mPrivacyListManager.getPrivacyLists());
		    } catch (RemoteException e) {
			Log.e(TAG, e.getMessage());
		    }
		    mAdapter.notifyDataSetChanged();
		}
	    });
	    Log.d(TAG, "END PrivacyListListener >> updatedPrivacyList.");
	}
    }

    private void createCreatePrivacyListDialog() {
	LayoutInflater factory = LayoutInflater.from(this);
	final View textEntryView = factory.inflate(R.layout.privacy_list_create_dialog, null);
	AlertDialog.Builder builder = new AlertDialog.Builder(this);
	builder.setTitle(R.string.privacy_list_create_dialog_title);
	builder.setView(textEntryView);

	builder.setPositiveButton(R.string.privacy_list_create_dialog_create_button,
	    new DialogInterface.OnClickListener() {
		public void onClick(DialogInterface dialog, int whichButton) {
		    EditText listNameField = (EditText) textEntryView
			.findViewById(R.id.privacy_list_create_dialog_list_name);
		    try {
			mPrivacyListManager.createPrivacyList(listNameField.getText().toString(),
			    new ArrayList<PrivacyListItem>());
		    } catch (RemoteException e) {
			Log.e(TAG, e.getMessage());
		    }
		}
	    });

	builder.setNegativeButton(R.string.CancelButton, new DialogInterface.OnClickListener() {
	    public void onClick(DialogInterface dialog, int whichButton) {
	    }
	});

	AlertDialog createPrivacyListDialog = builder.create();
	createPrivacyListDialog.show();
    }
}
