/***************************************************************************
                          dockwidget.cpp  -  description
                             -------------------
    begin                : Thu Jul 6 2000
    copyright            : (C) 2000-2003 by Ian Reinhart Geiser
                         : (C) 2002-2003 Nadeem Hasan <nhasan@kde.org>
    email                : geiseri@msoe.edu
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "dockwidget.h"

#include <qtooltip.h>
#include <qimage.h>
#include <qvbox.h>
#include <qlabel.h>
#include <qpainter.h>
#include <qtimer.h>

#include <kapplication.h>
#include <kcursor.h>
#include <kdebug.h>
#include <kglobalsettings.h>
#include <kiconeffect.h>
#include <kicontheme.h>
#include <kipc.h>
#include <klocale.h>
#include <kstandarddirs.h>

WeatherButton::WeatherButton( QWidget *parent, const char *name )
    : QButton( parent, name ), m_highlight( false )
{
    setBackgroundOrigin( AncestorOrigin );

    connect( kapp, SIGNAL( settingsChanged( int ) ),
       SLOT( slotSettingsChanged( int ) ) );
    connect( kapp, SIGNAL( iconChanged( int ) ),
       SLOT( slotIconChanged( int ) ) );

    kapp->addKipcEventMask( KIPC::SettingsChanged );
    kapp->addKipcEventMask( KIPC::IconChanged );

    slotSettingsChanged( KApplication::SETTINGS_MOUSE );
}

void WeatherButton::drawButton( QPainter *p )
{
    if ( isDown() || isOn() )
    {
        p->setPen( Qt::black );
        p->drawLine( 0, 0, width()-1, 0 );
        p->drawLine( 0, 0, 0, height()-1 );
        p->setPen( colorGroup().light() );
        p->drawLine( 0, height()-1, width()-1, height()-1 );
        p->drawLine( width()-1, 0, width()-1, height()-1 );
    }

    drawButtonLabel( p );
}

void WeatherButton::drawButtonLabel( QPainter *p )
{
    if ( pixmap() )
    {
        QPixmap pix = m_highlight? m_activeIcon : m_normalIcon;

        if ( isOn() || isDown() )
            p->translate( 2, 2 );

        p->drawPixmap( pixmapOrigin(), pix );
    }
}

void WeatherButton::setPixmap( const QPixmap &pix )
{
    QButton::setPixmap( pix );
    generateIcons();
}

void WeatherButton::generateIcons()
{
    if ( !pixmap() )
        return;

    QImage image = pixmap()->convertToImage();
    image = image.smoothScale( pixmapSize(), QImage::ScaleMin );

    KIconEffect effect;

    m_normalIcon = effect.apply( image, KIcon::Panel, KIcon::DefaultState );
    m_activeIcon = effect.apply( image, KIcon::Panel, KIcon::ActiveState );
}

void WeatherButton::slotSettingsChanged( int category )
{
    if ( category != KApplication::SETTINGS_MOUSE ) return;

    bool changeCursor = KGlobalSettings::changeCursorOverIcon();

    if ( changeCursor )
        setCursor( KCursor::handCursor() );
    else
        unsetCursor();
}

void WeatherButton::slotIconChanged( int group )
{
    if ( group != KIcon::Panel )
        return;

    generateIcons();
    repaint( false );
}

void WeatherButton::enterEvent( QEvent *e )
{
    m_highlight = true;

    repaint( false );
    QButton::enterEvent( e );
}

void WeatherButton::leaveEvent( QEvent *e )
{
    m_highlight = false;

    repaint( false );
    QButton::enterEvent( e );
}

void WeatherButton::resizeEvent( QResizeEvent * )
{
    generateIcons();
}

QPoint WeatherButton::pixmapOrigin() const
{
    QSize point = margin()/2;
    QPoint origin( point.width(), point.height() );

    return origin;
}

dockwidget::dockwidget(const QString &location, QWidget *parent,
        const char *name) : QWidget(parent,name), m_locationCode( location )
{
    initDock();
    connect(m_button, SIGNAL( clicked() ), SIGNAL( buttonClicked() ));

    m_weatherService = new DCOPRef( "KWeatherService", "WeatherService" );
    m_font = KGlobalSettings::generalFont();

    setBackgroundOrigin( AncestorOrigin );
}

dockwidget::~dockwidget(){
    delete m_weatherService;
}

DCOPReply dockwidget::callDCOP( const QString &name )
{
    QStringList result;
    QCString function = QString( "%1(QString)" ).arg( name ).local8Bit();
    DCOPReply reply =  m_weatherService->call( function, m_locationCode );

    return reply;
}

void dockwidget::setViewMode(int _mode)
{
    kdDebug(12004) << "View mode " << _mode << endl;
    m_mode = _mode;
    if (m_mode == ShowIconOnly)
    {
        m_lblTemp->hide();
        m_lblWind->hide();
        m_lblPres->hide();
    }
    else if (m_mode == ShowTempOnly)
    {
        m_lblTemp->show();
        m_lblWind->hide();
        m_lblPres->hide();
    }
    else if (m_mode == ShowAll)
    {
        m_lblTemp->show();
        m_lblWind->show();
        m_lblPres->show();
    }
}

void dockwidget::showWeather()
{
    QString tip;

    QString temp = callDCOP( "temperature" );
    QString wind = callDCOP( "wind" );
    QString pressure = callDCOP( "pressure" );
    QPixmap icon = callDCOP( "icon" );

    if (m_mode == ShowIconOnly)
    {
        tip = i18n("Temperature: ") + temp;
        tip += i18n("\nWind: ") + wind;
        tip += i18n("\nAir Pressure: ") + pressure;
    }
    else
    {
        tip = i18n("Click here to see\nthe weather report...");
    }

    QToolTip::remove(m_button);
    QToolTip::add(m_button, tip);

    m_lblTemp->setText(temp);
    m_lblWind->setText(wind);
    m_lblPres->setText(pressure);

    m_button->setPixmap( icon );
}

void dockwidget::initDock(){
    kdDebug(12004) << "Init dockwidget " << endl;

    m_button= new WeatherButton(this,"m_button");

    m_lblTemp= new QLabel(this,"lblTemp");
    m_lblWind= new QLabel(this,"lblWind");
    m_lblPres= new QLabel(this,"lblPres");

    m_lblTemp->setBackgroundOrigin(AncestorOrigin);
    m_lblWind->setBackgroundOrigin(AncestorOrigin);
    m_lblPres->setBackgroundOrigin(AncestorOrigin);

    m_lblTemp->setMargin(0);
    m_lblWind->setMargin(0);
    m_lblPres->setMargin(0);

    updateFont();

    QTimer::singleShot( 0, this, SLOT( showWeather() ) );
}

/** resize the view **/
void dockwidget::resizeView( const QSize &size )
{
    kdDebug(12004) << "Changing to size " << size << endl;
    resize(size);

    int w = size.width();
    int h = size.height();

    if (w >= h)
    {
		// Kicker in horizontal mode
		if( m_mode == ShowAll)
		{
			m_lblTemp->setGeometry(h+1, 0, w-h, h/3);
			m_lblWind->setGeometry(h+1, h/3, w-h, h/3);
			m_lblPres->setGeometry(h+1, 2*h/3, w-h, h/3);
		}
		else if ( m_mode == ShowTempOnly)
		{
			m_lblTemp->setGeometry(h+1, 0, w-h, h);
		}
		m_button->setGeometry(0, 0, h, h );
	}
	else
	{
		// Kicker in vertical mode
		if( m_mode == ShowAll)
		{
			m_lblTemp->setGeometry(0, w, w, w/3);
			m_lblWind->setGeometry(0, 4*w/3, w, w/3);
			m_lblPres->setGeometry(0, 5*w/3, w, w/3);
		}
		else if ( m_mode == ShowTempOnly)
		{
			m_lblTemp->setGeometry(1, w, w, h-(w+1) );
		}
		m_button->setGeometry(0, 0, w, w );
    }
    updateFont();
}

int dockwidget::widthForHeight(int h)
{
	int w=h;
	QFontMetrics fm(m_font);

	if( m_mode == ShowAll)
	{
		m_font.setPixelSize( h/3-2 );
		w = h + QMAX(fm.width(m_lblWind->text()),
			fm.width(m_lblPres->text())) + 1;
	}
	else if ( m_mode == ShowTempOnly)
	{
		m_font.setPixelSize( h );
		w = h + fm.width(m_lblTemp->text()) + 1;
	}

	updateFont();
	return w;
}

int dockwidget::heightForWidth( int w )
{
    int h;
    // Adjust the height of the font to compensate for width
    int startSize = w;
    int width = w + 1;
    if ( m_mode == ShowAll )
    {
       while( (width > w)  && (startSize > 0))
       {
   	   m_font.setPixelSize( --startSize );
           QFontMetrics fm(m_font);
	   width = QMAX(fm.width(m_lblWind->text()),
                        fm.width(m_lblPres->text()));
       }
       h = ( w * 2 );
    }
    else if ( m_mode == ShowTempOnly )
    {
       while( (width > w)  && (startSize > 0))
       {
   	   m_font.setPixelSize( --startSize );
           QFontMetrics fm(m_font);
	   width = fm.width(m_lblTemp->text());
       }
       h = w + startSize + 2;
    }
    else
        h = w;

    updateFont();
    return h;
}


void dockwidget::updateFont()
{
    kdDebug(12004) << "Update font: " << m_font.pixelSize() << endl;
    m_lblTemp->setFont(m_font);
    m_lblWind->setFont(m_font);
    m_lblPres->setFont(m_font);
}

#include "dockwidget.moc"

// vim:ts=4:sw=4:et
