/* config.c
 *
 * See the README file for copyright information and how to reach the author.
 *
 */

#include <vdr/font.h>
#include "config.h"


cMusicConfig MusicConfig;

#ifdef HAVE_FREETYPE
#if VDRVERSNUM != 10503
cMusicFont FontCache;
#endif

struct NoCase {
  bool operator()(const string& x, const string& y) {
    string lv(x);
    string rv(y);
    lcase(lv);
    lcase(rv);
    return lv < rv;
  }
  
  void lcase(string& s) {
    int n = s.size();
    for(int i = 0; i < n; i++)
      s[i] = tolower(s[i]);
  }
};            
#endif

FontConfig allFontConfig[FONT_NUMFONTS] =
{
  { FONT_TOP,         (char*)"FontTop",        (char*)"FontTopName" },
  { FONT_STATUS,      (char*)"FontStatus",     (char*)"FontStatusName" },
  { FONT_LIST,        (char*)"FontList",       (char*)"FontListName" },
  { FONT_LISTACTIVE,  (char*)"FontListActive", (char*)"FontListActiveName" },
  { FONT_TITLE,       (char*)"FontTitle",      (char*)"FontTitleName" },
  { FONT_INFO,        (char*)"FontInfo",       (char*)"FontInfoName" },
  { FONT_BOTTOM,      (char*)"FontBottom",     (char*)"FontBottomName" }
};

cMusicConfig::cMusicConfig()
{
#ifdef HAVE_FREETYPE
  availTTFs = NULL;
  nMaxTTFs = 0;
  memset(strFontsDir, 0, sizeof(strFontsDir));
#endif

  for (int id = 0; id < FONT_NUMFONTS; id++) {
    switch (id) {
      case FONT_TOP:
      case FONT_LIST:
      case FONT_INFO:
      case FONT_BOTTOM:
        allFonts[id].VdrId = fontSml +1;
	allFonts[id].Default = fontSml;
	break;
      
      default:
        allFonts[id].VdrId = fontOsd +1;
	allFonts[id].Default = fontOsd;
    }
    memset(allFonts[id].Name, 0, sizeof(allFonts[id].Name));
    allFonts[id].Width = 100;
    allFonts[id].Size  =  26;
  }
}

cMusicConfig::~cMusicConfig()
{
#ifdef HAVE_FREETYPE
  printf("DestroyMusicConfig\n");

  if(availTTFs) {
    char **ptr = availTTFs;
    while(*ptr) {
      delete(*ptr);
      ptr++;
    }
//    free(availTTFs);
    availTTFs = NULL;
  }      
#endif
}

#ifdef HAVE_FREETYPE
void cMusicConfig::SetFontsDir(const char *dir)
{
  if(dir) {
    printf("Music: FontDir: '%s'\n", dir);
    strncpy(strFontsDir, dir, sizeof(strFontsDir));
  }    
}


const char **cMusicConfig::GetAvailTTFs(void)
{
  if (availTTFs == NULL) {
    std::vector<std::string> vecFonts;
    cReadDir d(GetFontsDir());
    struct dirent *e;
    while ((e = d.Next()) != NULL) {
      if ((strcmp(e->d_name, ".") != 0) && (strcmp(e->d_name, "..") != 0)) {
        if (strcmp(e->d_name + strlen(e->d_name) - 4, ".ttf") == 0) {
          printf("Loading %s\n", e->d_name);
          vecFonts.push_back(std::string(e->d_name));
        } else {
          printf("Ignoring non-font file: %s\n", e->d_name);
        }
      }
    }

    if (vecFonts.size() > 0) {
      sort(vecFonts.begin(), vecFonts.end(), NoCase());
      availTTFs = (char **)calloc(vecFonts.size() + 1, sizeof(char*));
      if (availTTFs) {
        char **ptr = availTTFs;
        for (vector<std::string>::iterator i = vecFonts.begin(); i != vecFonts.end(); i++) {
          if (!(*i).empty()) {
            *ptr = strdup((*i).c_str());
            ptr++;
            nMaxTTFs++;
          }
        }
      }
    }

    vecFonts.clear();
  }

  return (const char**)availTTFs;
}
#endif




const cFont *cMusicConfig::GetFont(int id, const cFont *pFontCur)
{
  const cFont *res = NULL;
  if(::Setup.UseSmallFont == 1) {
    if (allFonts[id].VdrId == FONT_TRUETYPE) {
      if(pFontCur)
        return pFontCur;
      if(!isempty(allFonts[id].Name)) {	
#ifdef HAVE_FREETYPE
        char *cachename;
#if VDRVERSNUM < 10503
        asprintf(&cachename, "%s_%d_%d_%d", allFonts[id].Name, allFonts[id].Size, allFonts[id].Width, Setup.OSDLanguage);
        if (FontCache.Load(string(strFontsDir) + "/" + string(allFonts[id].Name), cachename, allFonts[id].Size, Setup.OSDLanguage, allFonts[id].Width)) {
#else
        asprintf(&cachename, "%s_%d_%d_%s", allFonts[id].Name, allFonts[id].Size, allFonts[id].Width, Setup.OSDLanguage);
        if (FontCache.Load(string(allFonts[id].Name), cachename, allFonts[id].Size, allFonts[id].Width)) {
#endif
          res = FontCache.GetFont(cachename);
          }
        else {
          esyslog("music: ERROR: Couldn't load font %s:%d", allFonts[id].Name, allFonts[id].Size);
        }
        free(cachename);
#else
        esyslog("music: ERROR: Font engine not enabled at compile time!");
#endif
      }


    } else if (allFonts[id].VdrId > FONT_TRUETYPE) {
        res = cFont::GetFont((eDvbFont)(allFonts[id].VdrId - 1));
    } else {
        res = cFont::GetFont((eDvbFont)allFonts[id].VdrId);
    }
  }

    if(res == NULL)
      res = cFont::GetFont((eDvbFont)allFonts[id].Default);

    if (res)
      return res;
    else
      return cFont::GetFont(fontOsd);
}

void cMusicConfig::SetFont(int id, const char *font)
{
  if (id >= 0 && id < FONT_NUMFONTS && font) {
    char *tmp = strrchr(font, ':');
    if (tmp) {
      strncpy(allFonts[id].Name, font, std::min((int)sizeof(allFonts[id].Name),(int) (tmp - font)));
      allFonts[id].Size = atoi(tmp + 1);
      tmp = strchr(tmp + 1, ',');
      if (tmp) {
        allFonts[id].Width = atoi(tmp + 1);
      }
    } else {
      strncpy(allFonts[id].Name, font, sizeof(allFonts[id].Name));
    }
  }
}

void cMusicConfig::SetFont(int id, int vdrId)
{
  if (id >= 0 && id < FONT_NUMFONTS && vdrId >= 0) {
    allFonts[id].VdrId = vdrId;
  }
}
