/***************************************************************************
 *   Copyright (C) 2005-2006 by Andreas Silberstorff   *
 *   ml@andreas-silberstorff.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.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA.             *
 *                                                                         *
 *   In addition, as a special exception, the copyright holders give       *
 *   permission to link the code of this program with any edition of       *
 *   the Qt library by Trolltech AS, Norway (or with modified versions     *
 *   of Qt that use the same license as Qt), and distribute linked         *
 *   combinations including the two.  You must obey the GNU General        *
 *   Public License in all respects for all of the code used other than    *
 *   Qt.  If you modify this file, you may extend this exception to        *
 *   your version of the file, but you are not obligated to do so.  If     *
 *   you do not wish to do so, delete this exception statement from        *
 *   your version.                                                         *
 ***************************************************************************/

#include "kalvaview.h"
#include "kalvasidebar.h"
#include "settings.h"
#include "kalva_channellist.h"
#include "kalva_player.h"
#include "kalva_recorder.h"
#include "serialbrowser.h"
#include "moviebrowser.h"
#include "fileselector.h"

#include <qlabel.h>
#include <qsplitter.h>
#include <qlayout.h>
#include <qsizepolicy.h>
#include <qevent.h>
#include <qpixmap.h>

#include <kdebug.h>
#include <klocale.h>
#include <kglobal.h>
#include <kdockwidget.h>
#include <kmultitabbar.h>
#include <kstandarddirs.h>
#include <kiconloader.h>

#include <kmessagebox.h>

KalvaView::KalvaView(QWidget *parent)
    : DCOPObject( "DCOP_kalva" ),
      QWidget(parent)
{
    setName( "kalvaview" );

    QBoxLayout * l = new QHBoxLayout( this );
    l->setAutoAdd( true );

    m_sidebar         = new KalvaSideBar(           this );
    m_channellist     = new KalvaChannellist(             m_sidebar, "channellist"     );
    m_movieBrowser    = new movieBrowser(           this, m_sidebar, "moviebrowser"    );
    m_serialBrowser   = new serialBrowser(          this, m_sidebar, "serialbrowser"   );

    m_sidebar->insertTab( m_channellist,
                  SmallIcon("kalva"),
                  i18n("Channellist"));
    m_sidebar->insertTab( m_movieBrowser,
                  SmallIcon("moviebrowser"),
                  i18n("Movies") );
    m_sidebar->insertTab( m_serialBrowser,
                  SmallIcon("serialbrowser"),
                  i18n("Serials") );

    m_tabWidget       = new QTabWidget( this, "tabWidget" );

    m_player          = new KalvaPlayer(     m_tabWidget, "player" );
    m_recorder        = new KalvaRecorder(   m_tabWidget, "recorder" );
    m_videocollection = new FileSelectorWidget( KFile::Files, this, "videocollection" );

    m_tabWidget->insertTab( m_player,          i18n("TV") );
    m_tabWidget->insertTab( m_recorder,        i18n("VCR") );
    m_tabWidget->insertTab( m_videocollection, i18n("Collection") );

    QHBoxLayout* sidebar    = new QHBoxLayout( m_sidebar, 0, 0 );
    QVBoxLayout* sbTabAerea = new QVBoxLayout( sidebar );

    sbTabAerea->addWidget( m_channellist );
    sbTabAerea->addWidget( m_movieBrowser );
    sbTabAerea->addWidget( m_serialBrowser );

   /*****************************************************
     My messy geometry combat field #-\
    *****************************************************/

    QSize minSizeChlst    = m_channellist->minimumSizeHint();
    QSize minSizeWS       = QSize(520, 460);
    QSize minSizeSplitter = ( minSizeWS + minSizeChlst );

    setMinimumSize( 640,480 );
    //resize( minimumSizeHint() );
    parent->setSizePolicy( QSizePolicy::MinimumExpanding,
                 QSizePolicy::MinimumExpanding );

   /*****************************************************
      end of my messy geometry combat field #-\
    *****************************************************/
    connect ( m_channellist, SIGNAL(signalStationChanged()),
              this,            SLOT(slotStationChanged()));
    connect ( m_recorder,  SIGNAL(signalMovieScheduled()),
              m_movieBrowser,  SLOT(slotRead()));
    connect ( m_recorder,  SIGNAL(signalSerialScheduled()),
              m_serialBrowser, SLOT(slotRead()));
    connect ( m_recorder,  SIGNAL(signalDeleteSerialFromCron()),
              m_serialBrowser, SLOT(slotDeleteSerial()));
    connect ( m_recorder,  SIGNAL(signalDeleteMovie( const QString &, bool )),
              m_movieBrowser,  SLOT(slotDeleteMovie( const QString &, bool ))
            );
    connect ( m_movieBrowser, SIGNAL(signalReadingDone()),
              m_recorder,      SLOT(slotMoviesRead())
            );

    m_channellist->loadChannellist();
    m_movieBrowser->slotRead();
    m_serialBrowser->slotRead();
}

KalvaView::~KalvaView()
{

}


void KalvaView::settingsChanged()
{
    KConfigGroup kalvaConfig(KGlobal::config(), "Kalva");
    QString lastStation = kalvaConfig.readEntry("lastStation");

    kdDebug() << "read last station as "
                      << lastStation << endl;

    m_channellist->loadChannellist();
    m_channellist->setStation( lastStation );
    m_videocollection->setDir( Settings::storage_path() );
    Settings::setChlst_changed(false);
    emit signalChangeStatusbar( i18n("Settings changed") );
}

void KalvaView::slotStationChanged()
{
    QString station = m_channellist->station();
    QString channel = m_channellist->channel();
    QString frq= m_channellist->frq();
    m_recorder->stationChanged(station,channel,frq);
    m_player->stationChanged(station,channel,frq);
    KConfigGroup kalvaConfig(KGlobal::config(), "Kalva");
    kalvaConfig.writeEntry( "lastStation", station);
    kdDebug() << "save last station as "
                      << station << endl;
    KGlobal::config()->sync();
}


KalvaSideBar* KalvaView::sidebar() const
{
   return m_sidebar;
}

KalvaChannellist* KalvaView::channellist() const
{
   return m_channellist;
}

/* DCOP Interfaces */

ASYNC KalvaView::DcopMovieManagerRead( )
{
   m_movieBrowser->slotRead();
}

QString KalvaView::DcopFuzzyStation( const QString & yourStation )
{
   return m_channellist->yourFuzzyStation( yourStation );
}

ASYNC KalvaView::DcopPlay(
                const QString & yourStation
                )
{
   QString myStation = underscoreToBlank(yourStation);
   bool stationFound = m_channellist->setStation(myStation);
   bool wait         = Settings::wait_on_dcop();
   bool run          = ( ( stationFound ) and ( ! wait ) );

   m_tabWidget->setCurrentPage(0);
   if (! stationFound )
      warnChannelNotFound(myStation);
   if ( run )  {
      m_player->play();
   }  else   {
      topLevelWidget()->show();
      topLevelWidget()->raise();
   }
}

QString KalvaView::DcopRecordNow(
                const QString & yourStation,
                const QString & yourTitel,
                const QString & yourLength
                )
{
   QString myStation = underscoreToBlank(yourStation);
   bool stationFound = m_channellist->setStation(myStation);
   bool wait         = Settings::wait_on_dcop();
   bool run          = ( ( stationFound ) and ( ! wait ) );

   m_tabWidget->setCurrentPage(1);
   m_recorder->recordNow( underscoreToBlank(yourTitel),
                          getTimeFromInput(yourLength),
                          run
                         );
   if (! stationFound )
      warnChannelNotFound(myStation);
   if (! run )  {
      topLevelWidget()->show();
      topLevelWidget()->raise();
   }
   return i18n("recording immediatly");
}

QString KalvaView::DcopRecordMovie(
                const QString & yourStation,
                const QString & yourTitel,
                const QString & yourLength,
                const QString & yourStartTime,
                const QString & yourStartDate
                )
{
   QString myStation = underscoreToBlank(yourStation);
   bool stationFound = m_channellist->setStation(myStation);
   bool wait         = Settings::wait_on_dcop();
   bool run          = ( ( stationFound ) and ( ! wait ) );

   m_tabWidget->setCurrentPage(1);
   m_recorder->recordMovie( underscoreToBlank(yourTitel),
                            getTimeFromInput(yourLength),
                            yourStartTime,
                            yourStartDate,
                            0,
                            run
                          );
   if (! stationFound )
      warnChannelNotFound(myStation);
   if (! run )  {
      topLevelWidget()->show();
      topLevelWidget()->raise();
   }
   return i18n("recording Movie");
}

QString KalvaView::DcopRecordSerial(
                const QString & yourStation,
                const QString & yourTitel,
                const QString & yourLength,
                const QString & yourStartTime,
                const QString & yourDOWs
                )
{
   QString myStation = underscoreToBlank(yourStation);
   bool stationFound = m_channellist->setStation(myStation);
   bool wait         = Settings::wait_on_dcop();
   bool run          = ( ( stationFound ) and ( ! wait ) );

   m_tabWidget->setCurrentPage(1);
   m_recorder->recordSerial( yourTitel,
	                     getTimeFromInput(yourLength),
                             yourStartTime,
                             yourDOWs,
                             run
                           );
   if (! stationFound )
      warnChannelNotFound(myStation);
   if (! run )  {
      topLevelWidget()->show();
      topLevelWidget()->raise();
   }
   return i18n("Recording serial");
}

QString KalvaView::getTimeFromInput(const QString& yourTime)  {
	if (yourTime.endsWith("m", false)) {
		return timeFromMinutes(yourTime);
	} else if  (yourTime.endsWith("s", false)) {
		return timeFromSeconds(yourTime);
	} else {
	   return yourTime;
	}
}

QString KalvaView::timeFromMinutes(const QString& yourTime) {
	QString minuteString = yourTime;
	minuteString = minuteString.left(minuteString.length() -1);
	int minutes = minuteString.toInt();
	int hours = minutes / 60;
	// sorry for being to lazy to lear how to get the rest...
	// feel free to improve this :-)
	int minutesInHours = hours * 60;
	minutes = minutes - minutesInHours;
	QString myTime =  QString("%1:%2:00").arg(hours).arg(minutes);
	return myTime;
}

QString KalvaView::timeFromSeconds(const QString& yourTime) {
	QString secondsString = yourTime;
	secondsString = secondsString.left(secondsString.length() -1);
	int seconds = secondsString.toInt();
	int minutes = seconds / 60;
	// sorry for being to lazy to lear how to get the rest...
	// feel free to improve this :-)
	int secondsInMinutes = minutes * 60;
	seconds = seconds - secondsInMinutes;
	int hours = minutes / 60;
	// sorry for being to lazy to lear how to get the rest...
	// feel free to improve this :-)
	int minutesInHours = hours * 60;
	minutes = minutes - minutesInHours;
	QString myTime =  QString("%1:%2:%3").arg(hours).arg(minutes).arg(seconds);
	return myTime;
}

QString KalvaView::underscoreToBlank(const QString& yourString) {
	QString myString = yourString;
	myString = myString.replace('_', " ");
	return myString;
}

void KalvaView::recordSerial(
                const QString & yourStation,
                const QString & yourTitel,
                const QString & yourLength,
                const QString & yourStartTime,
                const QString & yourDOWs
                )
{
   //kdDebug() << "In recordSerial() " << endl;

   bool stationFound = m_channellist->setStation( yourStation );
   bool wait         = Settings::wait_on_dcop();
   bool run          = ( (! stationFound ) and ( ! wait ) );

   m_tabWidget->setCurrentPage(1);
   m_recorder->recordSerial( yourTitel,
                             yourLength,
                             yourStartTime,
                             yourDOWs,
                             false
                           );
   if (! run )  {
      topLevelWidget()->show();
      topLevelWidget()->raise();
   }
   if (! stationFound )
      warnChannelNotFound( yourStation );
   return;
}

void KalvaView::recordMovie(
                const QString & yourStation,
                const QString & yourTitel,
                const QString & yourLength,
                const QString & yourStartTime,
                const QString & yourStartDay,
                const QString & yourJobId
                )
{
   kdDebug() << "In recordMovie() " << endl;
   bool run = m_channellist->setStation( yourStation );
   m_tabWidget->setCurrentPage(1);
   m_recorder->recordMovie( yourTitel,
                             yourLength,
                             yourStartTime,
                             yourStartDay,
                             yourJobId,
                             false
                           );
   if (! run )  {
      warnChannelNotFound( yourStation );
   }
   topLevelWidget()->show();
   topLevelWidget()->raise();
   return;
}

void KalvaView::warnChannelNotFound(const QString& text)
{
   KMessageBox::detailedSorry   (
      this,
      i18n("I could not find a channel for your station"), 
      i18n("<qt>Kalva could not find the channel that corresponds to the stationname <b>%1</b>.      Kalva probably was called by an external program like an electronic program guide. Search the correct station in the channellist on the left. You should consider to change the name of the station in the list to make it compatible to your external program.<br><br>Don't forget to save your channellist if you change it.</qt>").arg( text ), 
          i18n("Station not found")
       );
}

#include "kalvaview.moc"
