#include "services/remotetimers.h"
#include "channelepg.h"
#include "tools.h"
#include "epggrid.h"

cEpgGrid::cEpgGrid(cChannelEpg *c, const cEvent *event)  : cGridElement(c) {
    this->event = event;
    extText = new cTextWrapper();
    hasTimer = false;
    SetTimer();
    hasSwitchTimer = false;
    SetSwitchTimer();
    dummy = false;
}

cEpgGrid::~cEpgGrid(void) {
    delete extText;
}

void cEpgGrid::SetViewportHeight() {
    int viewportHeightOld = viewportHeight;
    if ( column->Start() > StartTime() ) {
        viewportHeight = (min((int)EndTime(), column->Stop()) - column->Start()) /60;
    } else if ( column->Stop() < EndTime() ) {
        viewportHeight = (column->Stop() - StartTime()) /60;
        if (viewportHeight < 0) viewportHeight = 0;
    } else {
        viewportHeight = Duration() / 60;
    }
    viewportHeight *= geoManager.minutePixel;
    if (viewportHeight != viewportHeightOld)
        dirty = true;
}

void cEpgGrid::PositionPixmap() {
    if (config.displayMode == eVertical) {
        int x0 = column->getX();
        int y0 = geoManager.statusHeaderHeight + geoManager.channelHeaderHeight + geoManager.channelGroupsHeight;
        if ( column->Start() < StartTime() ) {
            y0 += (StartTime() - column->Start())/60*geoManager.minutePixel;
        }
        if (!pixmap) {
            pixmap = osdManager.requestPixmap(-1, cRect(x0, y0, geoManager.colWidth, viewportHeight),
                                                cRect(0, 0, geoManager.colWidth, Duration()/60*geoManager.minutePixel));
        } else {
            pixmap->SetViewPort(cRect(x0, y0, geoManager.colWidth, viewportHeight));
        }
    } else if (config.displayMode == eHorizontal) {
        int x0 = geoManager.channelHeaderWidth + geoManager.channelGroupsWidth;
        int y0 = column->getY();
        if ( column->Start() < StartTime() ) {
            x0 += (StartTime() - column->Start())/60*geoManager.minutePixel;
        }
        if (!pixmap) {
            pixmap = osdManager.requestPixmap(-1, cRect(x0, y0, viewportHeight, geoManager.rowHeight),
                                                cRect(0, 0, Duration()/60*geoManager.minutePixel, geoManager.rowHeight));
        } else {
            pixmap->SetViewPort(cRect(x0, y0, viewportHeight, geoManager.rowHeight ));
        }
   }

}

void cEpgGrid::SetTimer() {
    hasTimer = false;
    if (config.useRemoteTimers && pRemoteTimers) {
        RemoteTimers_Event_v1_0 rt;
        rt.event = event;
        if (pRemoteTimers->Service("RemoteTimers::GetTimerByEvent-v1.0", &rt))
            hasTimer = true;
#if VDRVERSNUM >= 20301
    } else {
        eTimerMatch TimerMatch = tmNone;
        LOCK_TIMERS_READ;
        const cTimers *timers = Timers;
        if (timers->GetMatch(event, &TimerMatch) && (TimerMatch == tmFull))
            hasTimer = true;
#else
    } else if (column->HasTimer()) {
        hasTimer = event->HasTimer();
#endif
    }
}

void cEpgGrid::SetSwitchTimer() {
    if (column->HasSwitchTimer()) {
        hasSwitchTimer = SwitchTimers.EventInSwitchList(event);
    } else {
        hasSwitchTimer = false;
    }
}

void cEpgGrid::setText() {
    if (config.displayMode == eVertical) {
        text->Set(event->Title(), fontManager.FontGrid, geoManager.colWidth - 2 * borderWidth);
        extText->Set(event->ShortText(), fontManager.FontGridSmall, geoManager.colWidth - 2 * borderWidth);
    }
    if (config.showTimeInGrid) {
        timeString = cString::sprintf("%s - %s:", *(event->GetTimeString()), *(event->GetEndTimeString()));
    }
}

void cEpgGrid::drawText() {
    tColor colorText = (active) ? theme.Color(clrFontActive) : theme.Color(clrFont);
    tColor colorTextBack;
    if (config.style == eStyleFlat)
        colorTextBack = color;
    else if (config.style == eStyleGraphical)
        colorTextBack = (active) ? theme.Color(clrGridActiveFontBack) : theme.Color(clrGridFontBack);
    else
        colorTextBack = clrTransparent;
    if (config.displayMode == eVertical) {
        if (Height() / geoManager.minutePixel < 6)
            return;
        int textHeight = fontManager.FontGrid->Height();
        int textHeightSmall = fontManager.FontGridSmall->Height();
        int textLines = text->Lines();
        int titleY = borderWidth;
        if (config.showTimeInGrid) { // mit Zeitangabe im Grid
            pixmap->DrawText(cPoint(borderWidth, borderWidth), *timeString, colorText, colorTextBack, fontManager.FontGridSmall);
            titleY += textHeightSmall;
        }
        for (int i = 0; i < textLines; i++) {
            pixmap->DrawText(cPoint(borderWidth, titleY + i * textHeight), text->GetLine(i), colorText, colorTextBack, fontManager.FontGrid);
        }
        int extTextLines = extText->Lines();
        int offset = titleY + (textLines + 0.5) * textHeight;
        if ((Height() - textHeightSmall - 10) > offset) {
            for (int i = 0; i < extTextLines; i++) {
                pixmap->DrawText(cPoint(borderWidth, offset + i * textHeightSmall), extText->GetLine(i), colorText, colorTextBack, fontManager.FontGridSmall);
            }
        }
    } else if (config.displayMode == eHorizontal) {
        cString strTitle = CutText(event->Title(), viewportHeight - borderWidth, fontManager.FontGridHorizontal).c_str();
        int titleY = 0;
        if (config.showTimeInGrid) { // mit Zeitangabe im Grid
            pixmap->DrawText(cPoint(borderWidth, borderWidth), *timeString, colorText, colorTextBack, fontManager.FontGridHorizontalSmall);
            titleY = fontManager.FontGridHorizontalSmall->Height() + (geoManager.rowHeight - fontManager.FontGridHorizontalSmall->Height() - fontManager.FontGridHorizontal->Height()) / 2;
        } else {
            titleY = (geoManager.rowHeight - fontManager.FontGridHorizontal->Height()) / 2;
        }
        pixmap->DrawText(cPoint(borderWidth, titleY), *strTitle, colorText, colorTextBack, fontManager.FontGridHorizontal);
    }
    if (hasSwitchTimer)
        drawIcon("Switch", theme.Color(clrButtonYellow));
    if (hasTimer) {
        const cTimer *timer = NULL;
#if VDRVERSNUM >= 20301
        {
        LOCK_TIMERS_READ;
        timer = Timers->GetMatch(event);
        }
#else
        timer = Timers.GetMatch(event);
#endif
	if (timer)
#ifdef SWITCHONLYPATCH
           if (timer->HasFlags(tfSwitchOnly))
              drawIcon("Switch", theme.Color(clrButtonYellow));
           else if (timer->HasFlags(tfActive))
#else /* SWITCHONLY */
           if (timer->HasFlags(tfActive))
#endif /* SWITCHONLY */
              drawIcon("REC", theme.Color(clrButtonRed));
           else
              drawIcon("REC", theme.Color(clrButtonGreen));
        }
}

void cEpgGrid::drawIcon(cString iconText, tColor color) {

    const cFont *font = (config.displayMode == eVertical) ? fontManager.FontGrid : fontManager.FontGridHorizontalSmall;
    int textWidth = font->Width(*iconText) + 2 * borderWidth;
    int textHeight = font->Height() + 10;
    if ((config.displayMode == eHorizontal) && ((Width() - 2 * textWidth) < 0))
        pixmap->DrawEllipse( cRect(Width() - textHeight / 2 - borderWidth, Height() - textHeight - borderWidth, textHeight / 2, textHeight / 2), color);
    else if ((config.displayMode == eVertical) && ((Height() - 2 * textHeight) < 0))
        pixmap->DrawEllipse( cRect(Width() - textHeight / 2 - borderWidth, borderWidth, textHeight / 2, textHeight / 2), color);
    else {
        pixmap->DrawEllipse( cRect(Width() - textWidth - borderWidth, Height() - textHeight - borderWidth, textWidth, textHeight), color);
        pixmap->DrawText(cPoint(Width() - textWidth, Height() - textHeight - borderWidth / 2), *iconText, theme.Color(clrFont), clrTransparent, font);
    }
}

cString cEpgGrid::getTimeString(void) {
    return cString::sprintf("%s - %s", *(event->GetTimeString()), *(event->GetEndTimeString()));
}

void cEpgGrid::debug() {
    esyslog("tvguide epggrid: %s: %s, %s, viewportHeight: %d px, Duration: %d min, active: %d",
                column->Name(),
                *(event->GetTimeString()),
                event->Title(),
                viewportHeight,
                event->Duration()/60,
                active);
}
