/*
 * videostatus.c: Keeping track of video status information
 *
 * See the main source file 'skinelchi.c' for copyright information and
 * how to reach the author.
 *
 * $Id$
 */

#include <sys/ioctl.h>

#include "config.h"
#include "common.h"
#include "vdrstatus.h"  // für ReplayingName
#include "videostatus.h"

#define DEV_DVB_VIDEO     "/dev/dvb/adapter%d/video%d"

#ifdef DVB_OLDER_20050331
#error DVB_OLDER_20050331 is no longer supported with this version of skinelchi
#endif

// --------------------- VideoStatus -----------------------------
cVideoStatus::cVideoStatus(void)
:cThread("skinelchi-video-status")
{
   DSYSLOG("skinelchi: cVideoStatus::cVideoStatus() is called")

#ifdef SKINELCHI_USE_AVARDS_PLUGIN
   avards = cPluginManager::GetPlugin("avards");
#else
   avards = NULL;
#endif
}

cVideoStatus::~cVideoStatus()
{
   DSYSLOG("skinelchi: cVideoStatus::~cVideoStatus() is called")
   Stop();
}

void cVideoStatus::Stop()
{
   DSYSLOG("skinelchi: cVideoStatus::Stop() is called")
   if (Running()) {
      Cancel(-1);
      Wait.Signal();
   }
}

void cVideoStatus::Activate(bool active)
{
   bool using_avards = false;

   // ElchiConfig.videoinfo abfragen ??

#ifdef SKINELCHI_USE_AVARDS_PLUGIN
   if (avards) {
      avards_CurrentVideoFormat_v1_0 videoformat;
      avards->Service(AVARDS_CURRENT_VIDEO_FORMAT_SERVICE_STRING_ID, &videoformat);
      using_avards = videoformat.Mode != AVARDS_VIDEOMODE_UNKNOWN;
   }
#endif

   if (active) {
      if (!using_avards)
         Start();
   }
   else
      Stop();
}

bool cVideoStatus::GetVideoInfo(cVideoInfo *videoinfo)
{
   if (Running()) {
      Lock();
      videoinfo->height      = height;
      videoinfo->width       = width;
      videoinfo->aspectratio = aspectratio;
      Unlock();
      return true;
   }
#ifdef SKINELCHI_USE_AVARDS_PLUGIN
   else {
      if (avards) {
         avards_CurrentVideoFormat_v1_0 videoformat;
         avards->Service(AVARDS_CURRENT_VIDEO_FORMAT_SERVICE_STRING_ID, &videoformat);
         //isyslog("skinelchi: cVideoStatus avards %d*%d %X %s", videoformat.Width, videoformat.Height, videoformat.Mode, videoformat.ModeString);
         videoinfo->width  = videoformat.Width;
         videoinfo->height = videoformat.Height;

         switch (videoformat.Mode) {
            case AVARDS_VIDEOMODE_4_3:
               videoinfo->aspectratio = ar4_3;
               break;
            case AVARDS_VIDEOMODE_L14_9:
               videoinfo->aspectratio = arL14_9;
               break;
            case AVARDS_VIDEOMODE_L16_9:
               videoinfo->aspectratio = arL16_9;
               break;
            case AVARDS_VIDEOMODE_LG16_9:
               videoinfo->aspectratio = arL16_9;
               break;
            case AVARDS_VIDEOMODE_16_9:
               videoinfo->aspectratio = ar16_9;
               break;
            default:
               videoinfo->aspectratio = ar_unknown;
               break;
         }
         return true;
      }
   }
#endif

   return  false;
}

void cVideoStatus::Action(void)
{
   DSYSLOG("skinelchi: cVideoStatus::Action()")

   int fd_video = -1;

   if (cDevice::PrimaryDevice()->HasDecoder() && ElchiConfig.showVideoInfo) {
      char dev[sizeof(DEV_DVB_VIDEO)];
      snprintf(dev, sizeof(dev), DEV_DVB_VIDEO, cDevice::PrimaryDevice()->CardIndex(), 0);
      fd_video = open(dev, O_RDONLY | O_NONBLOCK);
      if (fd_video < 0) {
         esyslog("skinelchi: opening video device %s failed", dev);
         return;
      }
   }

   while (Running()) {
      video_size_t vs;
      int rc = ioctl(fd_video, VIDEO_GET_SIZE, &vs);
      Lock();
      if (rc == 0) {
         width = vs.w;
         height = vs.h;
         switch (vs.aspect_ratio) {
            case VIDEO_FORMAT_4_3:
               aspectratio = ar4_3;
               break;
            case VIDEO_FORMAT_16_9:
               aspectratio = ar16_9;
               break;
            case VIDEO_FORMAT_221_1:
               aspectratio = ar221_1;
               break;
            default:
               aspectratio = ar_unknown;
               break;
         }

         DSYSLOG2("skinelchi: cVideoStatus %d*%d %d", vs.w, vs.h, vs.aspect_ratio)
      }
      else {
         width = 0;
         height = 0;
         aspectratio = ar_unknown;
         DSYSLOG2("skinelchi: cVideoStatus Error, rc=%d", rc)
      }
      Unlock();

      if (Running())
         Wait.Wait(250);

   } // while Running()

   Lock();
   width = 0;
   height = 0;
   aspectratio = ar_unknown;
   Unlock();

   close(fd_video);

   DSYSLOG("skinelchi: cVideoStatus - Action end")
}
