/**
 *  GraphTFT plugin for the Video Disk Recorder 
 * 
 *  dvbrenderer.c - A plugin for the Video Disk Recorder
 *
 *  (c) 2004 Lars Tegeler, Sascha Volkenandt  
 *
 * This code is distributed under the terms and conditions of the
 * GNU GENERAL PUBLIC LICENSE. See the file COPYING for details.
 *
 * $Id: dvbrenderer.c,v 1.7 2007/11/10 17:46:54 root Exp $
 *
 **/

#include "common.h"
#include "dvbrenderer.h"
#include "setup.h"
#include "player.h"
#include "quantize.h"
#include <vdr/config.h>

#if VDRVERSNUM >= 10307
# ifdef GETOSDPATCH
#  define USEOSD = 1
# endif
#endif

//----------------------------------------------------------------------
void DvbRenderer::deinit()
{
   if (_Osd)       delete (_Osd);
   if (_quantizer) delete (_quantizer);
   _initialized = -1;
}

//----------------------------------------------------------------------

int DvbRenderer::init(int devnum)
{
	mpeg_init(dspWidth, dspHeight, 25);

	_devTo = cDevice::GetDevice(devnum);
	_player = new cGraphTFTPlayer();

#ifdef USEOSD

	_Osd = _devTo->GetOsd(0, 0);
	d(6,"DvbRenderer: Osd test\n");

  	if (_Osd)
   {
		tArea Area8 = {0 , 0, dspWidth-1, dspHeight-1,  8 };
		_colors = 256;
		_bpp = 8;

		if (_Osd->CanHandleAreas(&Area8, 1) != oeOk)
      {
			tArea Area4 = {0 , 0, dspWidth-1, dspHeight-1,  4 };
			_colors = 16;
			_bpp= 4;

			if (_Osd->CanHandleAreas(&Area4, 1) != oeOk)
         {
				tArea Area2 = {0 , 0, dspWidth-1, dspHeight-1, 2};
				_colors = 4;
				_bpp = 2;

				if (_Osd->CanHandleAreas(&Area2, 1) != oeOk)
            {
					tArea Area1 = {0 , 0, dspWidth-1, dspHeight-1,  1 };	 
					_colors = 2;
					_bpp = 1;

					if (_Osd->CanHandleAreas(&Area1, 1) != oeOk)
						fprintf(stderr, "vdr: GraphTFT Area set ERROR\n");
					else
						_Osd->SetAreas(&Area1, 1);
				}
            else
					_Osd->SetAreas(&Area2, 1);
			}
         else
				_Osd->SetAreas(&Area4, 1);
		}
      else
			_Osd->SetAreas(&Area8, 1);

		_quantizer = new cQuantizeFixed();
		_Osd->Flush();
	}
   else
   {
		_devTo->AttachPlayer(_player);
	}

#else
	_devTo->AttachPlayer(_player);
#endif
	
	_initialized = 1;

   return ImlibRenderer::init(devnum);
}

//----------------------------------------------------------------------

DvbRenderer::DvbRenderer(int x, int y, int width, int height, 
                         string cfgPath, int utf, string thmPath)
   : ImlibRenderer(x, y, width, height, cfgPath, utf, thmPath)
{
   _Osd = 0;
   _quantizer = 0;
   _initialized = -1;
}

DvbRenderer::~DvbRenderer()
{
   deinit();
}

//----------------------------------------------------------------------
void DvbRenderer::refresh()
{  
   ImlibRenderer::refresh();

   imlib_context_set_image(*pImageToDisplay);

#ifdef USEOSD

   if (_Osd)
   {
       cBitmap *bmp;
       unsigned int * outputPalette;
       unsigned char * outputImage;
       unsigned int alpha = 0xFF000000;

       bmp = new cBitmap(imlib_image_get_width(), imlib_image_get_height(), _bpp);
       bmp->SetBpp(_bpp);
   
       uint8_t *data = (uint8_t*)imlib_image_get_data_for_reading_only();
       _quantizer->Quantize(data, imlib_image_get_width()* imlib_image_get_height(), _colors);
       outputPalette = _quantizer->OutputPalette();
       outputImage = _quantizer->OutputImage();

      for (int i = 0; i < _colors; i++)
         bmp->SetColor(i, outputPalette[i] | alpha);

      for (int y = 0; y < bmp->Height(); y++)
      {
         for (int x = 0; x < bmp->Width(); x++)
         {
            bmp->SetIndex(x, y ,  outputImage[y * bmp->Width() + x] );
         }
      }

      _Osd->DrawBitmap(1,1,*bmp);
      _Osd->Flush();
      delete(bmp);
   }

   else
   {

#endif

      UINT8* frame = (UINT8*)imlib_image_get_data_for_reading_only();
      _iframe = mpeg_draw(frame);

      if (_iframe.data[_iframe.size - 1] != 0xb7) 
      {
         // add sequence end code
	 //
         _iframe.data[_iframe.size + 0] = 0x00;
         _iframe.data[_iframe.size + 1] = 0x00;
         _iframe.data[_iframe.size + 2] = 0x01;
         _iframe.data[_iframe.size + 3] = 0xb7;
         _iframe.size += 4;
      }

      _player->setIFrame(_iframe);

#ifdef USEOSD
   }
#endif

   imlib_context_set_image(_cur_image);
}

void DvbRenderer::clear()
{
   ImlibRenderer::clear();
}

//----------------------------------------------------------------------

int DvbRenderer::playVideo(const uchar *Data, int Length)
{
	return _devTo ? _devTo->PlayPes(Data, Length) : 0;
}

bool DvbRenderer::devicePoll(cPoller &Poller, int TimeoutMs)
{
	return _devTo ? _devTo->Poll(Poller, TimeoutMs) : false;
}

void DvbRenderer::setPlayMode(bool Video)
{
	if (_player) _player->setPlayMode(Video);
}

void DvbRenderer::deviceClear(void)
{
	if (_devTo) _devTo->Clear();
}

