/*
 *   Copyright (C) 2006
 *   Siraj Razick <siraj@kdemail.net>
 *   PhobosK <phobosk@mail.kbfx.org>
 *   see Also AUTHORS
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Library General Public License version 2 as
 *   published by the Free Software Foundation
 *
 *   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 Library General Public
 *   License along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include <config.h>

#include "kbfxbutton.h"


bool KbfxButton::m_sizeHeight = TRUE;
int KbfxButton::m_size = 0;

KbfxButton::KbfxButton ( TQWidget * parent, const char *name) :
		TQLabel ( parent,name,TQt::WStaticContents | TQt::WNoAutoErase |TQt::WPaintDesktop )
{
	setLineWidth ( 0 );
	setScaledContents ( false );
	setAcceptDrops ( true );
	m_dcopClient = new DCOPClient ();
	m_dcopClient->attach ();
	m_fadeTime = ConfigInit().m_fadeTime;

	/* Init normal size first */
	m_kicker_auto_adjust = TRUE;
	loadSkins();
	m_kicker_auto_adjust = ConfigInit().m_ToolBarResize;

	m_toggle = false;
	TQTimer * timer = new TQTimer ( this,"Update Timer" );
	connect ( timer,TQT_SIGNAL ( timeout() ),this,TQT_SLOT ( update() ) );
	timer->start ( 25,false );

	fade_timer = new TQTimer ( this,"Fade Timer" );
	connect ( fade_timer,TQT_SIGNAL ( timeout() ),this,TQT_SLOT ( fade() ) );
}

KbfxButton::~KbfxButton()
{
}

void KbfxButton::loadSkins()
{
	TQImage _tmpHover, _tmpPressed, _tmpNormal;
	_tmpHover = ( KbfxPlasmaPixmapProvider::PixmapPathCheck ( ConfigInit ().m_KbfxHoverButtonPath ) ) ?
		TQImage ( ConfigInit ().m_KbfxHoverButtonPath )
		: TQImage ( ConfigInit ().m_KbfxHoverButtonPathDefault );
	_tmpPressed = ( KbfxPlasmaPixmapProvider::PixmapPathCheck ( ConfigInit ().m_KbfxPressedButtonPath ) ) ?
		TQImage ( ConfigInit ().m_KbfxPressedButtonPath )
		: TQImage ( ConfigInit ().m_KbfxPressedButtonPathDefault );
	_tmpNormal = ( KbfxPlasmaPixmapProvider::PixmapPathCheck ( ConfigInit ().m_KbfxNormalButtonPath ) ) ?
		TQImage ( ConfigInit ().m_KbfxNormalButtonPath )
		: TQImage ( ConfigInit ().m_KbfxNormalButtonPathDefault );

	TQSize _sizeNormal = _tmpNormal.size();
	_tmpHover = _tmpHover.smoothScale ( _sizeNormal, TQ_ScaleFree );
	_tmpPressed = _tmpPressed.smoothScale ( _sizeNormal, TQ_ScaleFree );


	if ( !m_kicker_auto_adjust )
	{
		if ( m_sizeHeight )
		{
			_tmpHover = _tmpHover.smoothScale ( _tmpHover.width(), m_size, TQ_ScaleMin );
			_tmpPressed = _tmpPressed.smoothScale ( _tmpPressed.width(), m_size, TQ_ScaleMin );
			_tmpNormal = _tmpNormal.smoothScale ( _tmpNormal.width(), m_size, TQ_ScaleMin );
		}
		else
		{
			_tmpHover = _tmpHover.smoothScale ( m_size, _tmpHover.height(), TQ_ScaleMin );
			_tmpPressed = _tmpPressed.smoothScale ( m_size, _tmpPressed.height(), TQ_ScaleMin );
			_tmpNormal = _tmpNormal.smoothScale ( m_size, _tmpNormal.height(), TQ_ScaleMin );
		}
	}
	m_over_skin = TQPixmap ( _tmpHover );
	m_normal_skin = TQPixmap ( _tmpNormal );
	m_pressed_skin = TQPixmap ( _tmpPressed );
	m_current_skin = m_normal_skin;
	this->resize ( m_current_skin.width(),m_current_skin.height() );
	this->repaint();
}

TQCString KbfxButton::findPanel()
{
	TQCString m_AppletPanel = TQCString ("kicker");
	QCStringList objects=m_dcopClient->remoteObjects("kicker");

	for( QCStringList::ConstIterator it = objects.begin();
		 it != objects.end();
		 ++it)
	{
		if ( (*it).contains ( "Panel" ) > 0 )
		{
			DCOPRef _dcop_obj ( "kicker", (*it) );
			TQStringList _dcop_obj_applets =_dcop_obj.call ( "listApplets()" );

			for ( TQStringList::Iterator _it = _dcop_obj_applets.begin();
				  _it != _dcop_obj_applets.end();
				  _it++ )
			{
				if ( ( *_it ).contains ( "kbfx" ) )
				{
					m_AppletPanel = (*it);
					break;
				}
			}
		}
	}
	kdDebug () << "KBFX resides on panel: " << m_AppletPanel << endl;
	return m_AppletPanel;
}

void KbfxButton::readjust( bool _how )
{
	/* _how = TRUE is for height, _how = FALSE is for width readjust */
	TQCString _panel = findPanel();
	int _tmp_size;
	if ( _how )
	{
		_tmp_size = this->height ();
		kdDebug () << "Readjusting " << _panel << " to height: " << _tmp_size << endl;
	}
	else
	{
		_tmp_size = this->width ();
		kdDebug () << "Readjusting " << _panel << " to width: " << _tmp_size << endl;
	}
	TQByteArray data;
	TQDataStream arg ( data, IO_WriteOnly );
	arg << _tmp_size ;
	if ( !m_dcopClient->send ( "kicker", _panel, "setPanelSize(int)", data ) )
		kdWarning ()
			<< "Could not send DCOP command to:"
			<< _panel
			<< endl;
}

void KbfxButton::enterEvent ( TQEvent * e )
{
	e = e;
	if ( m_toggle == true )
	{
//		m_current_skin = m_pressed_skin; // no fade code
		m_fadePix = m_pressed_skin;
	}
	else
	{
//		m_current_skin = m_over_skin; // no fade code
		m_fadePix = m_over_skin;

		emit showToolTip ();
	}
	fade();
}

void KbfxButton::fade ( )
{
	if ( m_fadeTime == 0 )
	{
		m_current_skin = m_fadePix;
	}
	else
	{
		TQImage _final = m_fadePix.convertToImage ();
		TQImage _current = m_current_skin.convertToImage ();

		if ( !fade_timer->isActive ())
		{
			m_opacity = 0;
			fade_timer->start( m_fadeTime, false);
		}
		if ( m_opacity > 0.9 )
			fade_timer->stop();
		m_opacity += 0.1;

		KImageEffect::blend   ( _final, _current, m_opacity);
		m_current_skin = TQPixmap ( _current );
 }
	this->resize ( m_current_skin.size() );
	this->update();
}

void KbfxButton::leaveEvent ( TQEvent * e )
{
	e = e;

	if ( m_toggle )
	{
//		m_current_skin = m_pressed_skin; // no fade code
		m_fadePix = m_pressed_skin;
	}
	else
	{
//		m_current_skin = m_normal_skin; // no fade code
		m_fadePix = m_normal_skin;
	}
	fade();
	emit leave ();
}

void KbfxButton::toggle()
{
        if (this->hasMouse() ) {
            m_fadePix = m_over_skin;
        }else {

               m_fadePix = m_normal_skin;
               m_toggle = false;
        }
		fade();
}

void KbfxButton::toggleKMenu()
{
//	m_current_skin = m_normal_skin;
	m_fadePix = m_normal_skin;
	fade();
	m_toggle = false;
}

void KbfxButton::mousePressEvent ( TQMouseEvent * e )
{
	e->accept();
	if ( e->button() == Qt::LeftButton )
	{
		if ( m_toggle == false )
		{
//			m_current_skin = m_pressed_skin; // no fade code
			m_toggle = true;
			m_fadePix = m_pressed_skin;
			fade();
			emit pressed();
		}
		else
		{
//			m_current_skin = m_normal_skin; // no fade code
			m_toggle = false;
                        if (hasMouse() ) {
                            m_fadePix = m_over_skin;
                        }else {

			    m_fadePix = m_normal_skin;
                        }

			fade();
			emit hideMenu();
		}
		emit clicked ();
	}

	if ( e->button() == Qt::RightButton )
	{
		m_fadePix = m_normal_skin;
		fade();
		m_toggle = false;

		TQPopupMenu *popup = new TQPopupMenu();

		popup->insertItem ( SmallIcon ( "remove" ), i18n ( "Remove KBFX from Pannel" ),
							this, TQT_SLOT ( selfDeleter() ) );
		popup->insertItem ( SmallIcon ( "reload" ),i18n ( "Reload KBFX" ),
							this, TQT_SLOT ( reloadConfig() ) );
		popup->insertSeparator();
		popup->insertItem ( SmallIcon ( "kbfxconfigapp" ), i18n ( "Configure KBFX" ),
							this, TQT_SLOT ( openConfigDialog() ) );
		popup->insertItem ( SmallIcon ( "kmenuedit" ),i18n ( "Edit Applications Menu" ),
							this, TQT_SLOT ( openKmenuEdit() ) );
		popup->exec ( e->globalPos() );
		delete popup;
	}
}

void KbfxButton::reloadConfig()
{
/*
	DCOPRef m_kickerkbfxDevelnterface ( "kicker","KBFXInterface" );
	m_kickerkbfxDevelnterface.call ( "notifyConfigChange()" );
	m_kickerkbfxDevelnterface.call ( "notifyConfigChange()" );
*/

	DCOPRef m_kickerPanel("kicker", findPanel());
	m_kickerPanel.call("restart()");
}

void KbfxButton::selfDeleter()
{
	DCOPRef m_kickerPanel ( "kicker", findPanel() );
	TQStringList returnTQStringList =m_kickerPanel.call ( "listApplets()" );
	int _myIndex = 0;

	TQStringList::Iterator it;

	for ( it = returnTQStringList.begin();it != returnTQStringList.end();it++ )
	{
		if ( ( *it ).contains ( "kbfx" ) )
		{
			break;
		}
		else
			_myIndex++;
	}

	m_kickerPanel.call ( "removeApplet(int)", _myIndex );
}

void KbfxButton::openKmenuEdit()
{
#ifdef HAVE_MANDRAKE
	KRun::runCommand ( "menudrake" );
#else
	KRun::runCommand ( "kmenuedit" );
#endif
}

void KbfxButton::openConfigDialog()
{
	KRun::runCommand ( "kbfxconfigapp" );
}

void KbfxButton::paintEvent ( TQPaintEvent * pe )
{

	TQPainter p;
	if ( !m_current_skin.isNull () )
	{
		TQRect r = TQRect ( pe->rect().x(),pe->rect().y(),m_current_skin.width(),m_current_skin.height() );
		m_buffer = new TQPixmap();
		m_buffer->resize ( r.size() );
		m_buffer->fill ( this, r.topLeft() );

		p.begin ( m_buffer,this );
		p.translate ( -r.x(), -r.y() );
		p.drawPixmap ( r,m_current_skin );
		p.end ();
		bitBlt ( this, r.x(), r.y(),m_buffer, 0, 0,m_current_skin.width(), m_current_skin.height() );
		delete m_buffer;
	}

}

void KbfxButton::dragEnterEvent ( TQDragEnterEvent * e )
{
	e->accept ( TQUriDrag::canDecode ( e ) );
	kdDebug() << "Accepting KBFX button drag..." << endl;
}

void KbfxButton::dropEvent ( TQDropEvent * e )
{
	TQStringList filelist;
	TQString _hover, _normal, _pressed, _tmp;
	TQImage _hover_pix, _normal_pix, _pressed_pix;
	TQUriDrag::decodeLocalFiles ( e, filelist );

	for ( TQStringList::Iterator it = filelist.begin(); it != filelist.end(); ++it )
	{
		_tmp = ( *it );
		kdDebug() << "KBFX button dropped file: " << _tmp << endl;
		if ( _tmp.contains ( "hover", FALSE ) > 0 )
		{
			_hover = _tmp;
			_hover_pix = TQImage ( _tmp );
		}
		if ( _tmp.contains ( "normal", FALSE ) > 0 )
		{
			_normal = _tmp;
			_normal_pix = TQImage ( _tmp );
		}
		if ( _tmp.contains ( "pressed", FALSE ) > 0 )
		{
			_pressed = _tmp;
			_pressed_pix = TQImage ( _tmp );
		}
	}

	kdDebug() << "KBFX button hover: " << _hover << endl
			  << "KBFX button normal: " << _normal << endl
			  << "KBFX button pressed: " << _pressed << endl;

	if ( _hover_pix.isNull () ||
	        _normal_pix.isNull () ||
	        _pressed_pix.isNull () )
	{
		KMessageBox::error ( 0,
		                     tr2i18n ( "Invalid images were dropped!"
		                               "\nCannot set the KBFX button to use these images!" ),
		                     tr2i18n ( "Error setting KBFX button images" ) );
		return;
	}

	ConfigInit ().m_KbfxNormalButtonPath = _normal;
	ConfigInit ().m_KbfxHoverButtonPath = _hover;
	ConfigInit ().m_KbfxPressedButtonPath = _pressed;
	ConfigInit().writeThemerc ( ConfigInit().m_SpinxThemeName );

	/* Init normal size first */
	m_kicker_auto_adjust = TRUE;
	loadSkins();
	m_kicker_auto_adjust = ConfigInit().m_ToolBarResize;
}

#include "kbfxbutton.moc"
