/**
 *
 */
package com.beem.project.beem.service;

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

import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.util.StringUtils;

import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;

import com.beem.project.beem.utils.Status;

/**
 * This class contains informations on a jabber contact.
 * 
 * @author darisk
 */
public class Contact implements Parcelable {

	/**
	 * Parcelable.Creator needs by Android.
	 */
	public static final Parcelable.Creator<Contact> CREATOR = new Parcelable.Creator<Contact>() {

		@Override
		public Contact createFromParcel(Parcel source) {
			return new Contact(source);
		}

		@Override
		public Contact[] newArray(int size) {
			return new Contact[size];
		}
	};

	private int mID;
	private int mStatus;
	private String mJID;
	private String mMsgState;
	private List<String> mRes;
	private List<String> mGroups;
	private String mName;

	/**
	 * Constructor.
	 */
	public Contact() {
	}

	/**
	 * Construct a contact from a parcel.
	 * 
	 * @param in
	 *            parcel to use for construction
	 */
	private Contact(final Parcel in) {
		mID = in.readInt();
		mStatus = in.readInt();
		mJID = in.readString();
		mName = in.readString();
		mMsgState = in.readString();
		mRes = new ArrayList<String>();
		mGroups = new ArrayList<String>();
		in.readStringList(mRes);
		in.readStringList(mGroups);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeInt(mID);
		dest.writeInt(mStatus);
		dest.writeString(mJID);
		dest.writeString(mName);
		dest.writeString(mMsgState);
		dest.writeStringList(getMRes());
		dest.writeStringList(getGroups());
	}

	/**
	 * Constructor.
	 * 
	 * @param jid
	 *            JID of the contact
	 */
	public Contact(final String jid) {
		mJID = StringUtils.parseBareAddress(jid);
		mName = mJID;
		mStatus = Status.CONTACT_STATUS_DISCONNECT;
		mMsgState = null;
		mRes = new ArrayList<String>();
		String res = StringUtils.parseResource(jid);
		if (!"".equals(res))
			mRes.add(res);
		mGroups = new ArrayList<String>();
	}

	/**
	 * Create a contact from a Uri.
	 * 
	 * @param uri
	 *            an uri for the contact
	 * @throws IllegalArgumentException
	 *             if it is not a xmpp uri
	 */
	public Contact(final Uri uri) {
		if (!"xmpp".equals(uri.getScheme()))
			throw new IllegalArgumentException();
		String enduri = uri.getEncodedSchemeSpecificPart();
		mJID = StringUtils.parseBareAddress(enduri);
		mName = mJID;
		mStatus = Status.CONTACT_STATUS_DISCONNECT;
		mMsgState = null;
		mRes = new ArrayList<String>();
		mRes.add(StringUtils.parseResource(enduri));
		mGroups = new ArrayList<String>();
	}

	/**
	 * Add a group for the contact.
	 * 
	 * @param group
	 *            the group
	 */
	public void addGroup(String group) {
		if (!mGroups.contains(group))
			mGroups.add(group);
	}

	/**
	 * Remove the contact from a group.
	 * 
	 * @param group
	 *            the group to delete the contact from.
	 */
	public void delGroup(String group) {
		mGroups.remove(group);
	}

	/**
	 * Add a resource for this contact.
	 * 
	 * @param res
	 *            the resource to add
	 */
	public void addRes(String res) {
		if (!mRes.contains(res))
			mRes.add(res);
	}

	/**
	 * Delete a resource for this contact.
	 * 
	 * @param res
	 *            the resource de delete
	 */
	public void delRes(String res) {
		mRes.remove(res);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int describeContents() {
		// TODO Auto-generated method stub
		return 0;
	}

	/**
	 * Get the groups the contact is in.
	 * 
	 * @return the mGroups
	 */
	public List<String> getGroups() {
		return mGroups;
	}

	/**
	 * Get the id of the contact on the phone contact list.
	 * 
	 * @return the mID
	 */
	public int getID() {
		return mID;
	}

	/**
	 * Get the Jabber ID of the contact.
	 * 
	 * @return the Jabber ID
	 */
	public String getJID() {
		return mJID;
	}

	/**
	 * Get the list of resource for the contact.
	 * 
	 * @return the mRes
	 */
	public List<String> getMRes() {
		return mRes;
	}

	/**
	 * Get the message status of the contact.
	 * 
	 * @return the message status of the contact.
	 */
	public String getMsgState() {
		return mMsgState;
	}

	/**
	 * Get the name of the contact.
	 * 
	 * @return the mName
	 */
	public String getName() {
		return mName;
	}

	/**
	 * Get the status of the contact.
	 * 
	 * @return the mStatus
	 */
	public int getStatus() {
		return mStatus;
	}

	/**
	 * Set the groups the contact is in.
	 * 
	 * @param groups
	 *            list of groups
	 */
	public void setGroups(Collection<RosterGroup> groups) {
		this.mGroups.clear();
		for (RosterGroup rosterGroup : groups) {
			mGroups.add(rosterGroup.getName());
		}
	}

	/**
	 * Set the groups the contact is in.
	 * 
	 * @param groups
	 *            the mGroups to set
	 */
	public void setGroups(List<String> groups) {
		this.mGroups = groups;
	}

	/**
	 * set the id of te contact on the phone contact list.
	 * 
	 * @param mid
	 *            the mID to set
	 */
	public void setID(int mid) {
		mID = mid;
	}

	/**
	 * Set the Jabber ID of the contact.
	 * 
	 * @param jid
	 *            the jabber ID to set
	 */
	public void setJID(String jid) {
		mJID = jid;
	}

	/**
	 * Set a list of resource for the contact.
	 * 
	 * @param mRes
	 *            the mRes to set
	 */
	public void setMRes(List<String> mRes) {
		this.mRes = mRes;
	}

	/**
	 * Set the message status of the contact.
	 * 
	 * @param msgState
	 *            the message status of the contact to set
	 */
	public void setMsgState(String msgState) {
		mMsgState = msgState;
	}

	/**
	 * Set the name of the contact.
	 * 
	 * @param name
	 *            the mName to set
	 */
	public void setName(String name) {
		if (name == null || "".equals(name)) {
			this.mName = this.mJID;
			this.mName = StringUtils.parseName(this.mName);
			if (this.mName == null || "".equals(this.mName))
				this.mName = this.mJID;
		} else {
			this.mName = name;
		}
	}

	/**
	 * Set the status of the contact.
	 * 
	 * @param status
	 *            the mStatus to set
	 */
	public void setStatus(int status) {
		mStatus = status;
	}

	/**
	 * Set the status of the contact using a presence packet.
	 * 
	 * @param presence
	 *            the presence containing status
	 */
	public void setStatus(Presence presence) {
		mStatus = Status.getStatusFromPresence(presence);
		mMsgState = presence.getStatus();
	}

	/**
	 * Set status for the contact.
	 * 
	 * @param presence
	 *            The presence packet which contains the status
	 */
	public void setStatus(PresenceAdapter presence) {
		mStatus = presence.getStatus();
		mMsgState = presence.getStatusText();

	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String toString() {
		if (mJID != null)
			return mJID;
		return super.toString();
	}

	/**
	 * Get a URI to access the contact.
	 * 
	 * @return the URI
	 */
	public Uri toUri() {
		StringBuilder build = new StringBuilder("xmpp:");
		String name = StringUtils.parseName(mJID);
		build.append(name);
		if (!"".equals(name))
			build.append('@');
		build.append(StringUtils.parseServer(mJID));
		Uri u = Uri.parse(build.toString());
		return u;
	}

	/**
	 * Get a URI to access the specific contact on this resource.
	 * 
	 * @param resource
	 *            the resource of the contact
	 * @return the URI
	 */
	public Uri toUri(String resource) {
		StringBuilder build = new StringBuilder("xmpp:");
		String name = StringUtils.parseName(mJID);
		build.append(name);
		if (!"".equals(name))
			build.append('@');
		build.append(StringUtils.parseServer(mJID));
		if (!"".equals(resource)) {
			build.append('/');
			build.append(resource);
		}
		Uri u = Uri.parse(build.toString());
		return u;
	}

}
