#include "menu_switchtimers.h"
#include "tools.h"

// --- cMenuEditSwitchTimer --------------------------------------------------------
class cMenuEditSwitchTimer : public cOsdMenu {
private:
  cSwitchTimer *switchTimer;
  cSwitchTimer data;
  bool addIfConfirmed;
public:
  cMenuEditSwitchTimer(cSwitchTimer *SwitchTimer, bool New = false);
  void Set();
  virtual eOSState ProcessKey(eKeys Key);
};

cMenuEditSwitchTimer::cMenuEditSwitchTimer(cSwitchTimer* SwitchTimer, bool New)
:cOsdMenu(tr("Edit entry"),30)
{
    switchTimer = SwitchTimer;
    addIfConfirmed = New;
    if (switchTimer) 
    {
	data = *switchTimer;
	Set();
    }
}

void cMenuEditSwitchTimer::Set()
{
    int current = Current();
    Clear();

    Add(new cMenuEditIntItem(tr("Switch ... minutes before start"), &data.switchMinsBefore, 0, 99));
    char* info = NULL;
    asprintf(&info, "%s:\t%s", tr("action at"), TIMESTRING(data.event->StartTime() - 60 * data.switchMinsBefore));
    cOsdItem* pInfoItem = new cOsdItem(info);
    free(info);
    pInfoItem->SetSelectable(false);
    Add(pInfoItem);
    Add(new cMenuEditBoolItem(tr("Announce only"), &data.announceOnly, tr("no"), tr("yes")));
    
    SetCurrent(Get(current));
}

eOSState cMenuEditSwitchTimer::ProcessKey(eKeys Key)
{
    int iOldMinsBefore = data.switchMinsBefore;
    eOSState state = cOsdMenu::ProcessKey(Key);

    if (iOldMinsBefore != data.switchMinsBefore)
    {
	time_t now = time(NULL);
	if (data.event->StartTime() - 60 * data.switchMinsBefore < now)
	    data.switchMinsBefore = iOldMinsBefore;
	Set();
	Display();
    }

    if (state == osUnknown) {
	switch (Key) {
	    case kOk:
	    {
		if (switchTimer)
		{
		    *switchTimer = data;
		    if (addIfConfirmed)
			SwitchTimers.Add(switchTimer);	      
		    SwitchTimers.Save();
		}
		addIfConfirmed = false;
		return osBack;
		break;
	    } 
	    default: break;
	}
  }
    return state;
}

cMenuSwitchTimerItem::cMenuSwitchTimerItem(cSwitchTimer* SwitchTimer)
{
  switchTimer = SwitchTimer;
  Set();
}

void cMenuSwitchTimerItem::Set(void)
{
    if (!switchTimer || !switchTimer->event)
	return;

    const cEvent* event = switchTimer->event;
    time_t startTime = event->StartTime();
    char *buffer = NULL;

    char datebuf[32];
    struct tm tm_r;
    tm *tm = localtime_r(&startTime, &tm_r);
    strftime(datebuf, sizeof(datebuf), "%d.%m", tm);

    asprintf(&buffer, "%s\t%s\t%s\t%d\'\t%s~%s", switchTimer->announceOnly?"":">", datebuf, TIMESTRING(startTime), switchTimer->switchMinsBefore, event->Title()?event->Title():"", event->ShortText()?event->ShortText():"");
    SetText(buffer, false);
}

int cMenuSwitchTimerItem::Compare(const cListObject &ListObject) const
{
    cMenuSwitchTimerItem *p = (cMenuSwitchTimerItem *)&ListObject;
    if (switchTimer->event->StartTime() > p->switchTimer->event->StartTime()) 
	return 1; 
    else 
	return -1;
}

// --- cMenuSwitchTimers ----------------------------------------------------------
cMenuSwitchTimers::cMenuSwitchTimers()
:cOsdMenu(tr("Switch list"), 2, 6, 6, 4)
{
    Set();
    Display();
}

void cMenuSwitchTimers::Set()
{
    Clear();
    cSwitchTimer* switchTimer = SwitchTimers.First();
    while (switchTimer) {
	if (switchTimer->event)
	    Add(new cMenuSwitchTimerItem(switchTimer));
	switchTimer = SwitchTimers.Next(switchTimer);
    }
    Display();
    SetHelp(tr("Button$Edit"), tr("Button$Delete all"), tr("Button$Delete"), NULL);
    Sort();
}

cSwitchTimer* cMenuSwitchTimers::CurrentSwitchTimer(void)
{
    cMenuSwitchTimerItem *item = (cMenuSwitchTimerItem *)Get(Current());
    return item ? item->switchTimer : NULL;
}

eOSState cMenuSwitchTimers::Delete(void)
{
    cSwitchTimer *curSwitchTimer = CurrentSwitchTimer();
    if (curSwitchTimer) {
	if (Interface->Confirm(tr("Edit$Delete entry?"))) {
	    SwitchTimers.Del(curSwitchTimer);
	    SwitchTimers.Save();
	    cOsdMenu::Del(Current());
	    Display();
	}
    }
    return osContinue;
}

eOSState cMenuSwitchTimers::DeleteAll(void)
{
    if (Interface->Confirm(tr("Edit$Delete all entries?"))) 
    {
	while (SwitchTimers.First()) 
	    SwitchTimers.Del(SwitchTimers.First());
	SwitchTimers.Save();
	Set();
    }

    return osContinue;
}

eOSState cMenuSwitchTimers::Summary(void)
{
    if (HasSubMenu() || Count() == 0)
	return osContinue;
    cSwitchTimer *curSwitchTimer = CurrentSwitchTimer();
    if (curSwitchTimer && !isempty(curSwitchTimer->event->Description()))
	return AddSubMenu(new cMenuText(tr("Summary"), curSwitchTimer->event->Description()));
    return osContinue;
}

eOSState cMenuSwitchTimers::ProcessKey(eKeys Key)
{
  eOSState state = cOsdMenu::ProcessKey(Key);
  if (state == osUnknown) {
    switch (Key) {
	case kOk:
	    state = Summary();
	    break;
	case kGreen:
	    state = DeleteAll();
	    break;
	case kYellow:
	    state = Delete();
	    break;
	case kRed:
	    if (HasSubMenu())
		return osContinue;
	    if (CurrentSwitchTimer())
		state = AddSubMenu(new cMenuEditSwitchTimer(CurrentSwitchTimer()));
	    else
		state = osContinue;
	    break;
	case k0:
	    if (CurrentSwitchTimer())
	    {
		cSwitchTimer* switchTimer = CurrentSwitchTimer();
	        switchTimer->announceOnly = 1 - switchTimer->announceOnly;
		SwitchTimers.Save();
		RefreshCurrent();
		Display();
	    }
	    break;
      default: break;
    }
  }

  return state;
}
