/////////////////////////////////////////////////////////////////////////////////////////
//
// Please refer to "COPYRIGHT.md" for the relevant copyright statement of this software.
//
/////////////////////////////////////////////////////////////////////////////////////////
//
#pragma once
#ifndef _Gc_UniqueString_h_
#  define _Gc_UniqueString_h_

#  include <cstddef>
#  include <cstdint>

class GcUniqueString
{
public:
  typedef uint64_t value;

  static constexpr value Intern(const wchar_t* pws)
  {
    return (value)computeHash(pws);
  }

  static constexpr const value drawing2D()
  {
    return Intern(L"2D Drawing");
  }
  static constexpr const value drawing3D()
  {
    return Intern(L"3D Drawing");
  }
  static constexpr const value drawing3D2()
  {
    return Intern(L"3D Drawing2");
  }
  static constexpr const value selection3D()
  {
    return Intern(L"3D Selection");
  }
  static constexpr const value rapidRTRendering3D()
  {
    return Intern(L"RapidRT Rendering");
  }

private:
  static constexpr uint64_t computeHash(const wchar_t* pws)
  {
    uint64_t hash = 14695981039346656037ULL;
    if (pws && *pws)
    {
      for (; *pws; pws++)
      {
        wchar_t ch = *pws;
        if ((ch >= 'A') && (ch <= 'Z'))
          ch += 'a' - 'A';
        hash = fnv1a64char((uint8_t)(ch & 0xff), hash);
        hash = fnv1a64char((uint8_t)((ch >> 8) & 0xff), hash);
      }
    }
    return hash;
  }

  static constexpr uint64_t fnv1a64char(uint8_t ch, uint64_t hash)
  {
    return (hash ^ ch) * 1099511628211ULL;
  }
};

#endif
