/*
 * Copyright (c) 2002-2004 David Keiichi Watanabe
 * davew@xlife.org
 *
 * Modified by (c) 2004-2005 heavy_baby
 * heavy_baby@users.sourceforge.jp
 *
 * This program 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 2
 * of the License, or (at your option) any later version.
 * 
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package jp.sourceforge.cabos;

import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.limegroup.gnutella.ActivityCallback;
import com.limegroup.gnutella.Connection;
import com.limegroup.gnutella.Downloader;
import com.limegroup.gnutella.ErrorCallback;
import com.limegroup.gnutella.FileDesc;
import com.limegroup.gnutella.FileManagerEvent;
import com.limegroup.gnutella.GUID;
import com.limegroup.gnutella.ManagedConnection;
import com.limegroup.gnutella.MessageCallback;
import com.limegroup.gnutella.RemoteFileDesc;
import com.limegroup.gnutella.Uploader;
import com.limegroup.gnutella.browser.MagnetOptions;
import com.limegroup.gnutella.downloader.ManagedDownloader;
import com.limegroup.gnutella.gui.DaapManager;
import com.limegroup.gnutella.search.HostData;
import com.limegroup.gnutella.settings.BooleanSetting;
import com.limegroup.gnutella.settings.DaapSettings;
import com.limegroup.gnutella.util.CommonUtils;

public class AqEventHandler implements ActivityCallback, ErrorCallback,
		MessageCallback {

	/* Instances */

	protected volatile static Map stateCache = new Hashtable();

	protected volatile static Map hosts = new Hashtable();

	protected volatile static Map queriesToIndices = new HashMap();

	protected volatile static Map indicesToQueries = new HashMap();

	protected volatile static Map queryGUIDs = new HashMap();

	protected volatile static Map responses = new HashMap();

	protected volatile static Map alts = new HashMap();

	protected volatile static List downloads = new LinkedList();

	protected volatile static List uploads = new LinkedList();

	protected volatile static int currentQueryIndex = -1;

	protected volatile static int currentLocalIndex = -1;

	/* Connections */

	public void addressStateChanged() {
	}

	public void connectionInitializing(Connection c) {
	}

	public void connectionInitialized(Connection c) {
		if (c instanceof ManagedConnection)
			AqEvent.signalEvent(AqEvent.kLWEventConnectionInitialized, c);
	}

	public void connectionClosed(Connection c) {
		if (c instanceof ManagedConnection)
			AqEvent.signalEvent(AqEvent.kLWEventConnectionClosed, c);
	}

	/* Queries */

	public void handleQueryResult(RemoteFileDesc rfd, HostData data, Set locs) {
		synchronized (queriesToIndices) {
			if (queriesToIndices.containsKey(new GUID(data.getMessageGUID())))
				AqEvent.signalEvent(AqEvent.kLWEventQueryResult, rfd, data,
						locs);
		}
	}

	public void handleQueryString(String query) {
	}

	/* Uploads */

	public void addUpload(Uploader u) {
		int state = u.getState();
		if (state != Uploader.BANNED_GREEDY && state != Uploader.COMPLETE
				&& state != Uploader.FILE_NOT_FOUND
				&& state != Uploader.FREELOADER
				&& state != Uploader.LIMIT_REACHED
				&& state != Uploader.MALFORMED_REQUEST) {
			AqEvent.signalEvent(AqEvent.kLWEventAddUpload, u);
			List newUploads = new LinkedList(uploads);
			newUploads.add(u);
			uploads = Collections.unmodifiableList(newUploads);
		}
	}

	public void removeUpload(Uploader u) {
		List newUploads = new LinkedList(uploads);
		newUploads.remove(u);
		uploads = Collections.unmodifiableList(newUploads);
		AqEvent.signalEvent(AqEvent.kLWEventUpdateUploadStats, u);
		AqEvent.signalEvent(AqEvent.kLWEventRemoveUpload, u);
	}

	/* Browse */

	public void browseHostFailed(GUID guid) {
	}

	/* Sharing */

	public void fileManagerLoading() {
		if (CommonUtils.isJava14OrLater()
				&& DaapSettings.DAAP_ENABLED.getValue())
			DaapManager.instance().fileManagerLoading();
	}

	public void fileManagerLoaded() {
		if (CommonUtils.isJava14OrLater()
				&& DaapSettings.DAAP_ENABLED.getValue())
			DaapManager.instance().fileManagerLoaded();
	}

	public boolean warnAboutSharingSensitiveDirectory(final File dir) {
		return false;
	}

	public void handleFileEvent(FileManagerEvent evt) {
		if (CommonUtils.isJava14OrLater()
				&& DaapSettings.DAAP_ENABLED.getValue()
				&& DaapManager.instance().isEnabled())
			DaapManager.instance().handleFileManagerEvent(evt);
		if (evt.isAddEvent()) {
			FileDesc[] files = evt.getFileDescs();
			for (int i = 0; i < files.length; i++)
				AqEvent.signalEvent(AqEvent.kLWEventAddSharedFile, files[i]);
		}
	}

	public void handleSharedFileUpdate(File file) {
	}

	public void setAnnotateEnabled(boolean enabled) {
	}

	/* Misc */

	public void uploadsComplete() {
	}

	public void restoreApplication() {
	}

	public boolean isQueryAlive(GUID guid) {
		synchronized (queriesToIndices) {
			return queriesToIndices.containsKey(guid);
		}
	}

	public void componentLoading(String component) {
		System.err.println(component);
	}

	public boolean handleMagnets(final MagnetOptions[] magnets) {
		return false;
	}

	public void acceptedIncomingChanged(boolean status) {
	}

	/* DownloadCallback */

	public void addDownload(Downloader d) {
		if (d instanceof ManagedDownloader) {
			AqEvent.signalEvent(AqEvent.kLWEventAddDownload, d);
			List newDownloads = new LinkedList(downloads);
			newDownloads.add(d);
			downloads = Collections.unmodifiableList(newDownloads);
		}
	}

	public void removeDownload(Downloader d) {
		if (d instanceof ManagedDownloader) {
			List newDownloads = new LinkedList(downloads);
			newDownloads.remove(d);
			downloads = Collections.unmodifiableList(newDownloads);
			AqEvent.signalEvent(AqEvent.kLWEventUpdateDownloadStats, d);
			AqEvent.signalEvent(AqEvent.kLWEventRemoveDownload, d);
		}
	}

	public void downloadsComplete() {
	}

	public void showDownloads() {
	}

	public void promptAboutCorruptDownload(Downloader dloader) {
		if (dloader instanceof ManagedDownloader)
			dloader.discardCorruptDownload(false);
	}

	public String getHostValue(String key) {
		return null;
	}

	/* ErrorCallback */

	public void error(Throwable t) {
		t.printStackTrace();
	}

	public void error(Throwable t, String msg) {
		System.err.println(msg);
		t.printStackTrace();
	}

	/* MessageCallback */

	public void showError(String messageKey) {
		System.err.println(messageKey);
	}

	public void showError(String messageKey, BooleanSetting ignore) {
		System.err.println(messageKey + ": " + ignore);
	}

	public void showError(String messageKey, String message) {
		System.err.println(messageKey + ": " + message);
	}

	public void showError(String messageKey, String message,
			BooleanSetting ignore) {
		System.err.println(messageKey + ": " + message + ": " + ignore);
	}

	public void showMessage(String messageKey) {
		System.err.println(messageKey);
	}

	public void showMessage(String messageKey, BooleanSetting ignore) {
		System.err.println(messageKey + ": " + ignore);
	}

}