/*
 * autotimeredit: A plugin for the Video Disk Recorder
 *
 * See the README file for copyright information and how to reach the author.
 *
 * $Id: menudictionary.c 1.7 2005/10/19 23:22:17 hflor Exp $
 */

#include "autotimeredit.h"
#include "ddictionary.h"
#include "menudictionary.h"
#include "i18n.h"
#include "vdrtools.h"
// --- cMenuEditDictionary --------------------------------------------------------

cMenuEditDictionary::cMenuEditDictionary(cDefaultDictionary *DefaultDictionary, bool New)
:cOsdMenu(tr("Edit$Edit DefaultDictionary"), 30)
{
#ifdef ATE_Debug2
  dsyslog("%s: cMenuEditDictionary::cMenuEditDictionary DefaultDictionary=%s New=%s", plugin_name, DefaultDictionary ? DefaultDictionary->Dictionary() : "(null)", New ? "true" : "false");
#endif
  defaultdictionary = DefaultDictionary;
  isdictionarselect = false;
  dictionarypos = -1;
  dictionarysel = 0;
  addIfConfirmed = New;
  if (defaultdictionary) {
     data = *defaultdictionary;
     Set();
  }
}

cMenuEditDictionary::~cMenuEditDictionary()
{
#ifdef ATE_Debug2
  dsyslog("%s: cMenuEditDictionary::~cMenuEditDictionary DefaultDictionary=%s addIfConfirmed=%s", plugin_name, defaultdictionary ? defaultdictionary->Dictionary() : "(null)", addIfConfirmed ? "true" : "false");
#endif
  if (defaultdictionary  && addIfConfirmed)
    delete defaultdictionary; // apparently it wasn't confirmed
}

void cMenuEditDictionary::Set(void)
{
#ifdef ATE_Debug2
  dsyslog("%s: cMenuEditDictionary::Set Current=%d", plugin_name, Current());
#endif
  int current = Current();
  dictionarypos = -1;
  Clear();
  Add(new cMenuEditBoolItem(tr("Edit$Entrytyp"),                                &data.blacklist, tr("Choise$shown"), tr("Choise$hidden")));
  if (data.blacklist)
    Add(new cMenuEditBoolItem(tr("Edit$Include Subdictionarys"),                &data.includesub));
  dictionarypos = Count();
  if (isdictionarselect)
    Add(new cMenuEditStraItem(tr("Edit$Dictionary for Record <>"),              &dictionarysel, CountDefaultDictionarys, SelDefaultDictionary));
  else
    Add(new cMenuEditStrItem(tr("Edit$Dictionary for Record"),                  data.dictionary, sizeof(data.dictionary), tr(FileNameChars)));
  SetCurrent(Get(current));
}

eOSState cMenuEditDictionary::ProcessKey(eKeys Key)
{
#ifdef ATE_Debug3
  bool noneKey = Key == kNone;
  if (!noneKey)
    dsyslog("%s: cMenuEditDictionary::ProcessKey Key=%s", plugin_name, KeyName(Key));
#endif

  static int oldhelpkeys;
  int helpkeys;
#if VDRVERSNUM < 10307
  static char oldstatus[MAXOSDTEXTWIDTH];
  char status[MAXOSDTEXTWIDTH];
  int pathlen;
#endif
  int m_blacklist = data.blacklist;

  eOSState state = cOsdMenu::ProcessKey(Key);

#ifdef ATE_Debug3
  if (!noneKey || (state != osUnknown && state != osContinue)) {
    dsyslog("%s: cMenuEditDictionary::ProcessKey OSState=%s", plugin_name, OSStateName(state));
    noneKey = false;
  }
#endif

  if (m_blacklist != data.blacklist) {
    Set();
    Display();
  }
  if (state == osUnknown) {
    switch (Key) {
      case kOk:     if (Current() != dictionarypos || !isdictionarselect) {
                      if (isdictionarselect)
                        strn0cpy(data.dictionary, SelDefaultDictionary[dictionarysel], sizeof(data.dictionary));
                      if (!strlen(data.dictionary)) {
                        ERROR(tr("Error$Missing dictionary!"));
                        break;
                      }
                      if (defaultdictionary) {
                        if (memcmp(defaultdictionary, &data, sizeof(data)) != 0) { // no char* used
                          *defaultdictionary = data;
                          if (addIfConfirmed)
                            SetupDefaultDictionarys.Add(defaultdictionary);
                          if (verbose.u)
                            isyslog("%s: defaultdictionary %d %s (%s) [%s]", plugin_name, defaultdictionary->Index() + 1, addIfConfirmed ? "added" : "modified", defaultdictionary->dictionary, defaultdictionary->blacklist ? "blacklist" : "whitelist");
                          addIfConfirmed = false;
                        }
                      }
                      return osBack;
                    } // no break!
      case kBlue:   if (Current() == dictionarypos && CountDefaultDictionarys > 1) {
                      if (isdictionarselect)
                        strn0cpy(data.dictionary, SelDefaultDictionary[dictionarysel], sizeof(data.dictionary));
                      else
                        dictionarysel = DefaultDictionarys.SearchDictionary(data.dictionary);
                      isdictionarselect = !isdictionarselect;
                      Set();
                      Display();
                    } // no break!
      case kRed:
      case kGreen:
      case kYellow: state = osContinue;
      default: break;
    }
  }
#if VDRVERSNUM < 10307
  if (Current() == dictionarypos) {
    if (isdictionarselect)
      strn0cpy(data.dictionary, SelDefaultDictionary[dictionarysel], sizeof(data.dictionary));
    pathlen = strlen(data.dictionary);
    if (pathlen > AKTOSDTEXTWIDTH - 10) {
      sprintf(status, "...%s", &data.dictionary[pathlen - AKTOSDTEXTWIDTH + 10]);
    } else
      strcpy(status, data.dictionary);
    if (oldstatus != status) {
      SetStatus(status);
      strcpy(oldstatus, status);
    }
  } else
    if (strlen(oldstatus)) {
      SetStatus(NULL);
      oldstatus[0] = 0;
    }
#endif

  if (Current() == dictionarypos && CountDefaultDictionarys > 1)
    helpkeys = isdictionarselect ? 1 : 2;
  else
    helpkeys = 0;
  if (oldhelpkeys != helpkeys || Key == kOk) {
    oldhelpkeys = helpkeys;
    switch (helpkeys) {
      case 0: SetHelp(NULL, NULL, NULL, NULL);
              break;
      case 1: SetHelp(NULL, NULL, NULL, tr("Edit$Input"));
              break;
      case 2: SetHelp(NULL, NULL, NULL, tr("Edit$Select"));
              break;
    }
  }

#ifdef ATE_Debug3
  if (!noneKey || (state != osUnknown && state != osContinue))
    dsyslog("%s: cMenuEditDictionary::ProcessKey returned OSState=%s", plugin_name, OSStateName(state));
#endif
  return state;
}

// --- cMenuDictionaryItem --------------------------------------------------------

cMenuDictionaryItem::cMenuDictionaryItem(cDefaultDictionary *DefaultDictionary)
{
#ifdef ATE_Debug2
  dsyslog("%s: cMenuDictionaryItem::cMenuDictionaryItem DefaultDictionary=%s", plugin_name, DefaultDictionary ? DefaultDictionary->Dictionary() : "(null)");
#endif
  defaultdictionary = DefaultDictionary;
  Set();
}

#if VDRVERSNUM >= 10315
int cMenuDictionaryItem::Compare(const cListObject &ListObject) const
{
  const cMenuDictionaryItem *MDI = (cMenuDictionaryItem *)&ListObject;
  return defaultdictionary->Compare(*(MDI->defaultdictionary));
}
#else
bool cMenuDictionaryItem::operator< (const cListObject &ListObject)
{
  return *defaultdictionary < *((cMenuDictionaryItem *)&ListObject)->defaultdictionary;
}
#endif

void cMenuDictionaryItem::Set(void)
{
  char *buffer = NULL;
  asprintf(&buffer, "%s\t%s",
  defaultdictionary->Blacklist() ? defaultdictionary->Includesub() ? "--" : "-" : "+", defaultdictionary->Dictionary());
  SetText(buffer, false);
#ifdef ATE_Debug2
  dsyslog("%s: cMenuDictionaryItem::Set SetText=%s", plugin_name, buffer);
#endif
}

// --- cMenuDictionarys -----------------------------------------------------------

cMenuDictionarys::cMenuDictionarys(void)
:cOsdMenu(tr("Display$DefaultDictionary"), 3)
{
#ifdef ATE_Debug2
  dsyslog("%s: cMenuDictionarys::cMenuDictionarys", plugin_name);
#endif
  cDefaultDictionary *defaultdictionary = SetupDefaultDictionarys.First();
  while (defaultdictionary) {
    Add(new cMenuDictionaryItem(defaultdictionary));
    defaultdictionary = SetupDefaultDictionarys.Next(defaultdictionary);
  }
  Sort();
  SetHelpKeys();
}

void cMenuDictionarys::SetHelpKeys(void)
{
#ifdef ATE_Debug2
  dsyslog("%s: cMenuDictionarys::SetHelpKeys", plugin_name);
#endif
  if (Count())
    SetHelp(tr("Edit"), tr("New"), tr("Delete"), tr("On/Off"));
  else
    SetHelp(NULL, tr("New"), NULL, NULL);
}

eOSState cMenuDictionarys::Edit(void)
{
#ifdef ATE_Debug2
  dsyslog("%s: cMenuDictionarys::Edit", plugin_name);
#endif
  if (HasSubMenu() || !CurrentDefaultDictionary())
    return osContinue;
  isyslog("%s: editing defaultdictionary %d", plugin_name, CurrentDefaultDictionary()->Index() + 1);
  return AddSubMenu(new cMenuEditDictionary(CurrentDefaultDictionary()));
}

eOSState cMenuDictionarys::New(void)
{
#ifdef ATE_Debug2
  dsyslog("%s: cMenuDictionarys::New", plugin_name);
#endif
  if (HasSubMenu())
    return osContinue;
  return AddSubMenu(new cMenuEditDictionary(new cDefaultDictionary, true));
}

eOSState cMenuDictionarys::Delete(void)
{
#ifdef ATE_Debug2
  dsyslog("%s: cMenuDictionarys::Delete", plugin_name);
#endif
  cDefaultDictionary *cdd = CurrentDefaultDictionary();
  if (cdd) {
    if (Interface->Confirm(tr("Edit$Delete Default Dictionary?"))) {
      isyslog("%s: defaultdictionary %d deleted", plugin_name, cdd->Index() + 1);
      SetupDefaultDictionarys.Del(cdd);
      cOsdMenu::Del(Current());
      Display();
    }
  }
  return osContinue;
}

eOSState cMenuDictionarys::OnOff(void)
{
#ifdef ATE_Debug2
  dsyslog("%s: cMenuDictionarys::OnOff", plugin_name);
#endif
  cDefaultDictionary *cdd = CurrentDefaultDictionary();
  if (cdd) {
    cdd->OnOff();
    RefreshCurrent();
    DisplayCurrent(true);
  }
  return osContinue;
}

cDefaultDictionary *cMenuDictionarys::CurrentDefaultDictionary(void)
{
#ifdef ATE_Debug2
  dsyslog("%s: cMenuDictionarys::CurrentDefaultDictionary", plugin_name);
#endif
  cMenuDictionaryItem *item = (cMenuDictionaryItem *)Get(Current());
  return item ? item->DefaultDictionary() : NULL;
}

eOSState cMenuDictionarys::ProcessKey(eKeys Key)
{
#ifdef ATE_Debug3
  bool noneKey = Key == kNone;
  if (!noneKey)
    dsyslog("%s: cMenuDictionarys::ProcessKey Key=%s", plugin_name, KeyName(Key));
#endif

  cOsdItem *Item;
  int n;
  int nDefaultDictionarys = SetupDefaultDictionarys.Count();
  bool hSubMenu = HasSubMenu();

  eOSState state = cOsdMenu::ProcessKey(Key);

#ifdef ATE_Debug3
  if (!noneKey || (state != osUnknown && state != osContinue)) {
    dsyslog("%s: cMenuDictionarys::ProcessKey OSState=%s", plugin_name, OSStateName(state));
    noneKey = false;
  }
#endif

  if (!HasSubMenu() && hSubMenu) {
    if (nDefaultDictionarys == SetupDefaultDictionarys.Count())
      Item = Get(Current());
    else
      Add((Item = new cMenuDictionaryItem(SetupDefaultDictionarys.Get(nDefaultDictionarys))));
    Sort();
    SetCurrent(Item);
    Display();
  }

  switch (state) {
    case osUnknown: switch (Key) {
                      case k0...k9: n = (Key == k0) ? 10 : (Key - k0);
                                    if (n > Count())
                                      break;
                                    SetCurrent(Get(--n));
                                    // no break!
                      case kOk:
                      case kRed:    state = Edit(); break;
                      case kGreen:  state = New(); break;
                      case kYellow: state = Delete(); break;
                      case kBlue:   state = OnOff(); break;
                      default: break;
                    }
                    break;
    default:        break;
  }
  if (!HasSubMenu() && Key != kNone)
    SetHelpKeys();

#ifdef ATE_Debug3
  if (!noneKey || (state != osUnknown && state != osContinue))
    dsyslog("%s: cMenuDictionarys::ProcessKey returned OSState=%s", plugin_name, OSStateName(state));
#endif
  return state;
}
