/*
 * inputsoftdevice.c: input from Softdevice for the Atmolight-plugin
 *
 * See the README file for copyright information and how to reach the author.
 *
 * $Id$
 */

#include <vdr/device.h>
#include <vdr/plugin.h>
#include <vdr/tools.h>

#include "defs.h"
#include "calculations.h"
#include "input.h"
#include "inputsoftdevice.h"

// --- cInputSoftdevice ------------------------------------------------------

cInputSoftdevice::cInputSoftdevice()
{
  char buf[32];

  // length of PNM header to remove
  snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n", CAP_WIDTH, CAP_HEIGHT);
  pnm_header_length = strlen(buf);
}

cInputSoftdevice::~cInputSoftdevice()
{
}

bool cInputSoftdevice::Open(const char* param)
{
  // init variables
  ColorPacket.channel[0].r = ColorPacket.channel[0].g = ColorPacket.channel[0].g = 0;
  ColorPacket.channel[4] = ColorPacket.channel[3] = ColorPacket.channel[2] =
                           ColorPacket.channel[1] = ColorPacket.channel[0];

  // Softdevice-Plugin exists?
  cPlugin *Plugin = cPluginManager::GetPlugin("softdevice");
  if (Plugin)
  {
    Start(); // start thread
    return true;
  }
  else
  {
    return false;
  }
}

bool cInputSoftdevice::Close(void)
{
  Cancel(); // stop thread

  return true;
}

void cInputSoftdevice::Action(void)
{
  cTimeMs t;

  while (Running()) // in this loop the picture is read and the colors are calculated
  {
    t.Set(0);

    CalcColors(); // read picture and calculate colors

    if (t.Elapsed() < 20) // wait 20ms to avoid 100% CPU usage
    {
      cCondWait::SleepMs(20);
    }
  }
}

void cInputSoftdevice::CalcColors(void)
{
  tRGBColor RGB_Img;
  tHSVColor HSV_Img[IMAGE_SIZE];

  int ImageSize;
  uchar *Image = cDevice::PrimaryDevice()->GrabImage(ImageSize, false, 100, CAP_WIDTH, CAP_HEIGHT);
  if (Image) // format: PIX_FMT_BGR24
  {
    uchar *tmpImage = Image + pnm_header_length;

    if (ImageSize != IMAGE_SIZE)
    {
      esyslog("Atmolight: ImageSize != IMAGE_SIZE");
    }

    // generate HSV image
    for (int i = 0; i < IMAGE_SIZE; i++) // walk through map
    {
      // generate RGB pixel
      RGB_Img.r = *tmpImage++;
      RGB_Img.g = *tmpImage++;
      RGB_Img.b = *tmpImage++;

      // generate HSV pixel
      HSV_Img[i] = RGB2HSV(RGB_Img);
    }

    ColorPacket = CalcColorsAnalyzeHSV(HSV_Img);

    free(Image);
  }
}
