// 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=cdcd1b3b9458442c480e69c5f7cee2ed48587e8b$
//

#include "libcef_dll/cpptoc/navigation_entry_cpptoc.h"
#include "libcef_dll/cpptoc/sslstatus_cpptoc.h"
#include "libcef_dll/shutdown_checker.h"

namespace {

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

int CEF_CALLBACK
navigation_entry_is_valid(struct _cef_navigation_entry_t* self) {
  shutdown_checker::AssertNotShutdown();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

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

  // Execute
  bool _retval = CefNavigationEntryCppToC::Get(self)->IsValid();

  // Return type: bool
  return _retval;
}

cef_string_userfree_t CEF_CALLBACK
navigation_entry_get_url(struct _cef_navigation_entry_t* self) {
  shutdown_checker::AssertNotShutdown();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

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

  // Execute
  CefString _retval = CefNavigationEntryCppToC::Get(self)->GetURL();

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

cef_string_userfree_t CEF_CALLBACK
navigation_entry_get_display_url(struct _cef_navigation_entry_t* self) {
  shutdown_checker::AssertNotShutdown();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

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

  // Execute
  CefString _retval = CefNavigationEntryCppToC::Get(self)->GetDisplayURL();

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

cef_string_userfree_t CEF_CALLBACK
navigation_entry_get_original_url(struct _cef_navigation_entry_t* self) {
  shutdown_checker::AssertNotShutdown();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

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

  // Execute
  CefString _retval = CefNavigationEntryCppToC::Get(self)->GetOriginalURL();

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

cef_string_userfree_t CEF_CALLBACK
navigation_entry_get_title(struct _cef_navigation_entry_t* self) {
  shutdown_checker::AssertNotShutdown();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

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

  // Execute
  CefString _retval = CefNavigationEntryCppToC::Get(self)->GetTitle();

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

cef_transition_type_t CEF_CALLBACK
navigation_entry_get_transition_type(struct _cef_navigation_entry_t* self) {
  shutdown_checker::AssertNotShutdown();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

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

  // Execute
  cef_transition_type_t _retval =
      CefNavigationEntryCppToC::Get(self)->GetTransitionType();

  // Return type: simple
  return _retval;
}

int CEF_CALLBACK
navigation_entry_has_post_data(struct _cef_navigation_entry_t* self) {
  shutdown_checker::AssertNotShutdown();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

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

  // Execute
  bool _retval = CefNavigationEntryCppToC::Get(self)->HasPostData();

  // Return type: bool
  return _retval;
}

cef_time_t CEF_CALLBACK
navigation_entry_get_completion_time(struct _cef_navigation_entry_t* self) {
  shutdown_checker::AssertNotShutdown();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

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

  // Execute
  cef_time_t _retval = CefNavigationEntryCppToC::Get(self)->GetCompletionTime();

  // Return type: simple
  return _retval;
}

int CEF_CALLBACK
navigation_entry_get_http_status_code(struct _cef_navigation_entry_t* self) {
  shutdown_checker::AssertNotShutdown();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

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

  // Execute
  int _retval = CefNavigationEntryCppToC::Get(self)->GetHttpStatusCode();

  // Return type: simple
  return _retval;
}

struct _cef_sslstatus_t* CEF_CALLBACK
navigation_entry_get_sslstatus(struct _cef_navigation_entry_t* self) {
  shutdown_checker::AssertNotShutdown();

  // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

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

  // Execute
  CefRefPtr<CefSSLStatus> _retval =
      CefNavigationEntryCppToC::Get(self)->GetSSLStatus();

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

}  // namespace

// CONSTRUCTOR - Do not edit by hand.

CefNavigationEntryCppToC::CefNavigationEntryCppToC() {
  GetStruct()->is_valid = navigation_entry_is_valid;
  GetStruct()->get_url = navigation_entry_get_url;
  GetStruct()->get_display_url = navigation_entry_get_display_url;
  GetStruct()->get_original_url = navigation_entry_get_original_url;
  GetStruct()->get_title = navigation_entry_get_title;
  GetStruct()->get_transition_type = navigation_entry_get_transition_type;
  GetStruct()->has_post_data = navigation_entry_has_post_data;
  GetStruct()->get_completion_time = navigation_entry_get_completion_time;
  GetStruct()->get_http_status_code = navigation_entry_get_http_status_code;
  GetStruct()->get_sslstatus = navigation_entry_get_sslstatus;
}

// DESTRUCTOR - Do not edit by hand.

CefNavigationEntryCppToC::~CefNavigationEntryCppToC() {
  shutdown_checker::AssertNotShutdown();
}

template <>
CefRefPtr<CefNavigationEntry> CefCppToCRefCounted<
    CefNavigationEntryCppToC,
    CefNavigationEntry,
    cef_navigation_entry_t>::UnwrapDerived(CefWrapperType type,
                                           cef_navigation_entry_t* s) {
  NOTREACHED() << "Unexpected class type: " << type;
  return nullptr;
}

template <>
CefWrapperType CefCppToCRefCounted<CefNavigationEntryCppToC,
                                   CefNavigationEntry,
                                   cef_navigation_entry_t>::kWrapperType =
    WT_NAVIGATION_ENTRY;
