#include "DisplayMessage.h"
#include "setup.h"
#if VDRVERSNUM >= 10332
#include <vdr/device.h>
#endif
#ifdef VIDEOSTATUS
#include "videostatus.h"
#endif
extern bool vdrosd;
// --- cSkinElchiDisplayMessage --------------------------------------------

bool messagechanged;
int MessageScrollPid;
cCharScroll MessageScroll;

cSkinElchiDisplayMessage::cSkinElchiDisplayMessage(void)
{
  noflush = true;
#ifdef DEBUG
  isyslog("skinelchi: cSkinElchiDisplayMessage::cSkinElchiDisplayMessage()");
#endif
#ifdef VIDEOSTATUS
  VideoStatus.Update();
#endif
  font = cFont::GetFont(fontOsd);
  lh = font->Height();
  lhh = lh / 2;
#ifdef VIDEOSTATUS
  if (SkinElchiSetup.videostatus)
    vdrosd = (VideoStatus.NTSC() == (SkinElchiSetup.videosystem == vsNTSC));
  else
#endif
    vdrosd = (cDevice::PrimaryDevice()->GetVideoSystem() == vsNTSC) == (SkinElchiSetup.videosystem == vsNTSC);
  osd = cOsdProvider::NewOsd(vdrosd ? Setup.OSDLeft : SkinElchiSetup.osdleft, (vdrosd ? (Setup.OSDTop + Setup.OSDHeight) : (SkinElchiSetup.osdtop + SkinElchiSetup.osdheight)) - lh);
  tArea Areas[] = { { 0, 0, (vdrosd ? Setup.OSDWidth : SkinElchiSetup.osdwidth) - 1, lh - 1, 2 } };
  osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
  messagechanged = true;
  MessageScroll.Font = font;
  MessageScroll.DestWidth = osd->Width() - lh;
  MessageScroll.xOff = lhh;
  MessageScroll.yOff = 0;
  MessageScroll.delay = 10;
  scrolltext = new cMessageScrollText;
  noflush = false;
}

cSkinElchiDisplayMessage::~cSkinElchiDisplayMessage()
{
#ifdef DEBUG
  isyslog("skinelchi: cSkinElchiDisplayMessage::~cSkinElchiDisplayMessage()");
#endif
  noflush = true;
  messagechanged = true;
  MessageScroll.dir = 0;
  MessageScrollPid--;
  delete osd;
}

void cSkinElchiDisplayMessage::SetMessage(eMessageType Type, const char *Text)
{
#ifdef DEBUG
  isyslog("skinelchi: cSkinElchiDisplayMessage::SetMessage(%d,%s)", (int)Type, Text);
#endif
  MessageScrollPid = 0;
  messagechanged = true;
  tColor tr = Theme.Color(Transparent);
  int h1 = osd->Height() - 1;
  int lh21 = lh / 2 - 1;
  osd->DrawRectangle(0, 0, lh21, h1, tr);
  tColor msb = Theme.Color(clrMessageStatusBg + 2 * Type);
  osd->DrawEllipse(0, 0, lh21, h1, msb, 7);
  MessageScroll.Fg = Theme.Color(clrMessageStatusFg + 2 * Type);
  MessageScroll.Bg = msb;
  if (MessageScroll.SetText(Text)) {
    MessageScroll.pos = 0;
    MessageScroll.dir = -1;
    MessageScroll.Time.Set();
    osd->DrawText(MessageScroll.xOff, MessageScroll.yOff, MessageScroll.Text, MessageScroll.Fg, MessageScroll.Bg, MessageScroll.Font, MessageScroll.DestWidth);
    }
  else
    MessageScroll.dir = 0;
  osd->DrawText(MessageScroll.xOff, MessageScroll.yOff, MessageScroll.Text, MessageScroll.Fg, MessageScroll.Bg, MessageScroll.Font, MessageScroll.DestWidth, 0, taCenter);
  int wlh2 = osd->Width() - lh / 2;
  osd->DrawRectangle(wlh2 - 1, 0, wlh2, h1, msb);
  int w1 = osd->Width() - 1;
  osd->DrawRectangle(wlh2, 0, w1, h1, tr);
  osd->DrawEllipse(wlh2, 0, w1, h1, msb, 5);
}

void cSkinElchiDisplayMessage::Flush(void)
{
if (!noflush) {
  noflush = true;
  scrolltext->noflush = true;
  if (MessageScroll.dir) {//for scrolling
    if (MessageScroll.DrawNeeded()) {
        for (int i = 0; i < MessageScroll.DestWidth; i++) {
	    for (int j = 0; j < MessageScroll.Height(); j++)
		osd->DrawPixel(MessageScroll.xOff + i, MessageScroll.yOff + j, MessageScroll.bmp->Color(*(MessageScroll.bmp->Data(i + MessageScroll.pos, j))));
	    }
	messagechanged = true;
	}
    }
  if (messagechanged) {
    messagechanged = false;
#ifdef DEBUG
    isyslog("skinelchi: cSkinElchiDisplayMessage::Flush()");
#endif
    osd->Flush();
    }
#ifdef DEBUG
  else
    isyslog("skinelchi: skip cSkinElchiDisplayMessage::Flush()");
#endif
  scrolltext->noflush = false;
  noflush = false;
  }
#ifdef DEBUG
  else
    isyslog("skinelchi: skip cSkinElchiDisplayMessage::Flush() because cSkinElchiDisplayMessage::Flush() is active");
#endif
}

cMessageScrollText::cMessageScrollText(void) {
#ifdef DEBUG
    isyslog("skinelchi: DisplayMessage - cMessageScrollText::cMessageScrollText()");
#endif
    Start();
}

cMessageScrollText::~cMessageScrollText() {
#ifdef DEBUG
    isyslog("skinelchi: DisplayMessage - cMessageScrollText::~cMessageScrollText()");
#endif
    MessageScrollPid--;
}

void cMessageScrollText::Action(void) {
    pid = (int)getpid();
    MessageScrollPid = pid;
    while (MessageScrollPid == pid) {
	if (MessageScroll.dir && ((int)MessageScroll.Time.Elapsed() / MessageScroll.intervall)) {
		if (!messagechanged && !noflush) {
#ifdef DEBUG
		    isyslog("skinelchi: cMessageScrollText call Skins.Flush()");
#endif
    		    if (Skins.IsOpen())
			Skins.Flush();
		    }
	    }
	cCondWait::SleepMs(9);
	}
#ifdef DEBUG
    isyslog("skinelchi: cMessageScrollText - thread end (pid=%d)", pid);
#endif
}
