/*
    BEEM is a videoconference application on the Android Platform.

    Copyright (C) 2009 by Frederic-Charles Barthelery,
                          Jean-Manuel Da Silva,
                          Nikita Kozlov,
                          Philippe Lago,
                          Jean Baptiste Vergely,
                          Vincent Veronis.

    This file is part of BEEM.

    BEEM is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    BEEM is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.

    Please send bug reports with examples or suggestions to
    contact@beem-project.com or http://dev.beem-project.com/

    Epitech, hereby disclaims all copyright interest in the program "Beem"
    written by Frederic-Charles Barthelery,
               Jean-Manuel Da Silva,
               Nikita Kozlov,
               Philippe Lago,
               Jean Baptiste Vergely,
               Vincent Veronis.

    Nicolas Sadirac, November 26, 2009
    President of Epitech.

    Flavien Astraud, November 26, 2009
    Head of the EIP Laboratory.

*/
package com.beem.project.beem.smack.avatar;

import android.util.Log;

import com.beem.project.beem.smack.avatar.AvatarMetadataExtension.Info;
import com.beem.project.beem.smack.pep.PEPListener;
import com.beem.project.beem.smack.pep.PepSubManager;

import java.io.IOException;

import java.util.List;

import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smackx.pubsub.Item;
import org.jivesoftware.smackx.pubsub.PayloadItem;

/**
 * This class deals with the avatar data.
 * It can be configured to auto retrieve the avatar and put it in cache.
 *
 */
public class AvatarManager {

    private PepSubManager mPep;
    private Connection mCon;
    private boolean mAutoDownload;
    private AvatarCache mCache;

    /**
     * Create an AvatarManager.
     *
     * @param con the connection
     * @param cache the cache which will store the avatars
     * @param autoDownload true to enable auto download of avatars
     */
    public AvatarManager(final Connection con, final AvatarCache cache, final boolean autoDownload) {
	Log.d("AvatarMgr", "creation");
	mCon = con;
	mPep = new PepSubManager(mCon);
	mAutoDownload = autoDownload;
	mCache = cache;
	if (mAutoDownload)
	    mPep.addPEPListener(new Listener());
    }

    /**
     * Get an avatar from the cache.
     *
     * @param avatarId the id of the avatar
     * @return the avatar or null if it cannot be retrieved from the cache
     */
    public byte[] getAvatar(String avatarId) {
	try {
	    return mCache.get(avatarId);
	} catch (IOException e) {
	    return null;
	}
    }

    /**
     * Select the avatar to download.
     * Subclass should override this method to take control over the selection process.
     * This implementation select the first element.
     *
     * @param available list of the avatar metadata information
     * @return the metadata of the avatar to download
     */
    protected Info selectAvatar(List<Info> available) {
	return available.get(0);
    }

    /**
     * Doawload an avatar.
     *
     * @param from The jid of the user
     * @param info the metadata information of the avatar to download
     */
    private void downloadAvatar(String from, Info info) {
	try {
	    AvatarRetriever retriever = AvatarRetrieverFactory.getRetriever(mCon, from, info);
	    byte[] avatar = retriever.getAvatar();
	// TODO check the hash before store
	    mCache.put(info.getId(), avatar);
	} catch (IOException e) {
	    Log.d("AvatarMgr", "Error while downloading avatar", e);
	}
    }

    /**
     * A listener to PEPEevent.
     */
    private class Listener implements PEPListener {

	/**
	 * Create a listener.
	 */
	public Listener() {
	}

	@Override
	public void eventReceived(String from, String node, List<Item> items) {
	    Log.d("AvatarMgr", "Received pep event ");
	    Item i = items.get(0);
	    if (i instanceof PayloadItem) {
		PayloadItem<PacketExtension> pi = (PayloadItem<PacketExtension>) i;
		PacketExtension ex = pi.getPayload();
		if (ex instanceof AvatarMetadataExtension) {
		    Log.d("AvatarMgr", "Received avatar meta");
		    AvatarMetadataExtension ext = (AvatarMetadataExtension) ex;
		    Info info = selectAvatar(ext.getInfos());
		    if (!mCache.contains(info.getId()))
			downloadAvatar(from, info);
		}
	    }
	}
    }
}
