// Copyright (c) 2019 Giorgos Vougioukas
//
// The license can be found in the LICENSE file.

#include "euterpe/theme.h"
#include "euterpe/definitions.h"

static void del_raw_data(WDL_HeapBuf *p) { delete p; }

RSE_ITheme::RSE_ITheme()
  : data(true, del_raw_data)
{}

RSE_ITheme::~RSE_ITheme()
{
  data.DeleteAll();
}

RSE_PackedTheme::RSE_PackedTheme()
  : m_theme_res("")
  , m_zipfile(NULL)
{}

RSE_PackedTheme::~RSE_PackedTheme()
{}

bool RSE_PackedTheme::LoadResource(const char *resource)
{
  int res = UNZ_OK;
  char fn[2048];
  WDL_HeapBuf *raw_data = NULL;

  WDL_ASSERT(data.GetSize() == 0);
  WDL_ASSERT(resource != NULL);

  m_theme_res.Set(resource);

  m_zipfile = unzOpen64(m_theme_res.Get());
  if (!m_zipfile)
  {
    return false;
  }

  res = unzGetGlobalInfo64(m_zipfile, &m_global_info);
  if (res != UNZ_OK)
  {
    unzClose(m_zipfile);
    return false;
  }

  for (int i = 0; i < m_global_info.number_entry; i++)
  {
    res = unzGetCurrentFileInfo64(m_zipfile, &m_file_info,
      fn, sizeof(fn), NULL, 0, NULL, 0);
    if (res != UNZ_OK)
    {
      unzClose(m_zipfile);
      return false;
    }

    if (fn[(int)strlen(fn) - 1] == WDL_DIRCHAR) // check for dir_delimiter
    {
      // Entry is a directory
    }
    else
    {
      res = unzOpenCurrentFile(m_zipfile);
      if (res != UNZ_OK)
      {
        unzCloseCurrentFile(m_zipfile);
        unzClose(m_zipfile);
        return false;
      }

      raw_data = new WDL_HeapBuf;
      if (!raw_data)
      {
        delete raw_data;
        unzCloseCurrentFile(m_zipfile);
        unzClose(m_zipfile);
        return false;
      }
      raw_data->Resize((int)m_file_info.uncompressed_size);

      WDL_ASSERT(raw_data->GetSize() == (int)m_file_info.uncompressed_size);

      res = unzReadCurrentFile(m_zipfile, raw_data->Get(), raw_data->GetSize());
      if (res < 0)
      {
        unzCloseCurrentFile(m_zipfile);
        unzClose(m_zipfile);
        return false;
      }

      data.Insert(fn, raw_data);
      unzCloseCurrentFile(m_zipfile);
    }

    if ((i + 1) < m_global_info.number_entry)
    {
      res = unzGoToNextFile(m_zipfile);
      if (res != UNZ_OK)
      {
        unzClose(m_zipfile);
        return false;
      }
    }
  }

  unzClose(m_zipfile);
  return true;
}

void RSE_PackedTheme::UnloadResource()
{
  data.DeleteAll();
  m_theme_res.Set("");
}

const char *RSE_PackedTheme::GetThemeResource() const
{
  return m_theme_res.Get();
}

bool RSE_PackedTheme::IsThemeLoaded() const
{
  return m_theme_res.GetLength() &&
    data.GetSize();
}
