/***************************************************************************
   This file is part of LinTV
   lintv.cpp
   Called by the main function to either record with or without a GUI or
   just simply display the LinTV main window & start playing video.

   Author: Jesse L. Zamora <xtremek2009@gmail.com>

   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 Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
 ***************************************************************************/

#ifndef LINTV_H
#define LINTV_H

/* LinTV Includes */
#include "lintvplay.h"
#include "lintvdeviceinfo.h"
#include "lintvprogram.h"

#include <QObject>

/* Forward declarations */
class LinTVView;
class LinTVPlay;
class LinTVRecord;
class LinTVColorDialog;
class LinTVDeviceInfoDialog;

class QTimer;
class QLabel;
class QSystemTrayIcon;

class KAction;


/**
 * The main LinTV class. It basically uses LinTVPlay and LinTVRecord
 * to play and record TV. It connects with an LinTVView class instance
 * for a GUI, but doesn't need it in order to record TV. When recording
 * a schedule with a tray icon, the LinTVView class instance is NOT loaded
 * unless the user clicks the "Show LinTV" context menu action in the tray
 * icon.
 *
 * @short Main window class
 * @author Jesse L. Zamora <xtremek2009@aim.com>
 * @version 0.1
 */
class LinTV : public QObject
{
    Q_OBJECT

public:
    /** The current LinTV status */
    enum Status { NotPlaying = 0, NoDevices, Playing, Paused, Recording };

    /**
     * Intializes LinTVView & LinTVPlay and automatically starts
     * the LinTVPlay instance.
     */
    LinTV();

    /** The main function calls this constructor to record a schedule 
      * when LinTV is run with the --record parameter. It automatically
      * checks the schedules to find if which program is currently recording.
      * When the X server is running & the user is logged in, this creates a
      * system tray icon to let the user know LinTV is recording. Otherwise, it
      * records in the background.
      */
    LinTV(bool hasGui, const QString & device, int input, int channel,
                                    int minutes = 0, const QString & filename = QString());

    /**
     * Default Destructor
     */
    virtual ~LinTV();

public slots:
    
    bool cancelRecording();

    void slotOpenLinTVScheduler();


    // Some slots for LinTVPlay instance
    /** This is triggered when the video is playing **/
    void slotStartedPlaying();
    /** This is triggered when the video has started recording **/
    void slotStartedRecording();

    void slotChannelUp();
    void slotChannelDown();

    /** Show the adjust video colors dialog **/
    void slotAdjustColors();

    /** When the user changes some settings in the LinTV Configure
	dialog, this is called. **/
    void slotSettingsChanged();

    /** When the LinTVPlay backend stops playing video, this updates the status &
        restarts LinTVPlay if m_reloadLinTVPlay is true */
    void slotLinTVPlayExited(int, QProcess::ExitStatus);

    /** When the LinTVRecord backend stops recording video, this updates the program 
      * (if it's recording one) and show a notification 
      */
    void slotLinTVRecordExited(int, QProcess::ExitStatus);

    /** This LinTV class displays the LinTVColorDialog. This slot is called
      * when the user clicks the "Adjust Video Colors" in the LinTV UI context
      * menu 
      */
    void slotShowColorDialog();

    /** This LinTV class displays the LinTVDeviceInfoDialog. This slot is called
      * when the user clicks the "Device Info" context menu in the LinTV UI 
      */
    void slotShowDeviceInfoDialog();

    /** When the user switches the current input in the input selector, this is called
      * so LinTVPlay can change inputs 
      */
    void slotSetInput(int );

    /** Calls LinTVPlay to pause or unpause video */
    void slotPauseVideo(bool );

    /** When the user toggles whether or not to start recording, this is called */
    void slotSetStartRecording(bool );

    /** This is called when the user clicks the "Show LinTV" context menu item in
      * the system tray icon.
      */
    void slotToggleLinTV();

    /** When LinTVView sends an exit event (such as when the close button is pressed),
      * this slot is called to handle it. 
      */
    void exitEvent();

private:
    /** Loads common variables for the LinTV constructors */
    void loadCommon();

    void initializeGui();

    /** Initialize the LinTVPlay instance to play from a TV tuner */
    void initializeBackend(const QString & device, int input, int channel);

    void initializeLinTVPlay();
    void initializeLinTVRecord();

    /** When LinTV starts to record a program, this finds the program and updates the
      * status (from "Queued" to "Recording" for example)
      */
    LinTVProgram updateProgramStatus(const QString & device, int input, int channel,
                                                      const QString & programName);

    /** Detects the devices using LinTVDeviceInfo class */
    void detectDevices();

    /** Changes the current device to the one matching the deviceName
        parameter. If it can't find the device, it just selects the
        first one in the list and returns 0. */ 
    int selectDevice(QString deviceName);

    /** Saves the LinTV settings. */
    void saveSettings();

    void refreshPrograms();

private:
    LinTVView *m_view;
    LinTVPlay * m_lintvPlay;
    LinTVRecord *m_lintvRecord;
    LinTVColorDialog *m_colorDialog;
    LinTVDeviceInfoDialog *m_deviceInfoDialog;

    LinTVProgramHandler programHandler;

    LinTVDevices m_devices;

    // This contains the program that is currently recording (if LinTV is 
    // recording a program anyway...)
    LinTVProgram m_program;

    QSystemTrayIcon *m_tray;
    KAction *m_toggleLinTVAction;
    
    QTime m_time;

    static bool m_initDeviceInfoDialog;
    static bool m_initGui;
    static bool m_initLinTVPlay;

    int m_numOfDev;
    int m_curDev;

    int m_input;
    int m_channel;

    bool m_hasSchedule;
    bool m_exitWhenDone;

    bool m_hasGui;
    bool m_reloadLinTVPlay;

    bool m_canceledRecord;
    bool m_recordSchedule;
};

#endif // _LINTV_H_
