// Copyright 2004 Max Howell (max.howell@methylblue.com)
// See COPYING file for licensing information

#include "actions.h"
#include "adjustSizeButton.h"
#include "../debug.h"
#include "mainWindow.h"
#include <tdeconfig.h>
#include <tdeglobal.h>
#include "../mxcl.library.h"
#include <tqapplication.h>
#include <tqevent.h>
#include <tqlabel.h>
#include <tqpopupmenu.h>
#include <tqslider.h>
#include <tqwidgetstack.h>
#include "audioView.h"
#include "theStream.h"
#include "videoSettings.h" //FIXME unfortunate
#include "xineEngine.h"
#include "volumeAction.h"


//TODO do in Sconstruct
#define QT_FATAL_ASSERT


//TODO make the XineEngine into xine::Stream and then make singleton and add functions like Stream::hasVideo() etc.
//TODO make convenience function to get fullscreen state


namespace Codeine {


void
MainWindow::engineStateChanged( Engine::State state )
{
   Q_ASSERT( state != Engine::Uninitialised );

   KURL const &url = TheStream::url();
   bool const isFullScreen = toggleAction("fullscreen")->isChecked();
   TQWidget *const toolbar = reinterpret_cast<TQWidget*>(toolBar());

   Debug::Block block( state == Engine::Empty
         ? "State: Empty" : state == Engine::Loaded
         ? "State: Loaded" : state == Engine::Playing
         ? "State: Playing" : state == Engine::Paused
         ? "State: Paused" : state == Engine::TrackEnded
         ? "State: TrackEnded" : "State: Unknown" );


   /// update actions
   {
      using namespace Engine;

      #define enableIf( name, criteria ) action( name )->setEnabled( state & criteria );
      enableIf( "stop", (Playing | Paused) );
      enableIf( "fullscreen", (Playing | Paused) );
      enableIf( "reset_zoom", ~Empty && !isFullScreen );
      enableIf( "information", ~Empty );
      enableIf( "video_settings", (Playing | Paused) );
      enableIf( "volume", (Playing | Paused) );
      #undef enableIf

      toggleAction( "play" )->setChecked( state == Playing );

      //FIXME bad design to do this way
      m_volumeAction->setVolume(engine()->volume());
      m_volumeAction->setMuted(engine()->isMuted());
   }


   /// update VideoSettingsDialog instance
   VideoSettingsDialog::stateChanged( this, state );


   /// update menus
   {
      using namespace Engine;

      // the toolbar play button is always enabled, but the menu item
      // is disabled if we are empty, this looks more sensible
      TQPopupMenu * const file_menu = menu( "file" );
      TQPopupMenu * const settings_menu = menu( "settings" );
      const int play_id = file_menu->idAt( 2 );
      file_menu->setItemEnabled( play_id, state != Empty );

      // menus are clearer when handled differently to toolbars
      // KDE has a shit special action for this, but it stupidly changes
      // the toolbar icon too.
      // TODO do this from the playAction since we do it in context menu too
      const KGuiItem item = (state == Playing) ? KGuiItem( i18n("&Pause"), "media-playback-pause" ) : KGuiItem( i18n("&Play"), "media-playback-start" );
      file_menu->changeItem( play_id, item.iconSet(), item.text() );
      file_menu->setItemChecked( play_id, false );

      if (const auto aspectAction = dynamic_cast<TDESelectAction *>(action("aspect_ratio_select")))
      {
         aspectAction->setEnabled((state & (Playing | Paused)) && TheStream::hasVideo());
         if (state == Loaded)
         {
            aspectAction->setCurrentItem(TheStream::aspectRatio());
         }
      }
   }


   /// update statusBar
   {
      using namespace Engine;
      m_analyzer->setShown(state & (Playing | Paused) && (TheStream::hasVideo() && TheStream::hasAudio()));
      m_timeLabel->setShown(state & (Playing | Paused));
   }

   // Update the current widget shown.
   if (TheStream::hasVideo() || (state & (Engine::Empty)))
   {
      m_widgetStack->raiseWidget(videoWindow());
   }
   else if (TheStream::hasAudio())
   {
      m_widgetStack->raiseWidget(m_audioView);
   }


   /// update position slider
   switch( state )
   {
      case Engine::Empty:
         m_positionSlider->setEnabled( false );
         break;
      case Engine::Loaded:
      case Engine::TrackEnded:
         m_positionSlider->setValue( 0 );
         // NO BREAK!
      case Engine::Playing:
      case Engine::Paused:
         m_positionSlider->setEnabled( TheStream::canSeek() );
         break;
      default:
         break;
   }


   /// update recent files list if necessary
   if( state == Engine::Loaded ) {
      // update recently played list

      #ifndef NO_SKIP_PR0N
      // ;-)
      const TQString url_string = url.url();
      if( !(url_string.contains( "porn", false ) || url_string.contains( "pr0n", false )) )
      #endif
         if( url.protocol() != "dvd" && url.protocol() != "vcd" ) {
            TDEConfig *config = Codeine::config( "General" );
            const TQString prettyUrl = url.prettyURL();

            TQStringList urls = config->readPathListEntry( "Recent Urls" );
            urls.remove( prettyUrl );
            config->writePathEntry( "Recent Urls", urls << prettyUrl );
         }

      if( TheStream::hasVideo() && !isFullScreen )
         new AdjustSizeButton( reinterpret_cast<TQWidget*>(videoWindow()) );
   }


   /// set titles
   switch( state )
   {
      case Engine::Empty:
         m_titleLabel->setText( i18n("No media loaded") );
         break;
      case Engine::Paused:
         m_titleLabel->setText( i18n("Paused") );
         break;
      case Engine::Loaded:
      case Engine::Playing:
      case Engine::TrackEnded:
         m_titleLabel->setText( TheStream::prettyTitle() );
         break;
      default:
         break;
   }


   /// set toolbar states
   TQWidget *dvd_button = (TQWidget*)toolBar()->child( "toolbutton_toggle_dvd_menu" );
   if (dvd_button)
      dvd_button->setShown( state != Engine::Empty && url.protocol() == "dvd" );

   if( isFullScreen && !toolbar->hasMouse() ) {
      switch( state ) {
      case Engine::TrackEnded:
         toolbar->show();

         if( videoWindow()->isActiveWindow() ) {
            //FIXME dual-screen this seems to still show
            TQContextMenuEvent e( TQContextMenuEvent::Other, TQPoint(), TQt::MetaButton );
            TQApplication::sendEvent( videoWindow(), &e );
         }
         break;
      case Engine::Empty:
      case Engine::Loaded:
      case Engine::Paused:
         toolBar()->show();
         break;
      case Engine::Playing:
         toolBar()->hide();
         break;
      default:
         break;
      }
   }
}

}
