#include "ossmixerwindow.h"
#include "ossdevicewidget.h"
#include "osstray.h"
#include "../preferencesdlg.h"
#include "../../model/ossmodel.h"
#include "../../model/ossdevice.h"

#include <tqlayout.h>
#include <tqcombobox.h>
#include <tqtabwidget.h>
#include <tqlabel.h>
#include <tqwidgetstack.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>

OssMixerWindow::OssMixerWindow( OssModel *model, TQWidget *parent )
    : TDEMainWindow(parent, "OssMixerWindow"),
      m_model(model), m_tray(0), m_posRestored(false),
      m_outerStack(0), m_errorLabel(0),
      m_cardCombo(0), m_tabs(0), m_outputPage(0), m_inputPage(0),
      m_outputLayout(0), m_inputLayout(0)
{
    m_widgets.setAutoDelete(true);
    setCaption(i18n("Volume Control"));

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

    m_outerStack = new TQWidgetStack(central);
    vbox->addWidget(m_outerStack, 1);

    // Page 0: normal mixer content
    TQWidget *mixerPage = new TQWidget(m_outerStack);
    TQVBoxLayout *mixerLayout = new TQVBoxLayout(mixerPage, 8, 6);

    TQHBoxLayout *topRow = new TQHBoxLayout(0, 0, 6);
    topRow->addStretch();
    topRow->addWidget(new TQLabel(i18n("Card:"), mixerPage));
    m_cardCombo = new TQComboBox(false, mixerPage);
    TQValueList<OssCard> cards = model->cards();
    for ( TQValueListConstIterator<OssCard> it = cards.begin(); it != cards.end(); ++it )
        m_cardCombo->insertItem((*it).name);
    topRow->addWidget(m_cardCombo);
    mixerLayout->addLayout(topRow);

    m_tabs = new TQTabWidget(mixerPage);

    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"));

    mixerLayout->addWidget(m_tabs, 1);
    m_outerStack->addWidget(mixerPage, 0);

    // Page 1: error page
    TQWidget *errorPage = new TQWidget(m_outerStack);
    TQVBoxLayout *errorLayout = new TQVBoxLayout(errorPage, 8, 6);
    m_errorLabel = new TQLabel(errorPage);
    m_errorLabel->setAlignment(TQt::AlignCenter | TQt::WordBreak);
    errorLayout->addWidget(m_errorLabel);
    m_outerStack->addWidget(errorPage, 1);

    if ( model->lastError().isEmpty() ) {
        m_outerStack->raiseWidget(0);
        if ( !cards.isEmpty() )
            rebuildTabs(cards.front().index);
    } else {
        m_errorLabel->setText(i18n("Could not open OSS mixer:\n%1").arg(model->lastError()));
        m_outerStack->raiseWidget(1);
    }

    setMinimumSize(400, 250);

    TDEConfig *gcfg = TDEGlobal::config();
    gcfg->setGroup("OssMainWindow");
    if ( gcfg->hasKey("Width") )
        applyMainWindowSettings(gcfg, "OssMainWindow");
    else
        resize(550, 320);

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

    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 OssMixerWindow::rebuildTabs( int cardIdx )
{
    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<OssDevice> devs = m_model->devicesForCard(cardIdx);
    bool hasOutput = false, hasInput = false;
    for ( TQPtrListIterator<OssDevice> it(devs); *it; ++it ) {
        OssDevice *dev = *it;
        OssDeviceWidget *w = new OssDeviceWidget(dev,
            dev->category() == OssDevice::Output ? m_outputPage : m_inputPage);
        if ( dev->category() == OssDevice::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();
}

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

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

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

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

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

    if ( m_tray ) { hide(); return false; }
    quit();
    return false;
}

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

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

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

#include "ossmixerwindow.moc"
