/*
 * newsiconmgr.cpp
 *
 * Copyright (c) 2001 Frerich Raabe <raabe@kde.org>
 *
 * 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. For licensing and distribution details, check the
 * accompanying file 'COPYING'.
 */
#include "newsiconmgr.h"

#include <dcopclient.h>

#include <kapplication.h>
#include <kiconloader.h>
#include <kstandarddirs.h>

#include <tqbuffer.h>
#include <tqfile.h>
#include <tqimage.h>

struct KIODownload
{
	KURL       url;
	TQByteArray data;
	TQIODevice::Offset dataOffset;
};

NewsIconMgr *NewsIconMgr::m_instance = 0;

NewsIconMgr *NewsIconMgr::self()
{
	if (!m_instance)
		m_instance = new NewsIconMgr();

	return m_instance;
}

NewsIconMgr::NewsIconMgr(TQObject *parent, const char *name)
	: TQObject(parent, name), DCOPObject("NewsIconMgr"),
	m_stdIcon(SmallIcon(TQString::fromLatin1("news")))
{
	connectDCOPSignal("kded",
			"favicons", "iconChanged(bool, TQString, TQString)",
			"slotGotIcon(bool, TQString, TQString)",
			false);
}

NewsIconMgr::~NewsIconMgr()
{
	delete m_instance;
}

void NewsIconMgr::getIcon(const KURL &url)
{
	if (url.isEmpty()) {
		emit gotIcon(url, m_stdIcon);
		return;
	}

	if (url.isLocalFile()) {
		if (TQFile::exists(url.encodedPathAndQuery())) {
			TQPixmap icon(url.encodedPathAndQuery());
			if (!icon.isNull()) {
				if (icon.size() != TQSize(16, 16)) {
					if (!icon.convertFromImage(icon.convertToImage().smoothScale(16, 16, TQ_ScaleMin))) {
						emit gotIcon(url, m_stdIcon);
						return;
					}
				}
				emit gotIcon(url, icon);
				return;
			}
		}
		emit gotIcon(url, m_stdIcon);
		return;
	}

	if (url.encodedPathAndQuery() == "/favicon.ico") {
		if (favicon(url).isNull()) {
			TQByteArray data;
			TQDataStream ds(data, IO_WriteOnly);
			ds << url;
			kapp->dcopClient()->send("kded", "favicons", "downloadHostIcon(KURL)", data);
		} else {
			emit gotIcon(url, TQPixmap(KGlobal::dirs()->findResource("cache",
							TQString::fromLatin1("favicons/%1.png").tqarg(url.host()))));
		}
	} else {
		KIO::Job *job = KIO::get(url, true, false);
		connect(job, TQT_SIGNAL(data(KIO::Job *, const TQByteArray &)),
				TQT_SLOT(slotData(KIO::Job *, const TQByteArray &)));
		connect(job, TQT_SIGNAL(result(KIO::Job *)), TQT_SLOT(slotResult(KIO::Job *)));
		
		KIODownload download;
		download.url = url;
		download.dataOffset = 0;
		m_kioDownload.insert(job, download);
	}
}

bool NewsIconMgr::isStdIcon(const TQPixmap &pixmap) const
{
	if (!pixmap.isNull())
		return pixmap.convertToImage() == m_stdIcon.convertToImage();
	else
		return false;
}

void NewsIconMgr::slotData(KIO::Job *job, const TQByteArray &data)
{
	TQBuffer buf(m_kioDownload[job].data);
	buf.open(IO_WriteOnly);
	buf.at(m_kioDownload[job].dataOffset);
	buf.writeBlock(data);
	m_kioDownload[job].dataOffset = buf.at();
}

void NewsIconMgr::slotResult(KIO::Job *job)
{
	emit gotIcon(m_kioDownload[job].url, TQPixmap(m_kioDownload[job].data));
	m_kioDownload.remove(job);
}

void NewsIconMgr::slotGotIcon(bool isHost, TQString hostOrURL, TQString iconName)
{
	KURL url = KURL(hostOrURL);
	if (!isHost)
		url.setProtocol(TQString::fromLatin1("http"));
	
	if (iconName.isNull())
		emit gotIcon(url, m_stdIcon);
	else
		emit gotIcon(url, TQPixmap(KGlobal::dirs()->findResource("cache",
						TQString::fromLatin1("favicons/%1.png").tqarg(url.host()))));
}

TQString NewsIconMgr::favicon(const KURL &url) const
{
	TQByteArray data, reply;
	TQCString replyType;
	TQDataStream ds(data, IO_WriteOnly);

	ds << url;
	
	kapp->dcopClient()->call("kded", "favicons", "iconForURL(KURL)", data, replyType, reply);
	
	if (replyType == TQSTRING_OBJECT_NAME_STRING) {
		TQDataStream replyStream(reply, IO_ReadOnly);
		TQString result;
		replyStream >> result;
		return result;
	}
	
	return TQString();
}

#include "newsiconmgr.moc"