#include "alsamixerwindow.h"
#include "alsadevicewidget.h"
#include "alsadevicespage.h"
#include "alsatray.h"
#include "../preferencesdlg.h"
#include "../../model/alsamodel.h"
#include "../../model/alsadevice.h"

#include <tqlayout.h>
#include <tqcombobox.h>
#include <tqtabwidget.h>
#include <tqlabel.h>
#include <tqhbox.h>
#include <tdeapplication.h>
#include <tdelocale.h>
#include <tdemenubar.h>
#include <tdepopupmenu.h>
#include <tdeaboutapplication.h>
#include <tdeaboutdata.h>
#include <kiconloader.h>
#include <tdeconfig.h>
#include <tdeglobal.h>
#include <twin.h>

AlsaMixerWindow::AlsaMixerWindow( AlsaModel *model, TQWidget *parent )
    : TDEMainWindow(parent, "AlsaMixerWindow"),
      m_model(model), m_tray(0), m_posRestored(false), m_devicesPage(0)
{
    m_widgets.setAutoDelete(true);
    setCaption( i18n("Volume Control") );

    TQWidget *central = new TQWidget(this);
    setCentralWidget(central);
    TQVBoxLayout *vbox = new TQVBoxLayout(central, 8, 6);

    // card selector row — right aligned
    TQHBoxLayout *topRow = new TQHBoxLayout(0, 0, 6);
    topRow->addStretch();
    topRow->addWidget( new TQLabel(i18n("Card:"), central) );
    m_cardCombo = new TQComboBox(false, central);
    TQValueList<AlsaCard> cards = model->cards();
    for ( TQValueListConstIterator<AlsaCard> it = cards.begin(); it != cards.end(); ++it )
        m_cardCombo->insertItem( (*it).name );
    topRow->addWidget(m_cardCombo);
    vbox->addLayout(topRow);

    // tabs
    m_tabs = new TQTabWidget(central);

    m_outputPage = new TQWidget(m_tabs);
    m_outputLayout = new TQHBoxLayout(m_outputPage, 8, 6);
    m_tabs->addTab(m_outputPage, i18n("Output"));

    m_inputPage = new TQWidget(m_tabs);
    m_inputLayout = new TQHBoxLayout(m_inputPage, 8, 6);
    m_tabs->addTab(m_inputPage, i18n("Input"));

    m_devicesPage = new AlsaDevicesPage(model, m_tabs);
    m_tabs->addTab(m_devicesPage, i18n("Device Settings"));

    vbox->addWidget(m_tabs, 1);

    if ( !cards.isEmpty() )
        rebuildTabs( cards.front().index );

    setMinimumSize( 400, 250 );

    TDEConfig *gcfg = TDEGlobal::config();
    gcfg->setGroup("AlsaMainWindow");
    if ( gcfg->hasKey("Width") )
        applyMainWindowSettings( gcfg, "AlsaMainWindow" );
    else
        resize( 650, 380 );

    connect(m_cardCombo, TQ_SIGNAL(activated(int)), this, TQ_SLOT(onCardChanged(int)));
    connect(model, TQ_SIGNAL(deviceAdded(AlsaDevice*)), this, TQ_SLOT(onDeviceAdded(AlsaDevice*)));

    TDEPopupMenu *fileMenu = new TDEPopupMenu(this);
    fileMenu->insertItem( SmallIcon("application-exit"), i18n("&Quit"),
                          this, TQ_SLOT(quit()) );

    TDEPopupMenu *settingsMenu = new TDEPopupMenu(this);
    settingsMenu->insertItem( SmallIcon("configure"), i18n("&Configure..."),
                              this, TQ_SLOT(showPreferences()) );

    TDEPopupMenu *helpMenu = new TDEPopupMenu(this);
    helpMenu->insertItem( SmallIcon("help"), i18n("&About TMix"),
                          this, TQ_SLOT(showAbout()) );

    menuBar()->insertItem( i18n("&File"),     fileMenu     );
    menuBar()->insertItem( i18n("&Settings"), settingsMenu );
    menuBar()->insertItem( i18n("&Help"),     helpMenu     );
}

void AlsaMixerWindow::rebuildTabs( int cardIndex )
{
    m_widgets.clear();

    delete m_outputPage->layout();
    m_outputLayout = new TQHBoxLayout(m_outputPage, 8, 6);

    delete m_inputPage->layout();
    m_inputLayout = new TQHBoxLayout(m_inputPage, 8, 6);

    TQPtrList<AlsaDevice> devs = m_model->devicesForCard(cardIndex);
    bool hasOutput = false, hasInput = false;
    for ( TQPtrListIterator<AlsaDevice> it(devs); *it; ++it ) {
        AlsaDevice *dev = *it;
        if ( dev->type() != AlsaDevice::Slider ) continue;

        AlsaDeviceWidget *w = new AlsaDeviceWidget(dev,
            dev->category() == AlsaDevice::Output ? m_outputPage : m_inputPage);
        if ( dev->category() == AlsaDevice::Output ) {
            m_outputLayout->addWidget(w);
            hasOutput = true;
        } else {
            m_inputLayout->addWidget(w);
            hasInput = true;
        }
        w->show();
        m_widgets.append(w);
    }

    if ( !hasOutput ) m_outputLayout->addWidget( new TQLabel(i18n("No output controls."), m_outputPage) );
    if ( !hasInput  ) m_inputLayout->addWidget(  new TQLabel(i18n("No input controls."),  m_inputPage)  );

    m_outputLayout->addStretch();
    m_inputLayout->addStretch();

    if ( m_devicesPage )
        m_devicesPage->setCard(cardIndex);
}

void AlsaMixerWindow::onCardChanged( int idx )
{
    TQValueList<AlsaCard> cards = m_model->cards();
    if ( idx < 0 || idx >= (int)cards.count() ) return;
    TQValueListConstIterator<AlsaCard> it = cards.begin();
    for ( int i = 0; i < idx; ++i ) ++it;
    rebuildTabs( (*it).index );
}

void AlsaMixerWindow::onDeviceAdded( AlsaDevice * )
{
    m_cardCombo->clear();
    TQValueList<AlsaCard> cards = m_model->cards();
    for ( TQValueListConstIterator<AlsaCard> it = cards.begin(); it != cards.end(); ++it )
        m_cardCombo->insertItem( (*it).name );
    onCardChanged( m_cardCombo->currentItem() );
}

void AlsaMixerWindow::bringToFront()
{
    show();
    KWin::forceActiveWindow( winId() );
}

void AlsaMixerWindow::showEvent( TQShowEvent *e )
{
    TDEMainWindow::showEvent(e);
    if ( !m_posRestored ) {
        m_posRestored = true;
        TDEConfig *cfg = TDEGlobal::config();
        cfg->setGroup("AlsaMainWindow");
        int xp = cfg->readNumEntry("XPos", -1);
        int yp = cfg->readNumEntry("YPos", -1);
        if ( xp >= 0 && yp >= 0 )
            move( xp, yp );
    }
}

bool AlsaMixerWindow::queryClose()
{
    saveMainWindowSettings( TDEGlobal::config(), "AlsaMainWindow" );
    TDEConfig *cfg = TDEGlobal::config();
    cfg->setGroup("AlsaMainWindow");
    cfg->writeEntry("XPos", x());
    cfg->writeEntry("YPos", y());
    cfg->sync();

    if ( m_tray ) { hide(); return false; }
    // Not in systray — closing the window means quit.
    quit();
    return false;
}

void AlsaMixerWindow::quit()
{
    m_tray = 0;
    tdeApp->quit();
}

void AlsaMixerWindow::showPreferences()
{
    PreferencesDlg dlg( m_model, this );
    dlg.exec();
    emit settingsChanged();
}

void AlsaMixerWindow::showAbout()
{
    TDEAboutApplication dlg(this);
    dlg.exec();
}

#include "alsamixerwindow.moc"
