/*
 * Copyright (C) 2002 Richard Moore <rich@kde.org>
 *               2004 Dirk Ziegelmeier <dziegel@gmx.de>
 *
 *   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 <qslider.h>

#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
#include <kaction.h>
#include <kiconloader.h>

#include "actions.h"
#include "kdetv.h"
#include "channel.h"
#include "sourcemanager.h"
#include "volumecontroller.h"
#include "kdetvwidget.h"

#include "libkdetvactions.h"
#include "libkdetvactions.moc"

LibKdetvActions::LibKdetvActions( Kdetv *kdetv, const char *name )
    : QObject( kdetv, name ? name : "kdetv_actions" ),
      ktv(kdetv )
{
    connect(ktv->sourceManager(), SIGNAL(deviceChanged(const QString&)),
            this, SLOT( deviceChanged(const QString&)));
    connect(ktv->sourceManager(), SIGNAL(audioModeChanged(const QString&)),
            this, SLOT( checkAudioMode(const QString&)));

    _devicesActionList.setAutoDelete(true);
    _audioModeActionList.setAutoDelete(true);
}

LibKdetvActions::~LibKdetvActions()
{
}

void LibKdetvActions::createActions( KActionCollection *acts )
{
    // Standard Actions
    showSettings = KStdAction::preferences( ktv, SLOT( settings() ), acts );

    showKeys = KStdAction::keyBindings( this, SIGNAL( launchBindings() ), acts);

    // Application Actions
    chanLoadDefaults = new KAction( i18n("&Local Defaults..."), "1leftarrow", 0, ktv,
                                    SLOT( importDefault() ), acts,
                                    "channel_load_defaults" );

    chanImportLegacy = new KAction( i18n("Old &KWinTV Channels"), "1leftarrow", 0, ktv,
                                    SLOT( importLegacyChannels() ), acts,
                                    "channel_import_legacy" );

    ctrl = new KAction( i18n("&Video Hardware Controls"), "hwinfo", 0, ktv,
                        SLOT( controls() ), acts, "controls" );

    fltChainStatus = new KAction( i18n("&Filter Chain Status"), "filter", 0, ktv,
                                  SLOT( filterChainStatus() ), acts, "filter_chain_status" );

    chanDown = new KAction( i18n("Channel &Down"), "down", Key_Down, ktv,
                            SLOT( channelDown() ), acts, "channel_down" );

    chanUp = new KAction( i18n("Channel &Up"), "up", Key_Up, ktv,
                          SLOT( channelUp() ), acts, "channel_up" );

    chanWiz = new KAction( i18n("Channel &Wizard"), "wizard", 0,
                           ktv, SLOT( launchWizard() ), acts,
                           "channel_wizard" );

    chanEdit = new KAction( i18n("Channel &Editor"), "edit", 0,
                            ktv, SLOT( editChannels() ), acts,
                            "channel_editor" );

    snap = new KAction( i18n("Save &Snapshot"), "camera", Key_S,
                        ktv, SLOT( snapshot() ), acts, "save_snapshot" );

    volMute = new KToggleAction( i18n("Mute"), "player_mute", Key_Asterisk,
                                 ktv, SLOT( toggleMute() ), acts,
                                 "volume_mute" );

    volUp = new KAction( i18n("Volume Up"), "player_volume_up", Key_Right,
                         ktv, SLOT( volumeUp() ), acts, "volume_up" );

    volDown = new KAction( i18n("Volume Down"), "player_volume_down", Key_Left,
                           ktv, SLOT( volumeDown() ),
                           acts, "volume_down" );

    prevChannel = new KAction( i18n("Previous Channel"), "back", Key_L,
                               ktv, SLOT( previousChannel() ), acts,
                               "last_channel" );

    // Custom Actions
    chan = new LCDNumberAction( i18n("Current Channel"), 0, 0, 0, acts,
                                "channel_number" );
    chan->setNumDigits( 3 );
    chan->setIcon("kdetv");

    connect(ktv, SIGNAL(channelChanged(int)),
            chan, SLOT(display(int)) );

    /*
     * This is confusing in configure toolbars dialog
     connect( ktv, SIGNAL(channelChanged(const QString &)), chan,
     SLOT(setText(const QString &)) );
    */

    volSlider = new SliderAction( 0, 100, 1, 50, i18n("Volume"), acts,
                                  "volume_slider" );
    volSlider->setTickInterval( 5 );
    volSlider->setIcon("kcmsound");

    connect(volSlider, SIGNAL(valueChanged(int)),
            ktv, SLOT(setVolume(int)));
    connect(ktv->volumeController(), SIGNAL(volumeChanged(int)),
            this, SLOT(updateSlider(int)));
    connect(ktv->volumeController(), SIGNAL(muted(bool)),
            this, SLOT(updateMuteButton(bool)));
}

const QPtrList<KAction>& LibKdetvActions::devicesActionList( KActionCollection *acts )
{
    const QStringList& devs = ktv->sourceManager()->deviceList();
    _devicesActionList.clear();

    if (devs.count() != 0) {
        for (QStringList::ConstIterator p = devs.constBegin();
             p != devs.constEnd();
             ++p) {
            DeviceAction* a = new DeviceAction(*p, 0, *p, ktv, acts);
            a->setExclusiveGroup("kdetv_device_actions");
            _devicesActionList.append(a);
        }
    } else {
        KAction* a = new KAction(i18n("No Devices Found. Read FAQ at www.kdetv.org"));
        _devicesActionList.append(a);
    }

    checkDevice(ktv->sourceManager()->device());
    return _devicesActionList;
}

const QPtrList<KAction>& LibKdetvActions::audioModesActionList( KActionCollection *acts )
{
    const QStringList& am = ktv->sourceManager()->audioModes();
    _audioModeActionList.clear();

    if (am.count() != 0) {
        for (QStringList::ConstIterator p = am.constBegin();
             p != am.constEnd();
             ++p) {
            AudioModeAction* a = new AudioModeAction(*p, 0, *p, ktv, acts);
            a->setExclusiveGroup("kdetv_audiomode_actions");
            _audioModeActionList.append(a);
        }
    } else {
        KAction* a = new KAction(i18n("Audio Mode Selection is Not Supported by Current Device/Source"));
        _audioModeActionList.append(a);
    }

    checkAudioMode(ktv->sourceManager()->audioMode());
    return _audioModeActionList;
}

void LibKdetvActions::deviceChanged( const QString& dev )
{
    showSettings->setEnabled( true );

    if ( !dev.isEmpty() ) {
        chan->display( ktv->channel() != NULL ?
                       QString::number(ktv->channel()->number())
                       : QString("---") );
        chanDown->setEnabled( ktv->sourceManager()->isTuner(dev) );
        chanUp->setEnabled( ktv->sourceManager()->isTuner(dev) );
        snap->setEnabled( true );
        chanWiz->setEnabled( true );
        ctrl->setEnabled( true );
        prevChannel->setEnabled( true );
        chanEdit->setEnabled( true );
        if(ktv->sourceManager()->supportsImageFiltering()) {
            fltChainStatus->setText(i18n("&Filter Chain Status"));
            fltChainStatus->setEnabled( true );
        } else {
            fltChainStatus->setText(i18n("Current Video Plugin Does Not Support Image Filtering"));
            fltChainStatus->setEnabled( false );
        }
    } else {
        chan->display( "---" );
        chanDown->setEnabled( false );
        chanUp->setEnabled( false );
        snap->setEnabled( false );
        chanWiz->setEnabled( false );
        ctrl->setEnabled( false );
        prevChannel->setEnabled( false );
        chanEdit->setEnabled( false );
        fltChainStatus->setEnabled( false );
    }

    checkDevice(dev);
}

void LibKdetvActions::checkDevice(const QString& dev)
{
    for(QPtrListIterator<KAction> it(_devicesActionList);
        it.current() != 0;
        ++it) {
        if (it.current()->text() == dev) {
            static_cast<KToggleAction*>(it.current())->setChecked(true);
            break;
        }
    }
}

void LibKdetvActions::checkAudioMode(const QString& mode)
{
    for(QPtrListIterator<KAction> it(_audioModeActionList);
        it.current() != 0;
        ++it) {
        if (it.current()->text() == mode) {
            static_cast<KToggleAction*>(it.current())->setChecked(true);
            break;
        }
    }
}

void LibKdetvActions::updateSlider(int vol)
{
    volUp->setEnabled(vol != 100);
    volDown->setEnabled(vol != 0);
    volSlider->setValue(vol);
}

void LibKdetvActions::updateMuteButton(bool muted)
{
    volMute->setChecked(muted);
}

void LibKdetvActions::enableAudioActions(bool enable)
{
    volSlider->setEnabled(enable);
    volUp->setEnabled(enable);
    volDown->setEnabled(enable);
    volSlider->setEnabled(enable);
}

