/*
   This file is part of KDE/aRts (Noatun) - xine integration
   Copyright (C) 2002 Ewald Snel <ewald@rambo.its.tudelft.nl>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <noatun/app.h>
#include <noatun/engine.h>
#include <noatun/player.h>
#include <noatun/stdaction.h>

#include <tdeconfig.h>
#include <tdeglobal.h>
#include <tdeglobalsettings.h>
#include <kiconloader.h>
#include <tdelocale.h>
#include <kurldrag.h>
#include <tdemenubar.h>
#include <tdepopupmenu.h>
#include <kstatusbar.h>
#include <kstdaction.h>
#include <kstdguiitem.h>
#include <kurl.h>

#include <tqaccel.h>
#include <tqdragobject.h>
#include <tqhbox.h>
#include <tqimage.h>
#include <tqpixmap.h>
#include <tqstrlist.h>
#include <tqtooltip.h>
#include <tqvbox.h>

#include "userinterface.h"

#include "back.xpm"
#include "forward.xpm"
#include "pause.xpm"
#include "play.xpm"
#include "playlist.xpm"
#include "stop.xpm"
#include "volume.xpm"

SimpleUI::SimpleUI()
     : TDEMainWindow(0, "NoatunSimpleUI"), UserInterface()
{
    setAcceptDrops( true );
    setCaption( i18n("Noatun") );
    setIcon( SmallIcon( "noatun" ) );

    setupCentralWidget();
    setupActions();

    contextMenu = video->popupMenu( this );

    setupGUI( StatusBar|Create, "simpleui.rc" );

    connect( napp->player(), TQ_SIGNAL(playing()), TQ_SLOT(slotPlaying()) );
    connect( napp->player(), TQ_SIGNAL(stopped()), TQ_SLOT(slotStopped()) );
    connect( napp->player(), TQ_SIGNAL(paused()), TQ_SLOT(slotPaused()) );
    connect( napp->player(), TQ_SIGNAL(timeout()), TQ_SLOT(slotTimeout()) );
    connect( napp->player(), TQ_SIGNAL(newSong()), TQ_SLOT(slotChanged()) );
    connect( napp->player(), TQ_SIGNAL(volumeChanged(int)), TQ_SLOT(slotVolumeChanged(int)) );
    connect( napp, TQ_SIGNAL(hideYourself()), TQ_SLOT(hide()) );
    connect( napp, TQ_SIGNAL(showYourself()), TQ_SLOT(show()) );

    napp->player()->handleButtons();

    resize( minimumSize() );

    // Show UI and calculate video widget frame
    show();

    extra_width  = (width() - video->width());
    extra_height = (height() - video->height());

    // Load configuration
    TDEConfig &config = *TDEGlobal::config();
    config.setGroup( "Simple" );
    TQString str = config.readEntry( "View", "NormalSize" );

    if (str == "HalfSize")
        video->setHalfSize();
    else if (str == "NormalSize")
        video->setNormalSize();
    else if (str == "DoubleSize")
        video->setDoubleSize();
    else
        applyMainWindowSettings( &config, "Simple" );

    // PlayObject could be running, update video widget
    slotChanged();

    video->give();
}

SimpleUI::~SimpleUI()
{
    TDEConfig &config = *TDEGlobal::config();
    saveMainWindowSettings( &config, "Simple" );
    config.setGroup( "Simple" );
    TQString str;

    if (video->isHalfSize())
        str = "HalfSize";
    else if (video->isNormalSize())
        str = "NormalSize";
    else if (video->isDoubleSize())
        str = "DoubleSize";
    else
        str = "CustomSize";

    config.writeEntry( "View", str );
    config.sync();
}



void SimpleUI::setupActions()
{
    KStdAction::open( napp, TQ_SLOT(fileOpen()), actionCollection(), "_file_open" );
    new TDEAction( i18n("&Properties"), 0, propertiesDialog, TQ_SLOT(show()),
        actionCollection(), "_file_properties" );
    KStdAction::quit( napp, TQ_SLOT(quit()), actionCollection(), "_file_quit");

     NoatunStdAction::playlist( actionCollection(), "view_playlist" );
    actionCollection()->insert(video->action( "half_size" ));
    actionCollection()->insert(video->action( "normal_size" ));
    actionCollection()->insert(video->action( "double_size" ));
    actionCollection()->insert(video->action( "fullscreen_mode" ));

    actionCollection()->insert(napp->pluginActionMenu());

    menubarAction = KStdAction::showMenubar(this, TQ_SLOT(showMenubar()),
        actionCollection());
    statusbarAction = KStdAction::showStatusbar(this, TQ_SLOT(showStatusbar()),
        actionCollection());
    NoatunStdAction::effects( actionCollection(), "effects" );
    NoatunStdAction::equalizer( actionCollection(), "equalizer" );
    NoatunStdAction::loop( actionCollection(), "loop_style" );
    KStdAction::preferences( napp, TQ_SLOT(preferences()), actionCollection() );
}

void SimpleUI::showMenubar()
{
    if(menubarAction->isChecked())
        menuBar()->show();
    else
        menuBar()->hide();
}

void SimpleUI::showStatusbar()
{
    if(statusbarAction->isChecked())
        statusBar()->show();
    else
        statusBar()->hide();
}


void SimpleUI::setupCentralWidget()
{
    TQVBox *npWidget = new TQVBox( this );
    npWidget->setMargin( 0 );
    npWidget->setSpacing( 0 );

    positionLabel = new TQLabel( statusBar() );
    positionLabel->setAlignment( AlignVCenter | AlignCenter );
    positionLabel->setFixedSize( fontMetrics().size( 0, " 00:00/00:00 " ) );
    statusBar()->addWidget( positionLabel, 0, true );

    video = new VideoFrame( npWidget );
    connect( video, TQ_SIGNAL(adaptSize(int,int)),
         TQ_SLOT(slotAdaptSize(int,int)) );
    connect( video, TQ_SIGNAL(rightButtonPressed(const TQPoint &)),
         TQ_SLOT(slotContextMenu(const TQPoint &)) );

    TQHBox *ctlFrame = new TQHBox( npWidget );
    ctlFrame->setFixedHeight( 38 );
    ctlFrame->setFrameShape( TQFrame::StyledPanel );
    ctlFrame->setFrameShadow( TQFrame::Raised );
    ctlFrame->setMargin( 6 );
    ctlFrame->setSpacing( 6 );

    TQPushButton *backButton = new TQPushButton( ctlFrame );
    backButton->setFixedSize( 24, 24 );
    backButton->setPixmap( TQPixmap( back_xpm ) );
    TQToolTip::add( backButton, i18n("Back") );
    connect( backButton, TQ_SIGNAL(clicked()), napp->player(), TQ_SLOT(back()) );

    stopButton = new TQPushButton( ctlFrame );
    stopButton->setFixedSize( 24, 24 );
    stopButton->setPixmap( TQPixmap( stop_xpm ) );
    TQToolTip::add( stopButton, i18n("Stop") );
    connect( stopButton, TQ_SIGNAL(clicked()), napp->player(), TQ_SLOT(stop()) );

    playButton = new TQPushButton( ctlFrame );
    playButton->setFixedSize( 24, 24 );
    playButton->setPixmap( TQPixmap( play_xpm ) );
    TQToolTip::add( playButton, i18n("Play / Pause") );
    connect( playButton, TQ_SIGNAL(clicked()), napp->player(), TQ_SLOT(playpause()) );

    TQPushButton *forwButton = new TQPushButton( ctlFrame );
    forwButton->setFixedSize( 24, 24 );
    forwButton->setPixmap( TQPixmap( forward_xpm ) );
    TQToolTip::add( forwButton, i18n("Forward") );
    connect( forwButton, TQ_SIGNAL(clicked()), napp->player(), TQ_SLOT(forward()) );

    slider = new L33tSlider( 0, 1000, 10, 0, TQt::Horizontal, ctlFrame );
    slider->setFixedHeight( 24 );
    slider->setMinimumWidth( 100 );
    slider->setTickmarks( TQSlider::NoMarks );
    connect( slider, TQ_SIGNAL(userChanged(int)), TQ_SLOT(slotSkipTo(int)) );
    connect( slider, TQ_SIGNAL(sliderMoved(int)), TQ_SLOT(slotSliderMoved(int)) );

    TQPushButton *playlistButton = new TQPushButton( ctlFrame );
    playlistButton->setFixedSize( 24, 24 );
    playlistButton->setPixmap( TQPixmap( playlist_xpm ) );
    TQToolTip::add( playlistButton, i18n("Playlist") );
    connect( playlistButton, TQ_SIGNAL(clicked()), napp->player(), TQ_SLOT(toggleListView()) );

    volumeButton = new TQPushButton( ctlFrame );
    volumeButton->setFixedSize( 24, 24 );
    volumeButton->setPixmap( TQPixmap( volume_xpm ) );
    TQToolTip::add( volumeButton, i18n("Volume") );

    volumeFrame = new TQVBox( this, "Volume", WStyle_Customize | WType_Popup );
    volumeFrame->setFrameStyle( TQFrame::PopupPanel );
    volumeFrame->setMargin( 4 );

    volumeLabel = new TQLabel( volumeFrame );
    volumeLabel->setText( "100%" );
    volumeLabel->setAlignment( AlignCenter );
    volumeLabel->setFixedSize( volumeLabel->sizeHint() );

    TQHBox *volumeSubFrame = new TQHBox( volumeFrame );
    volumeSlider = new L33tSlider( 0, 100, 10, 0,TQt::Vertical, volumeSubFrame );
    volumeSlider->setValue( 100 - napp->player()->volume() );
    volumeSlider->setFixedSize( volumeSlider->sizeHint() );

    volumeFrame->resize( volumeFrame->sizeHint() );

    connect( volumeSlider, TQ_SIGNAL(sliderMoved(int)), TQ_SLOT(slotVolumeSliderMoved(int)) );
    connect( volumeSlider, TQ_SIGNAL(userChanged(int)), TQ_SLOT(slotVolumeSliderMoved(int)) );
    connect( volumeButton, TQ_SIGNAL(clicked()), TQ_SLOT(slotVolumeFrame()) );

    setCentralWidget( npWidget );

    video->setMinimumSize( minimumSizeHint().width(), 1 );

    // Create properties dialog
    propertiesDialog = new PropertiesDialog( this );
    propertiesDialog->resize( 375, 285 );
}

void SimpleUI::closeEvent( TQCloseEvent * )
{
    unload();
}

void SimpleUI::dragEnterEvent( TQDragEnterEvent *event )
{
    event->accept( KURLDrag::canDecode( event ) );
}

void SimpleUI::dropEvent( TQDropEvent *event )
{
    KURL::List uri;
    if (KURLDrag::decode( event, uri ))
        napp->player()->openFile( uri, false );
}

void SimpleUI::slotAdaptSize( int width, int height )
{
    resize( width + extra_width, height + extra_height );
}

void SimpleUI::slotPlaying()
{
    playButton->setPixmap( TQPixmap( pause_xpm ) );
    stopButton->setEnabled( true );
    slider->setEnabled( true );

    if (napp->player()->current())
        statusBar()->message( napp->player()->current().title() );
}

void SimpleUI::slotStopped()
{
    playButton->setPixmap( TQPixmap( play_xpm ) );
    stopButton->setEnabled( false );
    slider->setEnabled( false );
    slider->setValue( 0 );
    positionLabel->setText( "" );
    statusBar()->message( "" );
}

void SimpleUI::slotPaused()
{
    playButton->setPixmap( TQPixmap( play_xpm ) );
    slider->setEnabled( true );
}

void SimpleUI::slotTimeout()
{
    if (napp->player()->current() && !slider->currentlyPressed())
    {
        positionLabel->setText( napp->player()->lengthString() );
        slider->setRange( 0, (int)napp->player()->getLength() / 1000 );
        slider->setValue( (int)napp->player()->getTime() / 1000 );
    }
}

void SimpleUI::slotSkipTo( int sec )
{
    napp->player()->skipTo( sec * 1000 );
}

void SimpleUI::slotChanged()
{
    propertiesDialog->setPlayObject( napp->player()->current(),
        napp->player()->engine()->playObject() );
}

void SimpleUI::slotContextMenu( const TQPoint &pos )
{
    contextMenu->exec( pos );
}

void SimpleUI::slotSliderMoved( int sec )
{
    if (napp->player()->current())
        positionLabel->setText( napp->player()->lengthString( sec * 1000 ) );
}

void SimpleUI::slotVolumeChanged( int volume )
{
    volumeLabel->setText( TQString::number( volume ) + "%" );
    volumeSlider->setValue( 100 - volume );
}

void SimpleUI::slotVolumeFrame()
{
    if (volumeFrame->isVisible())
    {
        volumeFrame->hide();
    }
    else
    {
        int x = (volumeButton->width() - volumeFrame->width()) / 2;
        int y = -(volumeFrame->height() + 5);

        TQPoint point( volumeButton->mapToGlobal( TQPoint( x, y ) ) );
        TQRect deskRect = TDEGlobalSettings::desktopGeometry( point );

        bool bottom = (point.y() + volumeFrame->height()) > (deskRect.y() + deskRect.height());
        bool right = (point.x() + volumeFrame->width()) > (deskRect.x() + deskRect.width());

        volumeFrame->move(
            right ? (deskRect.x() + deskRect.width()) - volumeFrame->width() : ( point.x() < 0 ? 0 : point.x() ),
            bottom ? (deskRect.y() + deskRect.height()) - volumeFrame->height() : ( point.y() < 0 ? 0 : point.y() ) );
        volumeFrame->show();
    }
}

void SimpleUI::slotVolumeSliderMoved( int slider )
{
    napp->player()->setVolume( 100 - slider );
}

#include "userinterface.moc"
