package com.beem.project.beem.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.ExpandableListActivity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;

import com.beem.project.beem.BeemApplication;
import com.beem.project.beem.R;
import com.beem.project.beem.service.Contact;
import com.beem.project.beem.service.PresenceAdapter;
import com.beem.project.beem.service.aidl.IBeemRosterListener;
import com.beem.project.beem.service.aidl.IRoster;
import com.beem.project.beem.service.aidl.IXmppFacade;
import com.beem.project.beem.utils.Status;

public class ContactList extends ExpandableListActivity {

    private static final String TAG = "CONTACTLIST_ACT";
    private static final int PREFERENCECHANGED = 0;
    private static final int CREATEACCOUNT = 1;
    private IXmppFacade mService = null;
    private SharedPreferences mSettings;
    private Handler mHandler;
    private BeemApplication mBeemApplication;
    private BeemRosterListener mRosterListener;
    private IRoster mRoster;

    @SuppressWarnings("unchecked")
    @Override
    public boolean onChildClick(ExpandableListView parent, View v,
	int groupPosition, int childPosition, long id) {
	Intent i = new Intent(this, SendIM.class);
	Map<String, Contact> child = (HashMap<String, Contact>) parent
	.getExpandableListAdapter().getChild(groupPosition,
	    childPosition);
	i.putExtra("contact", child.get("CHILD"));
	startActivity(i);
	return true;
    }

    @Override
    protected void onCreate(Bundle saveBundle) {
	super.onCreate(saveBundle);
	setTheme(R.style.customtheme_contactList);
	mHandler = new Handler();
	mBeemApplication = BeemApplication.getApplication(this);
	mSettings = getSharedPreferences(
	    getString(R.string.PreferenceFileName), MODE_PRIVATE);
	mRosterListener = new BeemRosterListener();
    }

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

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        mBeemApplication.unbindBeemService();
    }

    @Override
    protected void onResume() {
	super.onResume();
	mBeemApplication.startBeemService();
	/*
	 * @TODO: A ameliorer apres listener de nikita
	 */
	Log.i(TAG, "onResume");
	mBeemApplication.callWhenConnectedToServer(mHandler, new Runnable() {
	    @Override
	    public void run() {
		mService = mBeemApplication.getXmppFacade();
		try {
		    mRoster = mService.getRoster();
		} catch (RemoteException e1) {
		    e1.printStackTrace();
		}
		if (mRoster != null) {
		    try {
			mRoster.addConnectionListener(mRosterListener);
		    } catch (RemoteException e) {
			e.printStackTrace();
		    }
		}
		callbackShowContactList();
	    }
	});
    }

    private void callbackShowContactList() {
	/*
	 * @TODO: A ameliorer apres listener de nikita
	 */
	if (mRoster != null)
	    try {
		showContactList(mRoster.getGroupsNames(), mRoster
		    .getContactList());
	    } catch (RemoteException e) {
		e.printStackTrace();
	    }
    }

    /**
     * Callback for menu creation.
     * 
     * @param menu
     *            the menu created
     * @return true on success, false otherwise
     */
    @Override
    public final boolean onCreateOptionsMenu(Menu menu) {
	super.onCreateOptionsMenu(menu);
	MenuInflater inflater = getMenuInflater();
	inflater.inflate(R.menu.contactlistmenu, menu);
	return true;
    }

    /**
     * Callback for menu item selected.
     * 
     * @param item
     *            the item selected
     * @return true on success, false otherwise
     */
    @Override
    public final boolean onOptionsItemSelected(MenuItem item) {
	switch (item.getItemId()) {
	    case R.id.account_edit:
		startActivityForResult(new Intent(this, ContactListSettings.class), PREFERENCECHANGED);
		return true;
	    case R.id.account_about:
		Intent t = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.beem-project.com"));
		startActivity(t);
		return true;
	    case R.id.account_create:
		startActivity(new Intent(this, AccountCreation.class));
		return true;
	    case R.id.add_contact:
		startActivity(new Intent(this, AddContact.class));
		return true;
	    default:
		return false;
	}
    }

    protected void onActivityResult(int requestCode, int resultCode,
	Intent data) {
	if (requestCode == PREFERENCECHANGED) {
	    if (resultCode == RESULT_OK) {
		mBeemApplication.stopBeemService();
		mBeemApplication.startBeemService();
	    }            
	}
    }


    private void showContactList(List<String> listGroup,
	List<Contact> listContact) {
	ExpandableListAdapter Adapter;
	List<Map<String, String>> groupData = new ArrayList<Map<String, String>>();
	List<List<Map<String, Contact>>> childData = new ArrayList<List<Map<String, Contact>>>();

	if (listGroup.size() == 0)
	    listGroup.add("Default");
	for (int i = 0; i < listGroup.size(); i++) {
	    Map<String, String> curGroupMap = new HashMap<String, String>();

	    groupData.add(curGroupMap);
	    curGroupMap.put("GROUP", listGroup.get(i));

	    List<Map<String, Contact>> children = new ArrayList<Map<String, Contact>>();
	    for (int j = 0; j < listContact.size(); ++j) {
		Map<String, Contact> curChildMap = new HashMap<String, Contact>();
		children.add(curChildMap);
		Contact c = listContact.get(j);
		Log.i(TAG, c.getID() + " " + c.getJID());
		curChildMap.put("CHILD", c);
	    }
	    childData.add(children);
	}

	Adapter = new ContactExpandableListAdapter(this, groupData,
	    R.layout.contactlistgroup, new String[] { "GROUP" },
	    new int[] { R.id.textgroup }, childData,
	    R.layout.contactlistcontact, new String[] { "CHILD" },
	    new int[] { R.id.contactliststatus, R.id.contactlistpseudo,
	    R.id.contactlistmsgperso, R.id.contactlistavatar });
	setListAdapter(Adapter);
    }

    /**
     * A simple adapter which allows you to bind data to specific Views defined
     * within the layout of an Expandable Lists children (Implement
     * getGroupView() to define the layout of parents)
     */
    private class ContactExpandableListAdapter extends
    SimpleExpandableListAdapter {

	private List<? extends List<? extends Map<String, ?>>> mChildData;
	private String[] mChildFrom;
	private int[] mChildTo;

	public ContactExpandableListAdapter(Context context,
	    List<? extends Map<String, ?>> groupData, int groupLayout,
		String[] groupFrom, int[] groupTo,
		List<? extends List<? extends Map<String, ?>>> childData,
		    int childLayout, String[] childFrom, int[] childTo) {
	    super(context, groupData, groupLayout, groupFrom, groupTo,
		childData, childLayout, childFrom, childTo);

	    mChildData = childData;
	    mChildFrom = childFrom;
	    mChildTo = childTo;

	}

	@Override
	public View getChildView(int groupPosition, int childPosition,
	    boolean isLastChild, View convertView, ViewGroup parent) {

	    View v;
	    if (convertView == null) {
		v = newChildView(isLastChild, parent);
	    } else {
		v = convertView;
	    }
	    bindView(v, mChildData.get(groupPosition).get(childPosition),
		mChildFrom, mChildTo, groupPosition, childPosition);
	    return v;
	}

	private void bindView(View view, Map<String, ?> data, String[] from,
	    int[] to, int groupPosition, int childPosition) {
	    Contact c = (Contact) data.get(from[0]);

	    if (c != null) {

		ImageView imgV = (ImageView) view.findViewById(to[0]);
		Drawable imageDrawable = null;
		switch (c.getStatus()) {
		    case Status.CONTACT_STATUS_AVAILABLE:
			imageDrawable = (Drawable) getResources().getDrawable(
			    R.drawable.online);
			break;
		    case Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT:
			imageDrawable = (Drawable) getResources().getDrawable(
			    R.drawable.chat);
			break;
		    case Status.CONTACT_STATUS_AWAY:
			imageDrawable = (Drawable) getResources().getDrawable(
			    R.drawable.away);
			break;
		    case Status.CONTACT_STATUS_BUSY:
			imageDrawable = (Drawable) getResources().getDrawable(
			    R.drawable.dnd);
			break;
		    case Status.CONTACT_STATUS_DISCONNECT:
			imageDrawable = (Drawable) getResources().getDrawable(
			    R.drawable.offline);
			break;
		    case Status.CONTACT_STATUS_UNAVAILABLE:
			imageDrawable = (Drawable) getResources().getDrawable(
			    R.drawable.requested);
			break;
		    default:
			imageDrawable = (Drawable) getResources().getDrawable(
			    R.drawable.error);
		    break;
		}
		imgV.setImageDrawable(imageDrawable);

		TextView v = (TextView) view.findViewById(to[1]);
		if (v != null) {
		    v.setText(c.getJID());
		}

		v = (TextView) view.findViewById(to[2]);
		if (v != null) {
		    v.setText(c.getMsgState());
		}

		/*
		 * TODO: Rajouter l'avatar du contact getAvatar() dans la
		 * classe
		 */
		imgV = (ImageView) view.findViewById(to[3]);
		if (imgV != null) {
		    imageDrawable = (Drawable) getResources().getDrawable(
			R.drawable.avatar);
		    imgV.setImageDrawable(imageDrawable);
		}
	    }
	}
    }

    private class BeemRosterListener extends IBeemRosterListener.Stub {

	@Override
	public void onEntriesAdded(List<String> addresses)
	throws RemoteException {
	    Log.i(TAG, "ENTRIES ADDED");

	}

	@Override
	public void onEntriesDeleted(List<String> addresses)
	throws RemoteException {
	    Log.i(TAG, "ENTRIES DEL");

	}

	@Override
	public void onEntriesUpdated(List<String> addresses)
	throws RemoteException {
	    Log.i(TAG, "ENTRIES UPD");

	}

	@Override
	public void onPresenceChanged(PresenceAdapter presence)
	throws RemoteException {
	    Log.i(TAG, "PRESENCE CHANGED");

	}

    }
}