/*
 *
 * $Id: krootpixmap.cpp,v 1.20 2003/06/01 01:49:31 hadacek Exp $
 *
 * This file is part of the KDE project, module tdeui.
 * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
 *
 * You can Freely distribute this program under the GNU Library
 * General Public License. See the file "COPYING.LIB" for the exact
 * licensing terms.
 */
 
/* Modified by Sascha Hlusiak */
/* Further modified 11/18/2014 by Timothy Pearson <kb9vqf@pearsoncomputing.net> */

#include <tqwidget.h>
#include <tqtimer.h>
#include <tqrect.h>
#include <tqimage.h>

#ifndef TQ_WS_TQWS //FIXME
#include <tdeapplication.h>
#include <kimageeffect.h>
#include <kpixmapio.h>
#include <netwm.h>
#include <twin.h>
#include <kdebug.h>
#include <netwm.h>
#include <dcopclient.h>
#include <dcopref.h>
#include <tqpainter.h>

#include <ksharedpixmap.h>
#include "myrootpixmap.h"

static TQString wallpaperForDesktop(int desktop)
{
    return DCOPRef("kdesktop", "KBackgroundIface").call("currentWallpaper", desktop);
}

DesktopWallpaperWatcher::DesktopWallpaperWatcher() : TQWidget(), m_old_current_desktop(-1)
{
	kapp->installX11EventFilter( this );
	(void ) kapp->desktop(); //trigger desktop widget creation to select root window events
}

DesktopWallpaperWatcher::~DesktopWallpaperWatcher()
{
}

bool DesktopWallpaperWatcher::x11Event( XEvent * ev )
{
	if ( ev->xany.window == tqt_xrootwin() ) {
		NETRootInfo rinfo( tqt_xdisplay(), NET::CurrentDesktop );
		rinfo.activate();

		if ( rinfo.currentDesktop() != m_old_current_desktop ) {
			emit currentDesktopChanged( rinfo.currentDesktop() );
		}

		m_old_current_desktop = rinfo.currentDesktop();
	}

	return false;
}

class KMyRootPixmapData
{
public:
#ifdef Q_WS_X11
    DesktopWallpaperWatcher *twin;
#endif
};

KMyRootPixmap::KMyRootPixmap( TQWidget * widget, const char *name )
    : TQObject(widget, name ? name : "KMyRootPixmap" ) 
{
    init();
}

KMyRootPixmap::KMyRootPixmap( TQWidget *, TQObject *parent, const char *name )
    : TQObject( parent, name ? name : "KMyRootPixmap" ) 
{
    init();
}

void KMyRootPixmap::init()
{
    d = new KMyRootPixmapData;
//    m_Fade = 0;
    m_pPixmap = new TDESharedPixmap;
//    m_pTimer = new TQTimer( this );
    m_bInit = false;
    m_bActive = false;
    m_Desk=-1;
//    m_bCustomPaint = false;

//    connect(kapp, TQT_SIGNAL(backgroundChanged(int)), TQT_SLOT(slotBackgroundChanged(int)));
    connect(m_pPixmap, TQT_SIGNAL(done(bool)), TQT_SLOT(slotDone(bool)));
//    connect(m_pTimer, TQT_SIGNAL(timeout()), TQT_SLOT(repaint()));

#ifdef Q_WS_X11
    d->twin = new DesktopWallpaperWatcher();
    connect(d->twin, TQT_SIGNAL(currentDesktopChanged(int)), TQT_SLOT(desktopChanged(int)));
#endif

//    d->toplevel = m_pWidget->topLevelWidget();
//    d->toplevel->installEventFilter(this);
}

KMyRootPixmap::~KMyRootPixmap()
{
    delete m_pPixmap;
    delete d;
}

void KMyRootPixmap::desktopChanged(int desktop)
{
    if (wallpaperForDesktop(m_Desk) == wallpaperForDesktop(desktop) &&
	!wallpaperForDesktop(m_Desk).isNull())
	return;

// #ifdef Q_WS_X11
//     if (KWin::windowInfo(m_pWidget->topLevelWidget()->winId()).desktop() == NET::OnAllDesktops &&
// 	pixmapName(m_Desk) != pixmapName(desktop))
// #endif
	repaint(true);
}

int KMyRootPixmap::currentDesktop() const
{
    NETRootInfo rinfo( tqt_xdisplay(), NET::CurrentDesktop );
    rinfo.activate();
    return rinfo.currentDesktop();
}

void KMyRootPixmap::start()
{
    if (m_bActive)
    return;

    m_bActive = true;
    enableExports();
    return;
//    if (m_bInit)
//    repaint(true);
}

void KMyRootPixmap::stop()
{
    m_bActive = false;
//    m_pTimer->stop();
}


void KMyRootPixmap::repaint()
{
    repaint(false);
}

void KMyRootPixmap::repaint(bool force)
{
//	printf("KMyRootPixmap::repaint(%s)\n",force?"true":"false");
    if ((!force) && (m_Desk==currentDesktop()))return;
    
    m_Desk = currentDesktop();

    if (!isAvailable())
    {
    	emit backgroundUpdated(NULL);
    }else{
    	// TDESharedPixmap will correctly generate a tile for us.
    	m_pPixmap->loadFromShared(pixmapName(m_Desk));
    	updateBackground( m_pPixmap );
    }
}

bool KMyRootPixmap::isAvailable() 
{
    return m_pPixmap->isAvailable(pixmapName(m_Desk));
}

TQString KMyRootPixmap::pixmapName(int desk) 
{
    TQString pattern = TQString("DESKTOP%1");
    int screen_number = DefaultScreen(tqt_xdisplay());
    if (screen_number) {
        pattern = TQString("SCREEN%1-DESKTOP").arg(screen_number) + "%1";
    }
    return pattern.arg( desk );
}


void KMyRootPixmap::enableExports()
{
//    kdDebug(270) << k_lineinfo << "activating background exports.\n";
    DCOPClient *client = kapp->dcopClient();
    if (!client->isAttached())
    client->attach();
    TQByteArray data;
    TQDataStream args( data, IO_WriteOnly );
    args << 1;

    TQCString appname( "kdesktop" );
    int screen_number = DefaultScreen(tqt_xdisplay());
    if ( screen_number )
        appname.sprintf("kdesktop-screen-%d", screen_number );

    client->send( appname, "KBackgroundIface", "setExport(int)", data );
}


void KMyRootPixmap::slotDone(bool success)
{
    if (!success)
    {
//    	kdWarning(270) << k_lineinfo << "loading of desktop background failed.\n";
    	return;
    }

    // We need to test active as the pixmap might become available
    // after the widget has been destroyed.
    if ( m_bActive )
    updateBackground( m_pPixmap );
}

void KMyRootPixmap::updateBackground( TDESharedPixmap *spm )
{
//	printf("KMyRootPixmap::updateBackground(%p)\n",spm);
    TQPixmap *px=spm;
    if (px->isNull() || px->width()==0 || px->height()==0) 
    {	// This is NOT an image, something went wrong, update to plain
    	emit backgroundUpdated(NULL);
	return;
    }
    KPixmapIO io;
    TQSize desktopsize(TQApplication::desktop()->width(),TQApplication::desktop()->height());
    
    if (px->rect().size()==desktopsize)
    {	// Image has already the right dimension, make a quick update
    	TQImage img = io.convertToImage(*spm);
    	emit backgroundUpdated(&img);
	return;  
    }else{	// we need to create a tiled pixmap and then the image to update
    	TQPixmap pix(desktopsize,spm->TQPixmap::depth());
    	TQPainter pufferPainter(&pix);
    
    	pufferPainter.drawTiledPixmap(pix.rect(),*spm);
    
    	pufferPainter.end();
    
    	TQImage img=io.convertToImage(pix);
    	emit backgroundUpdated(&img);
    }
}

#include "myrootpixmap.moc"
#endif