// Copyright (c) 2020 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=ba0a12367019906d32dae965d7d1b5245d02b442$
//

#include "libcef_dll/cpptoc/resource_bundle_cpptoc.h"

// GLOBAL FUNCTIONS - Body may be edited by hand.

CEF_EXPORT cef_resource_bundle_t* cef_resource_bundle_get_global() {
  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  // Execute
  CefRefPtr<CefResourceBundle> _retval = CefResourceBundle::GetGlobal();

  // Return type: refptr_same
  return CefResourceBundleCppToC::Wrap(_retval);
}

namespace {

// MEMBER FUNCTIONS - Body may be edited by hand.

cef_string_userfree_t CEF_CALLBACK
resource_bundle_get_localized_string(struct _cef_resource_bundle_t* self,
                                     int string_id) {
  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  DCHECK(self);
  if (!self)
    return NULL;

  // Execute
  CefString _retval =
      CefResourceBundleCppToC::Get(self)->GetLocalizedString(string_id);

  // Return type: string
  return _retval.DetachToUserFree();
}

int CEF_CALLBACK
resource_bundle_get_data_resource(struct _cef_resource_bundle_t* self,
                                  int resource_id,
                                  void** data,
                                  size_t* data_size) {
  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  DCHECK(self);
  if (!self)
    return 0;
  // Verify param: data; type: simple_byref
  DCHECK(data);
  if (!data)
    return 0;
  // Verify param: data_size; type: simple_byref
  DCHECK(data_size);
  if (!data_size)
    return 0;

  // Translate param: data; type: simple_byref
  void* dataVal = data ? *data : NULL;
  // Translate param: data_size; type: simple_byref
  size_t data_sizeVal = data_size ? *data_size : 0;

  // Execute
  bool _retval = CefResourceBundleCppToC::Get(self)->GetDataResource(
      resource_id, dataVal, data_sizeVal);

  // Restore param: data; type: simple_byref
  if (data)
    *data = dataVal;
  // Restore param: data_size; type: simple_byref
  if (data_size)
    *data_size = data_sizeVal;

  // Return type: bool
  return _retval;
}

int CEF_CALLBACK
resource_bundle_get_data_resource_for_scale(struct _cef_resource_bundle_t* self,
                                            int resource_id,
                                            cef_scale_factor_t scale_factor,
                                            void** data,
                                            size_t* data_size) {
  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

  DCHECK(self);
  if (!self)
    return 0;
  // Verify param: data; type: simple_byref
  DCHECK(data);
  if (!data)
    return 0;
  // Verify param: data_size; type: simple_byref
  DCHECK(data_size);
  if (!data_size)
    return 0;

  // Translate param: data; type: simple_byref
  void* dataVal = data ? *data : NULL;
  // Translate param: data_size; type: simple_byref
  size_t data_sizeVal = data_size ? *data_size : 0;

  // Execute
  bool _retval = CefResourceBundleCppToC::Get(self)->GetDataResourceForScale(
      resource_id, scale_factor, dataVal, data_sizeVal);

  // Restore param: data; type: simple_byref
  if (data)
    *data = dataVal;
  // Restore param: data_size; type: simple_byref
  if (data_size)
    *data_size = data_sizeVal;

  // Return type: bool
  return _retval;
}

}  // namespace

// CONSTRUCTOR - Do not edit by hand.

CefResourceBundleCppToC::CefResourceBundleCppToC() {
  GetStruct()->get_localized_string = resource_bundle_get_localized_string;
  GetStruct()->get_data_resource = resource_bundle_get_data_resource;
  GetStruct()->get_data_resource_for_scale =
      resource_bundle_get_data_resource_for_scale;
}

// DESTRUCTOR - Do not edit by hand.

CefResourceBundleCppToC::~CefResourceBundleCppToC() {}

template <>
CefRefPtr<CefResourceBundle> CefCppToCRefCounted<
    CefResourceBundleCppToC,
    CefResourceBundle,
    cef_resource_bundle_t>::UnwrapDerived(CefWrapperType type,
                                          cef_resource_bundle_t* s) {
  NOTREACHED() << "Unexpected class type: " << type;
  return nullptr;
}

template <>
CefWrapperType CefCppToCRefCounted<CefResourceBundleCppToC,
                                   CefResourceBundle,
                                   cef_resource_bundle_t>::kWrapperType =
    WT_RESOURCE_BUNDLE;
