#include "region.h"
#include "page.h"
#include <vdr/osd.h>
#include <vdr/thread.h>
#include "viewer.h"
#include "configuration.h"
#include "subtitle.h"


SubtitlesViewer::SubtitlesViewer(  )
    :iOsd( NULL ), iShowing( false ),iCurrentPage(0)
{

  iMutex = new cMutex();

}
SubtitlesViewer::~SubtitlesViewer()
{
  cMutexLock lock(iMutex);
  iShowing = false;
  if (iCurrentPage)
      delete iCurrentPage;
  cOsd* tmp = iOsd;
  iOsd = NULL;
  delete tmp;
  
}

void SubtitlesViewer::Show()
{
 
  cMutexLock lock(iMutex);
#if DEBUG
  fprintf(stderr, "viewer::show\n");
#endif
  iShowing = true;
  DrawPage();
}

void SubtitlesViewer::Hide()
{
  cMutexLock lock(iMutex);
#if DEBUG
  fprintf(stderr, "viewer::hide\n");
#endif
  iShowing = false;
  if ( iOsd ){
//    iOsd->Hide( iWinHandle );
      cOsd* tmp = iOsd;
      iOsd = NULL;
    delete tmp;
  }
  iOsd = NULL;

}

void SubtitlesViewer::Flush()
{
  cMutexLock lock(iMutex);
  if (iOsd)
    iOsd->Flush();
}

void SubtitlesViewer::Clear()
{
  cMutexLock lock(iMutex);
  if (iCurrentPage != NULL)
  {
      delete iCurrentPage;
      iCurrentPage = 0;
  }
  if (iOsd)
  {
      cOsd* tmp = iOsd;
      iOsd = NULL;
    delete tmp;
    iOsd = NULL;
  }
  if ( !iShowing )
    return;
  iOsd = cOsdProvider::NewOsd( 0, gSubtitlesConfiguration.offset, true );

}

void enforceRange(int& value, int min, int max)
{
    if (value < min)
	value=min;

    if (value >max)
	value=max;
}
void SubtitlesViewer::SetPage( cSubtitlesPage* page )
{

  cMutexLock lock(iMutex);
  Clear();
  iCurrentPage = page;
  DrawPage();

}

void SubtitlesViewer::DrawPage()
{

  cMutexLock lock(iMutex);

  if (!gSubtitlesConfiguration.enabled)
      return;

  if (!iCurrentPage || !iShowing)
      return;

  if (!iOsd)
      iOsd = cOsdProvider::NewOsd( 0, gSubtitlesConfiguration.offset, true );
      

  if (!iOsd)
    return;

  SubtitleList subtitles = iCurrentPage->GetSubtitles();
 
  int numAreas = 0;
  tArea areas[MAXOSDAREAS];

  for (SubtitleList::iterator i = subtitles.begin(); 
       i != subtitles.end(); 
       i++ )
  {

      cSubtitle* subtitle = *i;
      cBitmap* bitmap = subtitle->GetBitmap();
      if (bitmap == NULL)
         continue; // zero-sized area?

      int x = subtitle->X();
      int y = subtitle->Y();
      int w = bitmap->Width();
      int h = bitmap->Height();


      w += w%4; // osd must be multiples of 4, works for 2 and 4 bpp

      // sanity checks
      enforceRange(w, 0, 720);
      enforceRange(h, 0, 576);

      enforceRange(x, 0, 720);
      enforceRange(y, 0, 576);

      tArea area = {x,y,x+w-1, y+h-1, gSubtitlesConfiguration.dxr3comp?2:4};
      areas[numAreas++] = area;
  }

  if (iOsd->CanHandleAreas(areas, numAreas) != oeOk)
  {
      dsyslog("DVB Subs: OSD can't handle areas - subtitles not shown\n");
      return;
  }
  
  iOsd->SetAreas(areas, numAreas);

  for (SubtitleList::iterator i = subtitles.begin(); 
       i != subtitles.end(); 
       i++ )
  {
      cSubtitle* subtitle = *i;
      cBitmap* bitmap = subtitle->GetBitmap();
      if (bitmap == NULL)
         continue; // zero-sized area?

      int x = subtitle->X();
      int y = subtitle->Y();
      
      enforceRange(x, 0, 720);
      enforceRange(y, 0, 576);

      iOsd->DrawBitmap( x, y , *bitmap );
  }
  Flush();

}


