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.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.graphics.drawable.Drawable;
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.aidl.IRoster;
import com.beem.project.beem.service.aidl.IXMPPFacade;

public class ContactList extends ExpandableListActivity {

    private static final String TAG = "CONTACTLIST_ACT";
    private SharedPreferences mSettings;
    private IXMPPFacade mService = null;
    private Handler mHandler;
    private BeemApplication mBeemApplication;
    private ContactListDialogSettings mDialog;

    @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);
	mHandler = new Handler();
	mBeemApplication = BeemApplication.getApplication(this);
	mSettings = getSharedPreferences(
		getString(R.string.PreferenceFileName), MODE_PRIVATE);
	mDialog = new ContactListDialogSettings(this, mSettings);

	mSettings
		.registerOnSharedPreferenceChangeListener(new OnSharedPreferenceChangeListener() {
		    @Override
		    public void onSharedPreferenceChanged(
			    SharedPreferences sharedPreferences, String key) {
			/*
			 * TODO : A faire apres listener nikita
			 * 
			 * mBeemApplication.stopBeemService();
			 * mBeemApplication.startBeemService();
			 * mBeemApplication.callWhenServiceConnected(mHandler,
			 * new Runnable() {
			 * 
			 * @Override public void run() {
			 * callbackShowContactList(); } });
			 */
		    }
		});

    }

    @Override
    protected void onStart() {
	super.onStart();
	Log.i(TAG, "onStart");
    }

    @Override
    protected void onResume() {
	super.onResume();
	/*
	 * @TODO: A ameliorer apres listener de nikita
	 */
	Log.i(TAG, "onResume");
	if (!mBeemApplication.isConnected())
	    mBeemApplication.startBeemService();
	else {
	    callbackShowContactList();
	}
	mBeemApplication.callWhenServiceConnected(mHandler, new Runnable() {
	    @Override
	    public void run() {
		callbackShowContactList();
	    }
	});
    }

    private void callbackShowContactList() {
	/*
	 * @TODO: A ameliorer apres listener de nikita
	 */
	mService = mBeemApplication.getXmppFacade();
	if (mService != null) {
	    try {
		IRoster r = mService.getRoster();
		if (r != null)
		    showContactList(r.getGroupsNames(), r.getContactList());
	    } catch (RemoteException e) {
		// TODO Auto-generated catch block
		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:
		mDialog.show();
		return true;
	    case R.id.account_about:
		return true;
	    default:
		return false;
	}
    }

    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 Contact.CONTACT_STATUS_AVAILABLE:
			imageDrawable = (Drawable) getResources().getDrawable(
				R.drawable.avatar);
		    case Contact.CONTACT_STATUS_AVAILABLE_FOR_CHAT:
			imageDrawable = (Drawable) getResources().getDrawable(
				R.drawable.chat);
		    case Contact.CONTACT_STATUS_AWAY:
			imageDrawable = (Drawable) getResources().getDrawable(
				R.drawable.away);
		    case Contact.CONTACT_STATUS_BUSY:
			imageDrawable = (Drawable) getResources().getDrawable(
				R.drawable.dnd);
		    case Contact.CONTACT_STATUS_DISCONNECT:
			imageDrawable = (Drawable) getResources().getDrawable(
				R.drawable.offline);
		    case Contact.CONTACT_STATUS_UNAVAILABLE:
			imageDrawable = (Drawable) getResources().getDrawable(
				R.drawable.requested);
		    default:
			imageDrawable = (Drawable) getResources().getDrawable(
				R.drawable.error);
		}
		imgV.setImageDrawable(imageDrawable);

		TextView v = (TextView) view.findViewById(to[1]);
		if (v != null) {
		    v.setText(c.getJID());
		}
		/*
		 * @TODO: Rajouter le message perso du contact v = (TextView)
		 */
		v = (TextView) view.findViewById(to[2]);
		if (v != null) {
		    v.setText(c.getMMsgState());
		}

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