/**
 *  GraphTFT plugin for the Video Disk Recorder 
 * 
 *  display.h - A plugin for the Video Disk Recorder
 *
 *  (c) 2004-2006 Lars Tegeler, Sascha Volkenandt, Jörg Wendel
 *
 * This code is distributed under the terms and conditions of the
 * GNU GENERAL PUBLIC LICENSE. See the file COPYING for details.
 *
 * $Id: display.h,v 1.11 2007/12/03 19:58:20 root Exp $
 *
 **/

#ifndef __GTFT_DISPLAY_H
#define __GTFT_DISPLAY_H

//***************************************************************************
// Includes
//***************************************************************************

#include <map>
#include <string>
#include <vector>

#include <vdr/thread.h>
#include <vdr/status.h>
#include <vdr/tools.h>
#include <vdr/skins.h>

#include <common.h>
#include <comthread.h>
#include <renderer.h>
#include <theme.h>
#include <transfer.h>

using std::map;
using std::string;
using std::vector;

//***************************************************************************
// Class cGraphTFTService
//***************************************************************************

class cGraphTFTService : public cThemeService
{
   public:

      enum ChannelType
      {
         ctRadio = 0,
         ctTv
      };

      enum { MaxTabs = 6 };
      
      enum DisplayMode 
      {
         ModeUnknown      = 0x00,

         ModeMask         = 0xF0,
         DisplayMask      = 0x0F,

         ModeNormal       = 0x10,
         ModeReplay       = 0x20,
         ModeMenu         = 0x30,
         ModeCallibration = 0x40,

         NormalView       = 0x11,

         ReplayNormal     = 0x21,
         ReplayMP3        = 0x22,
         ReplayDVD        = 0x23,

         MenuDefault      = 0x31,
         MenuMain         = 0x32,
         MenuSchedule     = 0x33,
         MenuChannels     = 0x34,
         MenuTimers       = 0x35,
         MenuRecordings   = 0x36,
         MenuSetup        = 0x37,
         MenuCommands     = 0x38,
         MenuWhatsOnElse  = 0x39,
         MenuWhatsOnNow   = 0x3a,
         MenuWhatsOnNext  = 0x3b,
         MenuSetupPage    = 0x3c,

         Calibration      = 0x41
      };

      static int isModeNormal(DisplayMode mode)       { return (mode & ModeMask) == ModeNormal; }
      static int isModeReplay(DisplayMode mode)       { return (mode & ModeMask) == ModeReplay; }
      static int isModeMenu(DisplayMode mode)         { return (mode & ModeMask) == ModeMenu; }
      static int isModeCallibration(DisplayMode mode) { return (mode & ModeMask) == ModeCallibration; }
};

//***************************************************************************
// Class GraphTFT Display
//***************************************************************************

class cGraphTFTDisplay : public cStatus, cThread, public cGraphTFTService
{
   public:

      // object

      cGraphTFTDisplay();
      ~cGraphTFTDisplay();

      // interface

      int Init(const char* dev, const char* cfgDir, int port);
      void setupChanged();
      void setCalibrate(int active);
      int setMode(DisplayMode mode, const char* menuName = 0, int force = false);
   
      // thread stuff

      bool Start()        { return cThread::Start(); }
      void Stop();
      bool Active() const { return _active; }
      cMutex* getMutex()  { return &_mutex; }

      void themesReloaded() { lastSection = 0; currentSection = 0; }

      // due to comThread destructor is called by vdr, 
      // trick to inherited by cRemote

      void clearComThread() { comThread = 0; } 

      // event
      
      void mouseEvent(int x, int y, int button, int flag = ComThread::efNone);

      // PbP stuff

      void Pbp();
      void PbpRestart();
      void PbpSwitch(bool Back);
      void PbpUpDown(bool Up);
      bool PbpIsRunning();
      void PbpStart();
      void PbpStop();
      void PbpInit();

      // display stuff

      void broadcast(int force = no);
      int display(string sectionName);
      void refresh();
      void clear();
      int updateGroup(int group);

      // Tabs

      const char* GetTabbedText(const char* s, int Tab);

      // some structures and types

      struct RecordingInfo 
      {
         string name;
         const cDevice* device;
      };

      typedef vector <RecordingInfo> RecordingInfos;
   
      struct ReplayInfo 
      {
         DisplayMode lastMode;
         string name;
         string fileName;
         cControl* control;
      };

      struct CalibrationPos
      {
         int x;
         int y;
      };

      struct MenuItem 
      {
         string text;
         string tabs[MaxTabs];
         int tabCount;
         Ts::MenuItemType type;
      };
   
      struct MenuInfo 
      {
         DisplayMode lastMode;
         int currentPos;
         int currentPosLast;
         int topPos;
         int lineHeight;
         string title;
         string current;
         string buttons[4];
         string text;
         int textStartLine;
         vector<MenuItem> items;
         int charInTabs[MaxTabs+1];
      };

      // display contents

      cThemeSection* currentSection;
      cThemeSection* lastSection;
      ChannelType channelType;
      DisplayMode _mode;
      string _sectionName;

      int _channel;

      bool _mute;
      int _volume;

      int _showRecording;

      const cEvent* _presentEvent;
      const cEvent* _followingEvent;
      string _channelText;
      string _channelInfo;
      const cEvent* _event;

      string _recording;
      ReplayInfo _replay;

      string _message;
      RecordingInfos _recordings;
      MenuInfo _menu;
      CalibrationPos calibrationPos;

      int displayActive;
      int snapshotPending;

   protected:

      // thread

      virtual void Action();

      // helper functions

      void takeSnapshot();
      bool StoppedTimer(const char *Name);
      void UpdateProgramme();

      // status interface

      virtual void ChannelSwitch(const cDevice* Device, int ChannelNumber);
      virtual void OsdSetEvent(const cEvent* event);
      virtual void OsdSetRecording(const cRecording* recording);
      virtual void OsdChannel(const char* Text);
      virtual void OsdProgramme(time_t PresentTime, const char* PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle);
      virtual void SetVolume(int Volume, bool Absolute);
      virtual void Replaying(const cControl *Control, const char *Name, const char *FileName, bool On);
      virtual void Recording(const cDevice *Device, const char *Name, const char *FileName, bool On);
      virtual void OsdStatusMessage(const char *Message);
      virtual void OsdTitle(const char* Title);
      virtual void OsdItem(const char* Text, int Index);
      virtual void OsdCurrentItem(const char *Text);
      virtual void OsdClear();
      virtual void OsdHelpKeys(const char* Red, const char* Green, const char* Yellow, const char* Blue);
      virtual void OsdTextItem(const char* Text, bool Scroll);
      virtual void OsdMenuDisplay(const char* kind);
      virtual void OsdMenuDestroy();

   private:

      // renderer

      Renderer* _render;
      int isDummyRender;
      ComThread* comThread;

      // thread control

      bool _active;
      cMutex _mutex;
      cCondVar _doUpdate;

      //

      int forceNextDraw;

      // pbp stuff

      bool _pbpActive;
      cDevice* _dev;
      const cChannel* _chan;
      cGraphTFTTransfer* _transfer;
};

//***************************************************************************
#endif // __GTFT_DISPLAY_H
