/*
 * KMix -- KDE's full featured mini mixer
 *
 *
 * Copyright (C) 2004 Christian Esken <esken@kde.org>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library 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
 * Library 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 <tqcursor.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqobject.h>
#include <tqslider.h>
#include <tqtooltip.h>

#include <tdelocale.h>
#include <tdeconfig.h>
#include <tdeaction.h>
#include <tdepopupmenu.h>
#include <kglobalaccel.h>
#include <kkeydialog.h>
#include <kdebug.h>

#include "kledbutton.h"
#include "mdwswitch.h"
#include "mixer.h"
#include "viewbase.h"
#include "verticaltext.h"

/**
 * Class that represents a single Switch
 * The orientation (horizontal, vertical) can be configured and whether it should
 * be "small"  (uses KSmallSlider instead of TQSlider then).
 */
MDWSwitch::MDWSwitch(Mixer *mixer, MixDevice* md,
                                 bool small, TQt::Orientation orientation,
                                 TQWidget* parent, ViewBase* mw, const char* name) :
    MixDeviceWidget(mixer,md,small,orientation,parent,mw,name),
    _label(0) , _labelV(0) , _switchLED(0), _layout(0)
{
    // create actions (on _mdwActions, see MixDeviceWidget)

    // KStdAction::showMenubar() is in MixDeviceWidget now
    new TDEToggleAction( i18n("&Hide"), 0, this, TQ_SLOT(setDisabled()), _mdwActions, "hide" );
    new TDEAction( i18n("C&onfigure Shortcuts..."), 0, this, TQ_SLOT(defineKeys()), _mdwActions, "keys" );

    // create widgets
    createWidgets();

    m_keys->insert( "Toggle switch", i18n( "Toggle Switch" ), TQString(),
		    TDEShortcut(), TDEShortcut(), this, TQ_SLOT( toggleSwitch() ) );

    // The keys are loaded in KMixerWidget::loadConfig, see kmixerwidget.cpp (now: kmixtoolbox.cpp)
    //m_keys->readSettings();
    //m_keys->updateConnections();

    installEventFilter( this ); // filter for popup
}

MDWSwitch::~MDWSwitch()
{
}


void MDWSwitch::createWidgets()
{
	if ( _orientation == TQt::Vertical ) {
		_layout = new TQVBoxLayout( this );
		_layout->setAlignment(TQt::AlignHCenter);
	}
	else {
		_layout = new TQHBoxLayout( this );
		_layout->setAlignment(TQt::AlignVCenter);
	}
	TQToolTip::add( this, m_mixdevice->name() );
	
	
	_layout->addSpacing( 4 );
	// --- LEDS --------------------------
	if ( _orientation == TQt::Vertical ) {
		if( m_mixdevice->isRecordable() )
		 _switchLED = new KLedButton( TQt::red,
				 m_mixdevice->isRecSource()?KLed::On:KLed::Off,
				 KLed::Sunken, KLed::Circular, this, "RecordLED" );
		else
		 _switchLED = new KLedButton( TQt::yellow, KLed::On, KLed::Sunken, KLed::Circular, this, "SwitchLED" );
		 _switchLED->setFixedSize(16,16); 
		 _labelV = new VerticalText( this, m_mixdevice->name().utf8().data() );
		 
		 _layout->addWidget( _switchLED );
		 _layout->addSpacing( 2 );
		 _layout->addWidget( _labelV );
		 
		 _switchLED->installEventFilter( this );
		 _labelV->installEventFilter( this );
	 }
	 else
	 {
		if( m_mixdevice->isRecordable() )
			_switchLED = new KLedButton( TQt::red,
					m_mixdevice->isRecSource()?KLed::On:KLed::Off,
					KLed::Sunken, KLed::Circular, this, "RecordLED" );
		else
		 _switchLED = new KLedButton( TQt::yellow, KLed::On, KLed::Sunken, KLed::Circular, this, "SwitchLED" );
		 _switchLED->setFixedSize(16,16);
		 _label  = new TQLabel(m_mixdevice->name(), this, "SwitchName");
		 
		 _layout->addWidget( _switchLED );
		 _layout->addSpacing( 1 );
		 _layout->addWidget( _label );
		 _switchLED->installEventFilter( this );
		 _label->installEventFilter( this );
	 }
    connect( _switchLED, TQ_SIGNAL(stateChanged(bool)), this, TQ_SLOT(toggleSwitch()) );
    _layout->addSpacing( 4 );
}

void MDWSwitch::update()
{
	if ( _switchLED != 0 ) {
		_switchLED->blockSignals( true );
		if( m_mixdevice->isRecordable() )
			_switchLED->setState( m_mixdevice->isRecSource() ? KLed::On : KLed::Off );
		else
			_switchLED->setState( m_mixdevice->isMuted() ? KLed::Off : KLed::On );
		
		_switchLED->blockSignals( false );
	}
}

void MDWSwitch::setBackgroundMode(BackgroundMode m)
{
    if ( _label != 0 ){
	_label->setBackgroundMode(m);
    }
    if ( _labelV != 0 ){
	_labelV->setBackgroundMode(m);
    }
    _switchLED->setBackgroundMode(m);
    MixDeviceWidget::setBackgroundMode(m);
}

void MDWSwitch::showContextMenu()
{
    if( m_mixerwidget == NULL )
	return;

    TDEPopupMenu *menu = m_mixerwidget->getPopup();

    TQPoint pos = TQCursor::pos();
    menu->popup( pos );
}

TQSize MDWSwitch::sizeHint() const {
    if ( _layout != 0 ) {
	return _layout->sizeHint();
    }
    else {
	// layout not (yet) created
	return TQWidget::sizeHint();
    }
}


/**
   This slot is called, when a user has clicked the mute button. Also it is called by any other
    associated TDEAction like the context menu.
*/
void MDWSwitch::toggleSwitch() {
	if( m_mixdevice->isRecordable() )
		setSwitch( !m_mixdevice->isRecSource() );
	else
		setSwitch( !m_mixdevice->isMuted() );
}

void MDWSwitch::setSwitch(bool value)
{
	if (  m_mixdevice->isSwitch() ) {
		if ( m_mixdevice->isRecordable() ) {
			m_mixer->setRecordSource( m_mixdevice->num(), value );
		}
		else {
			m_mixdevice->setMuted( value );
			m_mixer->commitVolumeChange( m_mixdevice );
		}
	}
}

void MDWSwitch::setDisabled()
{
    setDisabled( true );
}

void MDWSwitch::setDisabled( bool value ) {
    if ( m_disabled!=value)
    {
	value ? hide() : show();
	m_disabled = value;
    }
}

/**
 * An event filter for the various TQWidgets. We watch for Mouse press Events, so
 * that we can popup the context menu.
 */
bool MDWSwitch::eventFilter( TQObject* obj, TQEvent* e )
{
    if (e->type() == TQEvent::MouseButtonPress) {
	TQMouseEvent *qme = static_cast<TQMouseEvent*>(e);
	if (qme->button() == TQt::RightButton) {
	    showContextMenu();
	    return true;
	}
    }
    return TQWidget::eventFilter(obj,e);
}

#include "mdwswitch.moc"
