#ifdef VIDEOSTATUS
#include <sys/ioctl.h>
#endif
#include <vdr/menu.h>
#include "DisplayReplay.h"
#include "setup.h"
#include "vdrstatus.h"
#ifdef VIDEOSTATUS
#include "videostatus.h"
#endif
#if VDRVERSNUM >= 10332
#include <vdr/device.h>
#endif
#include "symbols/ffwd.xpm"
#include "symbols/ffwd1.xpm"
#include "symbols/ffwd2.xpm"
#include "symbols/ffwd3.xpm"
#include "symbols/ffwd4.xpm"
#include "symbols/ffwd5.xpm"
#include "symbols/ffwd6.xpm"
#include "symbols/ffwd7.xpm"
#include "symbols/ffwd8.xpm"
#include "symbols/frew.xpm"
#include "symbols/frew1.xpm"
#include "symbols/frew2.xpm"
#include "symbols/frew3.xpm"
#include "symbols/frew4.xpm"
#include "symbols/frew5.xpm"
#include "symbols/frew6.xpm"
#include "symbols/frew7.xpm"
#include "symbols/frew8.xpm"
#include "symbols/pause.xpm"
#include "symbols/play.xpm"
#include "symbols/recording.xpm"
#include "symbols/sfwd.xpm"
#include "symbols/sfwd1.xpm"
#include "symbols/sfwd2.xpm"
#include "symbols/sfwd3.xpm"
#include "symbols/sfwd4.xpm"
#include "symbols/sfwd5.xpm"
#include "symbols/sfwd6.xpm"
#include "symbols/sfwd7.xpm"
#include "symbols/sfwd8.xpm"
#include "symbols/srew.xpm"
#include "symbols/srew1.xpm"
#include "symbols/srew2.xpm"
#include "symbols/srew3.xpm"
#include "symbols/srew4.xpm"
#include "symbols/srew5.xpm"
#include "symbols/srew6.xpm"
#include "symbols/srew7.xpm"
#include "symbols/srew8.xpm"

cBitmap cSkinElchiDisplayReplay::bmFfwd(ffwd_xpm);
cBitmap cSkinElchiDisplayReplay::bmFfwd1(ffwd1_xpm);
cBitmap cSkinElchiDisplayReplay::bmFfwd2(ffwd2_xpm);
cBitmap cSkinElchiDisplayReplay::bmFfwd3(ffwd3_xpm);
cBitmap cSkinElchiDisplayReplay::bmFfwd4(ffwd4_xpm);
cBitmap cSkinElchiDisplayReplay::bmFfwd5(ffwd5_xpm);
cBitmap cSkinElchiDisplayReplay::bmFfwd6(ffwd6_xpm);
cBitmap cSkinElchiDisplayReplay::bmFfwd7(ffwd7_xpm);
cBitmap cSkinElchiDisplayReplay::bmFfwd8(ffwd8_xpm);
cBitmap cSkinElchiDisplayReplay::bmFrew(frew_xpm);
cBitmap cSkinElchiDisplayReplay::bmFrew1(frew1_xpm);
cBitmap cSkinElchiDisplayReplay::bmFrew2(frew2_xpm);
cBitmap cSkinElchiDisplayReplay::bmFrew3(frew3_xpm);
cBitmap cSkinElchiDisplayReplay::bmFrew4(frew4_xpm);
cBitmap cSkinElchiDisplayReplay::bmFrew5(frew5_xpm);
cBitmap cSkinElchiDisplayReplay::bmFrew6(frew6_xpm);
cBitmap cSkinElchiDisplayReplay::bmFrew7(frew7_xpm);
cBitmap cSkinElchiDisplayReplay::bmFrew8(frew8_xpm);
cBitmap cSkinElchiDisplayReplay::bmPause(pause_xpm);
cBitmap cSkinElchiDisplayReplay::bmPlay(play_xpm);
cBitmap cSkinElchiDisplayReplay::bmSfwd(sfwd_xpm);
cBitmap cSkinElchiDisplayReplay::bmSfwd1(sfwd1_xpm);
cBitmap cSkinElchiDisplayReplay::bmSfwd2(sfwd2_xpm);
cBitmap cSkinElchiDisplayReplay::bmSfwd3(sfwd3_xpm);
cBitmap cSkinElchiDisplayReplay::bmSfwd4(sfwd4_xpm);
cBitmap cSkinElchiDisplayReplay::bmSfwd5(sfwd5_xpm);
cBitmap cSkinElchiDisplayReplay::bmSfwd6(sfwd6_xpm);
cBitmap cSkinElchiDisplayReplay::bmSfwd7(sfwd7_xpm);
cBitmap cSkinElchiDisplayReplay::bmSfwd8(sfwd8_xpm);
cBitmap cSkinElchiDisplayReplay::bmSrew(srew_xpm);
cBitmap cSkinElchiDisplayReplay::bmSrew1(srew1_xpm);
cBitmap cSkinElchiDisplayReplay::bmSrew2(srew2_xpm);
cBitmap cSkinElchiDisplayReplay::bmSrew3(srew3_xpm);
cBitmap cSkinElchiDisplayReplay::bmSrew4(srew4_xpm);
cBitmap cSkinElchiDisplayReplay::bmSrew5(srew5_xpm);
cBitmap cSkinElchiDisplayReplay::bmSrew6(srew6_xpm);
cBitmap cSkinElchiDisplayReplay::bmSrew7(srew7_xpm);
cBitmap cSkinElchiDisplayReplay::bmSrew8(srew8_xpm);
cBitmap cSkinElchiDisplayReplay::bmRecording(recording_xpm);

#ifdef VIDEOSTATUS
extern int fd_video;
#endif
extern bool vdrosd;
// --- cSkinElchiDisplayReplay ---------------------------------------------

cSkinElchiDisplayReplay::cSkinElchiDisplayReplay(bool ModeOnly)
{
  noflush = true;
#ifdef DEBUG
  isyslog("skinelchi: cSkinElchiDisplayReplay::cSkinElchiDisplayReplay(%s)", ModeOnly ? "'ModeOnly'" : "'nonModeOnly'");
#endif
#ifdef VIDEOSTATUS
  asprintf(&oldtitlestatus, " ");
  VideoStatus.Update();
  oldbm = NULL;
#endif
  asprintf(&oldcurrentChar, " ");
  modeonly = ModeOnly;
  showVolume = false;
  volumechange = VdrStatus.VolumeChange;
  rec = false;
  asprintf(&title, " ");
  asprintf(&oldtitle, " ");
  message = false;
  cBitmap bm(play_xpm);
  lastCurrentWidth = 0;
  font = cFont::GetFont(fontOsd);
  smallfont = cFont::GetFont(fontSml);
  lh = font->Height();
  lhh = lh / 2;
  x0 = 0;
#ifdef VIDEOSTATUS
  if (SkinElchiSetup.videostatus)
    vdrosd = (VideoStatus.NTSC() == (SkinElchiSetup.videosystem == vsNTSC));
  else
#endif
    vdrosd = (cDevice::PrimaryDevice()->GetVideoSystem() == vsNTSC) == (SkinElchiSetup.videosystem == vsNTSC);
  x1 = x0 + (vdrosd ? Setup.OSDWidth : SkinElchiSetup.osdwidth);
  x2 = x1 - lh - smallfont->Width("00:00:00 / 00:00:00");
  x3 = x1 - lh - bmRecording.Width() - 3 - bmFrew.Width() - 3 - bmSrew.Width() - 3 - bmPlay.Width() - 3 - bmSfwd.Width() - 3 - bmFfwd.Width(); 
#ifdef VIDEOSTATUS
  if ((fd_video >= 0) && (SkinElchiSetup.videostatus & 1))
    x3 -= bmRecording.Width()/*dummy*/ + 3;
#endif
  x4 = x2 - 2 * lh;
  x5 = x3 - 2 * lh;
  y0 = 0;
  y1 = lh;
  y2 = 2 * lh;
  y3 = 3 * lh;

  osd = cOsdProvider::NewOsd(vdrosd ? Setup.OSDLeft : SkinElchiSetup.osdleft, (vdrosd ? (Setup.OSDTop + Setup.OSDHeight) : (SkinElchiSetup.osdtop + SkinElchiSetup.osdheight)) - y3);
  tArea Areas[] = { { x0, y0, x1 - 1, y3 - 1, 4 } };
  osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
  bg = Theme.Color(clrBackground);
  tColor tr = Theme.Color(Transparent);
  if (ModeOnly) {
    osd->DrawRectangle(x0, y0, x1 - 1, y2 - 1, tr);
    osd->DrawRectangle(x3, y2, x3 + lhh - 1, y3 - 1, tr);
    osd->DrawEllipse(x3, y2, x3 + lhh - 1, y3 - 1, bg, 7);
    osd->DrawRectangle(x3 + lhh, y2, x1 - lhh - 1, y3 - 1, bg);
    osd->DrawRectangle(x1 - lhh, y2, x1 - 1, y3 - 1, tr);
    osd->DrawEllipse(x1 - lhh, y2, x1 - 1, y3 - 1, bg, 5);
    }
  else {
    osd->DrawRectangle(x0, y0, x2 - 1, y1 - 1, tr);
    osd->DrawSlope(x4, y0, x2 - 1, y1 - 1, bg, 0);

    osd->DrawRectangle(x2, y0, x1 - lhh - 1, y1 - 1, bg);

    osd->DrawRectangle(x1 - lhh, y0, x1 - 1, y1 - lhh - 1, tr);
    osd->DrawEllipse(x1 - lhh, y0, x1 - 1, y1 - lhh - 1, bg, 1);

    osd->DrawRectangle(x0 + lhh, y1, x0 + lh - 1, y2 - 1, tr);
    osd->DrawEllipse(x0 + lhh, y1, x0 + lh - 1, y2 - 1, bg, 7);
    osd->DrawRectangle(x0 + lh, y1, x1 - lhh - 1, y2 - 1, bg);
    osd->DrawRectangle(x2, y0, x1 - lhh - 1, y1 - 1, bg);

    if (Setup.ShowReplayMode) {
	osd->DrawRectangle(x0, y2, x3 - 1, y3 - 1, tr);
	osd->DrawSlope(x5, y2, x3 - 1, y3 - 1, bg, 3);
	osd->DrawRectangle(x1 - lhh, y1 - lhh, x1 - 1, y2 + lhh, bg);
	osd->DrawRectangle(x3, y2, x1 - lhh - 1, y3 - 1, bg);
	osd->DrawRectangle(x1 - lhh, y3 - lhh, x1 - 1, y3 - 1, tr);
	osd->DrawEllipse(x1 - lhh, y3 - lhh, x1 - 1, y3 - 1, bg, 4);
	}
    else {
	osd->DrawRectangle(x1 - lhh, y1 - lhh, x1 - 1, y1 + lhh, bg);
	osd->DrawRectangle(x1 - lhh, y2 - lhh, x1 - 1, y2 - 1, tr);
	osd->DrawEllipse(x1 - lhh, y2 - lhh, x1 - 1, y2 - 1, bg, 4);
	}
    }
    TitleScroll.DestWidth = x4 - x0;
    TitleScroll.Fg = Theme.Color(clrReplayTitleFg);
    TitleScroll.Bg = Theme.Color(clrReplayTitleBg);
    TitleScroll.Font = smallfont;
    TitleScroll.xOff = x0;
    TitleScroll.yOff = y0;
    TitleScroll.delay = 20;
    TitleScroll.intervall = 7;
  changed = true;
  noflush = false;
}

cSkinElchiDisplayReplay::~cSkinElchiDisplayReplay()
{
  noflush = true;
  if (oldcurrentChar != NULL)
    free(oldcurrentChar);
#ifdef DEBUG
  isyslog("skinelchi: cSkinElchiDisplayReplay::~cSkinElchiDisplayReplay()");
#endif
#ifdef VIDEOSTATUS
    if (fd_video != -1 && !SkinElchiSetup.videostatus) {
	close(fd_video);
	fd_video = -1;
	}
  if (oldtitlestatus)
    free(oldtitlestatus);
#endif
  if (title)
    free(title);
  if (oldtitle)
    free(oldtitle);
  delete osd;
  changed = true;
}

void cSkinElchiDisplayReplay::SetTitle(const char *Title)
{
#ifdef DEBUG
  isyslog("skinelchi: cSkinElchiDisplayReplay::SetTitle(%s)", Title);
#endif
  if (title && !showVolume) {
    if (oldtitle && Title) {
	if (!strcmp(oldtitle, Title))
    	    return;
	else
	    free(oldtitle);
	}
	asprintf(&oldtitle,"%s", Title);
    free(title);
    }
  asprintf(&title," %s ", Title);
  int w = smallfont->Width(title);
  if (w > TitleScroll.DestWidth)
    w = TitleScroll.DestWidth;
  int h = font->Height() - smallfont->Height();
  if (TitleScroll.SetText(title)) {
    TitleScroll.pos = 0;
    TitleScroll.dir = -1;
    TitleScroll.Time.Set();
    osd->DrawText(x0, y0, TitleScroll.Text, Theme.Color(clrReplayTitleFg), Theme.Color(clrReplayTitleBg), TitleScroll.Font, TitleScroll.DestWidth);
    }
  else {
    osd->DrawText(x0, y0, title, Theme.Color(clrReplayTitleFg), Theme.Color(clrReplayTitleBg), TitleScroll.Font, w);
    TitleScroll.dir = 0;
    tColor tr = Theme.Color(Transparent);
    osd->DrawRectangle(w, y0, w + 3 - 1, y0 + 3 - 1, tr);
    osd->DrawRectangle(w + 3, y0, x4 - 1, y1 - h - 1, tr);
    osd->DrawRectangle(x4, y0 + 3, x4 + 3 - 1, y1 - h - 1, tr);
    if (h)
	osd->DrawRectangle(w + 3, y1 - h, x4 + 3 - 1, y1 - h + 3 - 1, Theme.Color(Transparent));
    }
  osd->DrawRectangle(w, y0 + 3, w + 3 - 1, y1 - h + 3 - 1, bg);
  osd->DrawRectangle(x0 + 3, y1 - h, w - 1, y1 - h + 3 - 1, bg);
  changed = true;
}

void cSkinElchiDisplayReplay::SetMode(bool Play, bool Forward, int Speed)
{
#ifdef DEBUG
  isyslog("skinelchi: cSkinElchiDisplayReplay::SetMode(%s,%s,Speed=%d)", Play ? "'Play'" : "'nonPlay'", Forward ? "'Forward'" : "'nonForward'", Speed);
#endif
  if (Setup.ShowReplayMode) {
    tColor off = Theme.Color(clrReplaySymbolOff);
    int x = x3 + y1 / 2;
    int y = y3 - y2;
    if (Speed < -1)
	Speed = -1;
    if (Speed > 9)
        Speed = 9;
    rec = cRecordControls::Active();
//    osd->DrawBitmap(x, y2 + (y - bmRecording.Height()) / 2, bmRecording, Theme.Color(rec ? clrChannelSymbolRecFg : clrChannelSymbolOff), rec ? Theme.Color(clrChannelSymbolRecBg) : bg);
    osd->DrawBitmap(x, y2 + (y - bmRecording.Height()) / 2, bmRecording, rec ? Theme.Color(clrChannelSymbolRecFg) : off, rec ? Theme.Color(clrChannelSymbolRecBg) : bg);
    x += bmFrew.Width() + 3;
    cBitmap *bm = NULL;
    if ((Speed > -1) && Play && !Forward) {
        switch (Speed) {
            case 0:
	    case 1: bm = &bmFrew; break;
	    case 2: bm = &bmFrew1; break;
	    case 3: bm = &bmFrew2; break;
	    case 4: bm = &bmFrew3; break;
	    case 5: bm = &bmFrew4; break;
	    case 6: bm = &bmFrew5; break;
	    case 7: bm = &bmFrew6; break;
	    case 8: bm = &bmFrew7; break;
	    case 9: bm = &bmFrew8; break;
	    }
	osd->DrawBitmap(x, y2 + (y - bm->Height()) / 2, *bm, Theme.Color(clrReplaySymbolOn), bg);
	}
    else
	osd->DrawBitmap(x, y2 + (y - bmFrew.Height()) / 2, bmFrew, off, bg);
    x += bmFrew.Width() + 3;

    if ((Speed > -1) && !Play && !Forward) {
        switch (Speed) {
            case 0: 
            case 1: bm = &bmSrew; break;
            case 2: bm = &bmSrew1; break;
            case 3: bm = &bmSrew2; break;
            case 4: bm = &bmSrew3; break;
            case 5: bm = &bmSrew4; break;
            case 6: bm = &bmSrew5; break;
            case 7: bm = &bmSrew6; break;
            case 8: bm = &bmSrew7; break;
            case 9: bm = &bmSrew8; break;
	    }
	osd->DrawBitmap(x, y2 + (y - bm->Height()) / 2, *bm, Theme.Color(clrReplaySymbolOn), bg);
	}
    else
        osd->DrawBitmap(x, y2 + (y - bmSrew.Height()) / 2, bmSrew, off, bg);
    x += bmSrew.Width() + 3;

    if (Speed == -1)
	osd->DrawBitmap(x, y2 + (y - bmPlay.Height()) / 2, Play ? bmPlay : bmPause, Theme.Color(clrReplaySymbolOn), bg);
    else
        osd->DrawBitmap(x, y2 + (y - bmPlay.Height()) / 2, bmPlay, off, bg);
    x += bmPlay.Width() + 3;
     
    if ((Speed > -1) && !Play && Forward) {
        switch (Speed) {
            case 0: 
            case 1: bm = &bmSfwd; break;
            case 2: bm = &bmSfwd1; break;
            case 3: bm = &bmSfwd2; break;
            case 4: bm = &bmSfwd3; break;
            case 5: bm = &bmSfwd4; break;
            case 6: bm = &bmSfwd5; break;
            case 7: bm = &bmSfwd6; break;
            case 8: bm = &bmSfwd7; break;
            case 9: bm = &bmSfwd8; break;
	    }
	osd->DrawBitmap(x, y2 + (y - bm->Height()) / 2, *bm, Theme.Color(clrReplaySymbolOn), bg);
	}
    else
	osd->DrawBitmap(x, y2 + (y - bmSfwd.Height()) / 2, bmSfwd, off, bg);
    x += bmSfwd.Width() + 3;

    if ((Speed > -1) && Play && Forward) {
        switch (Speed) {
            case 0: 
	    case 1: bm = &bmFfwd; break;
            case 2: bm = &bmFfwd1; break;
            case 3: bm = &bmFfwd2; break;
            case 4: bm = &bmFfwd3; break;
            case 5: bm = &bmFfwd4; break;
            case 6: bm = &bmFfwd5; break;
            case 7: bm = &bmFfwd6; break;
            case 8: bm = &bmFfwd7; break;
            case 9: bm = &bmFfwd8; break;
	    }
	osd->DrawBitmap(x, y2 + (y - bm->Height()) / 2, *bm, Theme.Color(clrReplaySymbolOn), bg);
	}
    else
        osd->DrawBitmap(x, y2 + (y - bmFfwd.Height()) / 2, bmFfwd, off, bg);
    changed = true;
    }
}

void cSkinElchiDisplayReplay::SetProgress(int Current, int Total)
{
#ifdef DEBUG
  isyslog("skinelchi: cSkinElchiDisplayReplay::SetProgress(%d,%d)", Current, Total);
#endif
  if (!showVolume) {
    cProgressBar pb(x1 - x0 - y1 - y1 / 2, y2 - y1 - 8, Current, Total, marks, Theme.Color(clrReplayProgressSeen), Theme.Color(clrReplayProgressRest), Theme.Color(clrReplayProgressSelected), Theme.Color(clrReplayProgressMark), Theme.Color(clrReplayProgressCurrent));
    osd->DrawBitmap(x0 + y1, y1 + 4, pb);
    changed = true;
    }
}

void cSkinElchiDisplayReplay::SetCurrent(const char *Current)
{
    
  if (strcmp(oldcurrentChar, Current)) {
#ifdef DEBUG
    isyslog("skinelchi: cSkinElchiDisplayReplay::SetCurrent(%s)", Current);
#endif
    asprintf(&oldcurrentChar, "%s", Current);
    int v = smallfont->Width("00:00:00");
    char *current;
    asprintf(&current,"%s %s ", Current, "/");
    int w = smallfont->Width(current);
    int x = x1 - v - y1 / 2;
    osd->DrawText(x - w, y0, current, Theme.Color(clrReplayCurrent), Theme.Color(clrBackground), smallfont);
    if (lastCurrentWidth > w)
	osd->DrawRectangle(x - lastCurrentWidth, y0, x - w - 1, y1 - 1, Theme.Color(clrBackground));
    free(current);
    lastCurrentWidth = w;
    changed = true;
    }
#ifdef DEBUG
  else
    isyslog("skinelchi: skipped cSkinElchiDisplayReplay::SetCurrent(%s)", Current);
#endif
}

void cSkinElchiDisplayReplay::SetTotal(const char *Total)
{
#ifdef DEBUG
  isyslog("skinelchi: cSkinElchiDisplayReplay::SetTotal(%s)", Total);
#endif
  osd->DrawText(x1 - smallfont->Width(Total) - y1 / 2, y0, Total, Theme.Color(clrReplayTotal), Theme.Color(clrBackground), smallfont);
  changed = true;
}

void cSkinElchiDisplayReplay::SetJump(const char *Jump)
{
#ifdef DEBUG
  isyslog("skinelchi: cSkinElchiDisplayReplay::SetJump(%s)", Jump);
#endif
  int w = font->Width(Jump);
  if (w > 0)
    osd->DrawText(x5 - w, y2, Jump, Theme.Color(clrReplayModeJump), Theme.Color(clrBackground), font, w);
  else
    osd->DrawRectangle(x0, y2, x5 - 1, y3 - 1, Theme.Color(Transparent));
  changed = true;
}

void cSkinElchiDisplayReplay::SetMessage(eMessageType Type, const char *Text)
{
#ifdef DEBUG
  isyslog("skinelchi: cSkinElchiDisplayReplay::SetMessage(%d,%s)", (int)Type, Text);
#endif
  if (Text) {
    char *text;
    asprintf(&text, "%s", Text);
/*    if (!strcasecmp(text, tr("Going to sleep in about one minute"))) {
	asprintf(&text, "\"%s\" <- Sleeptimer-Message received -> not printed on screen", Text);
	esyslog(text);
	}
    else */{
	tColor msbg = Theme.Color(clrMessageStatusBg + 2 * Type);
	int y = y3 - 1;
	if (!message) {
	    osd->SaveRegion(x0, y2, x1 - 1, y);
	    message = true;
	    }
	osd->DrawEllipse(x0, y2, lhh - 1, y, msbg, 7);
        osd->DrawText(x0 + lhh, y2, Text, Theme.Color(clrMessageStatusFg + 2 * Type), msbg, font, x1 - x0 - 2 * lhh, y3 - y2, taCenter);
	osd->DrawEllipse(x1 - lhh, y2, x1 - 1, y, msbg, 5);
	changed = true;
	}
    free(text);
    }
  else {
    if (message) {
	osd->RestoreRegion();
	message = false;
	changed = true;
	}
    }
}

void cSkinElchiDisplayReplay::Flush(void)
{
if (!noflush) {
    noflush = true;
#ifdef VIDEOSTATUS
    if (fd_video >= 0) {
	char *titlestatus;
	asprintf(&titlestatus, "%s", title);
	int videoformat = VideoStatus.Ar();
	if (SkinElchiSetup.videostatus & 2)
 	    asprintf(&titlestatus, "%s %d*%d %s", titlestatus, VideoStatus.Width(), VideoStatus.Height(), VideoStatus.VideoFormat());
	if (videoformat != -1) {
	    cBitmap *bm = VideoStatus.DFbmp();
	    if (SkinElchiSetup.videostatus & 2)
		asprintf(&titlestatus, " %s %s", titlestatus, VideoStatus.DisplayFormat());
	    if ((SkinElchiSetup.videostatus & 1) && bm != oldbm && !message && Setup.ShowReplayMode) {
	        changed = true;
	        if (bm)
    		    osd->DrawBitmap(x1 - y1/2 - bm->Width(), y2 + (y3 - y2 - bm->Height()) / 2, *bm, Theme.Color(clrReplaySymbolOn), Theme.Color(clrBackground));
		else
    		    osd->DrawRectangle(x1 - y1/2 - bmRecording.Width()/*dummy*/, y2, x1 - y1/2 - 1, y3 - 1, Theme.Color(clrBackground));
		}
	    if (!bm && (SkinElchiSetup.videostatus & 2))
/*test*/
	        asprintf(&titlestatus, "%s - no videostatus available ", titlestatus);
	    }
/*test*/	else if (SkinElchiSetup.videostatus & 2)
		    asprintf(&titlestatus, "%s - no videosize available ", titlestatus);
	if (!modeonly && !showVolume && strcmp(oldtitlestatus, titlestatus)) {
	    asprintf(&oldtitlestatus, "%s", titlestatus);
	    int w = TitleScroll.Font->Width(titlestatus);
	    if (w > TitleScroll.DestWidth)
	        w = TitleScroll.DestWidth;
	    int h = font->Height() - smallfont->Height();
	    if (TitleScroll.SetText(titlestatus)) {
		if (!TitleScroll.dir) {
		    TitleScroll.pos = 0;
		    TitleScroll.dir = -1;
		    TitleScroll.delay = 20;
		    TitleScroll.Time.Set();
		    osd->DrawText(TitleScroll.xOff, TitleScroll.yOff, TitleScroll.Text, TitleScroll.Fg, TitleScroll.Bg, TitleScroll.Font, TitleScroll.DestWidth);
		    }
		}
	    else {
		osd->DrawText(TitleScroll.xOff, TitleScroll.yOff, TitleScroll.Text, TitleScroll.Fg, TitleScroll.Bg, TitleScroll.Font, w);
		TitleScroll.dir = 0;
		tColor tr = Theme.Color(Transparent);
		osd->DrawRectangle(w, y0, w + 3 - 1, y0 + 3 - 1, tr);
		osd->DrawRectangle(w + 3, y0, x4 - 1, y1 - h - 1, tr);
		osd->DrawRectangle(x4, y0 + 3, x4 + 3 - 1, y1 - h - 1, tr);
		if (h)
		    osd->DrawRectangle(w + 3, y1 - h, x4 + 3 - 1, y1 - h + 3 - 1, Theme.Color(Transparent));
		}
	    osd->DrawRectangle(w, y0 + 3, w + 3 - 1, y1 - h + 3 - 1, bg);
	    osd->DrawRectangle(x0 + 3, y1 - h, w - 1, y1 - h + 3 - 1, bg);
	    changed = true;
	    }
	free(titlestatus);
	}
    else {
	if (!modeonly && !showVolume && strcmp(oldtitlestatus, title)) {
	    asprintf(&oldtitlestatus, "%s", title);
	    int w = smallfont->Width(title);
	    if (w > TitleScroll.DestWidth)
	        w = TitleScroll.DestWidth;
	    int h = font->Height() - smallfont->Height();
	    if (TitleScroll.SetText(title)) {
		w = TitleScroll.DestWidth;
		if (!TitleScroll.dir) {
		    TitleScroll.pos = 0;
		    TitleScroll.dir = -1;
		    TitleScroll.delay = 20;
		    TitleScroll.Time.Set();
		    osd->DrawText(x0, y0, title, Theme.Color(clrReplayTitleFg), Theme.Color(clrReplayTitleBg), smallfont, w);
		    }
		}
	    else {
		osd->DrawText(x0, y0, title, Theme.Color(clrReplayTitleFg), Theme.Color(clrReplayTitleBg), smallfont, w);
		TitleScroll.dir = 0;
		tColor tr = Theme.Color(Transparent);
		osd->DrawRectangle(w, y0, w + 3 - 1, y0 + 3 - 1, tr);
		osd->DrawRectangle(w + 3, y0, x4 - 1, y1 - h - 1, tr);
		osd->DrawRectangle(x4, y0 + 3, x4 + 3 - 1, y1 - h - 1, tr);
		if (h)
		    osd->DrawRectangle(w + 3, y1 - h, x4 + 3 - 1, y1 - h + 3 - 1, Theme.Color(Transparent));
		}
	    osd->DrawRectangle(w, y0 + 3, w + 3 - 1, y1 - h + 3 - 1, bg);
	    osd->DrawRectangle(x0 + 3, y1 - h, w - 1, y1 - h + 3 - 1, bg);
	    changed = true;
	    }
	}
#endif
    if (!modeonly && TitleScroll.dir) {//for scrolling
	if (TitleScroll.DrawNeeded()) {
	    for (int i = 0; i < TitleScroll.DestWidth; i++) {
		for (int j = 0; j < TitleScroll.Height(); j++)
		    osd->DrawPixel(TitleScroll.xOff + i, TitleScroll.yOff + j, TitleScroll.bmp->Color(*(TitleScroll.bmp->Data(i + TitleScroll.pos, j))));
		}
	    changed = true;
	    }
	}

    if (Setup.ShowReplayMode && !message) {
	bool rectemp = cRecordControls::Active();
	if (rec != rectemp) {
	    rec = rectemp;
//	    osd->DrawBitmap(x3 + y1 / 2, y2 + (y3 - y2 - bmRecording.Height()) / 2, bmRecording, Theme.Color(rec ? clrChannelSymbolRecFg : clrChannelSymbolOff), rec ? Theme.Color(clrChannelSymbolRecBg) : bg);
	    osd->DrawBitmap(x3 + y1 / 2, y2 + (y3 - y2 - bmRecording.Height()) / 2, bmRecording, rec ? Theme.Color(clrChannelSymbolRecFg) : Theme.Color(clrReplaySymbolOff), rec ? Theme.Color(clrChannelSymbolRecBg) : bg);
	    changed = true;
	    }
	}

    if (VdrStatus.VolumeChange != volumechange) {
	volumechange = VdrStatus.VolumeChange;
	oldvolume = VdrStatus.Volume;
	int x = x0 + y1;
	int w = x1 - y1 / 2;
	int y = y1 + 4;
	int h = y2 - 5;
	if (!showVolume) {
	    showVolume = true;
    	    if (modeonly) {
    		osd->SaveRegion(x0, y0, x1 - 1, y2 - 1);
		tColor tr = Theme.Color(Transparent);
		osd->DrawRectangle(x1 - lhh, y1, x1 - 1, y2 - lhh - 1, tr);
		osd->DrawEllipse(x1 - lhh, y1, x1 - 1, y2 - lhh - 1, bg, 1);
		osd->DrawRectangle(x0 + lhh, y1, x0 + lh - 1, y2 - 1, tr);
		osd->DrawEllipse(x0 + lhh, y1, x0 + lh - 1, y2 - 1, bg, 7);
		osd->DrawRectangle(x0 + lh, y1, x1 - lhh - 1, y2 - 1, bg);
		osd->DrawRectangle(x0, y2, x3 - 1, y3 - 1, tr);
		osd->DrawSlope(x5, y2, x3 - 1, y3 - 1, bg, 3);
		osd->DrawRectangle(x3, y2, x3 + lhh - 1, y3 - 1, bg);
		osd->DrawRectangle(x1 - lhh, y2 - lhh, x1 - 1, y2 + lhh, bg);
		}
	    else
    		osd->SaveRegion(x, y, w, h);
	    SetTitle(tr("Volume "));
	    }
	int p = (w - x) * oldvolume / 255;
	int xp = x + p;
	osd->DrawRectangle(x, y, xp - 1, h, Theme.Color(clrVolumeBarUpper));
	osd->DrawRectangle(xp, y, w - 1, h, Theme.Color(clrVolumeBarLower));
	changed = true;
	volume.Set(1000);
	}
     else {
	if (showVolume) {
	    if (volume.TimedOut()) {
    		osd->RestoreRegion();
		if (modeonly) {
		    tColor tr = Theme.Color(Transparent);
		    osd->DrawRectangle(x5, y2, x3 + lhh - 1, y3 - 1, tr);
		    osd->DrawEllipse(x3, y2, x3 + lhh - 1, y3 - 1, bg, 7);
		    osd->DrawRectangle(x1 - lhh, y2, x1 - 1, y3 - 1, tr);
		    osd->DrawEllipse(x1 - lhh, y2, x1 - 1, y3 - 1, bg, 5);
		    }
		else {
#ifdef VIDEOSTATUS
		    if (oldtitlestatus)
			free(oldtitlestatus);
		    asprintf(&oldtitlestatus," ");
#endif
    		    SetTitle(oldtitle);
		    }
    		showVolume = false;
		changed = true;
		}
	    }
	}

    if (changed) {
#ifdef DEBUG
	isyslog("skinelchi: cSkinElchiDisplayReplay::Flush()");
#endif
        osd->Flush();
	changed = false;
	}
#ifdef DEBUG
    else
	isyslog("skinelchi: skipped cSkinElchiDisplayReplay::Flush()");
#endif
    noflush = false;
    }
#ifdef DEBUG
else
  isyslog("skinelchi: skip cSkinElchiDisplayReplay::Flush() because cSkinElchiDisplayReplay::Flush() is active");
#endif
}

