{*
 *******************************************************************************
 *
 *  Copyright 2025 RIEGL Laser Measurement Systems
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  SPDX-License-Identifier: Apache-2.0
 *
 *******************************************************************************
 *}
{*!
 *******************************************************************************
 *
 * \file    riegl.rdb.pointcloud.openSettings.pas
 * \author  RIEGL LMS GmbH, Austria
 * \brief   Database open settings (Pascal wrapper code)
 * \version 2015-10-14/AW: Initial version
 * \version 2016-09-22/AW: Parameter 'cacheSize' changed from 32 to 64 bit type
 * \version 2016-12-20/AW: New functions to load/save settings from/to JSON
 * \version 2017-03-28/AW: Documentation of JSON load/save functions updated
 * \version 2019-02-15/AW: Fix Pascal API wrapper of OpenSettings class
 *
 *******************************************************************************
 *}

unit riegl.rdb.pointcloud.openSettings;

{******************************************************************************}
{***} INTERFACE {**************************************************************}
{******************************************************************************}

//---< INCLUDES >---------------------------------------------------------------

uses
  riegl.rdb,
  riegl.rdb.context;

//---< RDB LIBRARY IMPORTS >----------------------------------------------------

//______________________________________________________________________________
{*!
 * \brief Default constructor
 *
 * All values are set to default values.
 *}
function rdb_pointcloud_open_settings_new(
  Context      : TRDBContextHandle;               //!< [in] library context
  var Settings : TRDBPointcloudOpenSettingsHandle //!< [out] handle of created object
) : TRDBResult; cdecl; external riegl.rdb.RDB_LIBRARY_FILENAME;

//______________________________________________________________________________
{*!
 * \brief Destroy settings object
 *}
function rdb_pointcloud_open_settings_delete(
  Context      : TRDBContextHandle;               //!< [in] library context
  var Settings : TRDBPointcloudOpenSettingsHandle //!< [in] handle of object to delete
) : TRDBResult; cdecl; external riegl.rdb.RDB_LIBRARY_FILENAME;

//______________________________________________________________________________
(*!
 * \brief Load settings from JSON string
 *
 * This function parses the given JSON string and applies all available
 * properties - missing properties are silently ignored (i.e. the value
 * remains unchanged). When parsing the JSON string fails, an exception
 * is thrown.
 *
 * Example JSON string:
 *
 *     {
 *         "cache_size": 524288000
 *     }
 *)
function rdb_pointcloud_open_settings_json_load(
  Context  : TRDBContextHandle;                //!< [in] library context
  Settings : TRDBPointcloudOpenSettingsHandle; //!< [in] attribute handle
  JSON     : TRDBString                        //!< [in] JSON string
) : TRDBResult; cdecl; external riegl.rdb.RDB_LIBRARY_FILENAME;

//______________________________________________________________________________
{*!
 * \brief Save settings to JSON string
 * \see rdb_pointcloud_open_settings_json_load()
 *}
function rdb_pointcloud_open_settings_json_save(
  Context  : TRDBContextHandle;                //!< [in] library context
  Settings : TRDBPointcloudOpenSettingsHandle; //!< [in] attribute handle
  var JSON : TRDBString                        //!< [out] JSON string
) : TRDBResult; cdecl; external riegl.rdb.RDB_LIBRARY_FILENAME;

//______________________________________________________________________________
{*!
 * \brief Get point cache size
 *
 * The database engine may buffer read and write operations in an
 * internal cache. This value defines the cache size in bytes (octets).
 *
 * Default: 500 MB
 *}
function rdb_pointcloud_open_settings_get_cache_size(
  Context   : TRDBContextHandle;                //!< [in] library context
  Settings  : TRDBPointcloudOpenSettingsHandle; //!< [in] handle of object
  var Value : TRDBUInt32                        //!< [out] current value
) : TRDBResult; cdecl; external riegl.rdb.RDB_LIBRARY_FILENAME;
//
function rdb_pointcloud_open_settings_get_cache_size_64(
  Context   : TRDBContextHandle;                //!< [in] library context
  Settings  : TRDBPointcloudOpenSettingsHandle; //!< [in] handle of object
  var Value : TRDBUInt64                        //!< [out] current value
) : TRDBResult; cdecl; external riegl.rdb.RDB_LIBRARY_FILENAME;

//______________________________________________________________________________
{*!
 * \brief Set point cache size
 * \see rdb_pointcloud_open_settings_get_cache_size()
 *}
function rdb_pointcloud_open_settings_set_cache_size(
  Context  : TRDBContextHandle;                //!< [in] library context
  Settings : TRDBPointcloudOpenSettingsHandle; //!< [in] handle of object
  Value    : TRDBUInt32                        //!< [in] new value
) : TRDBResult; cdecl; external riegl.rdb.RDB_LIBRARY_FILENAME;
//
function rdb_pointcloud_open_settings_set_cache_size_64(
  Context  : TRDBContextHandle;                //!< [in] library context
  Settings : TRDBPointcloudOpenSettingsHandle; //!< [in] handle of object
  Value    : TRDBUInt64                        //!< [in] new value
) : TRDBResult; cdecl; external riegl.rdb.RDB_LIBRARY_FILENAME;

//---< CLASS TRDBPointcloudOpenSettings >---------------------------------------
{*!
 * \brief Database open settings
 *
 * This class defines settings for opening a point cloud database.
 *}
type
  TRDBPointcloudOpenSettings = class(System.TObject)
  public
    {*!
     * \brief Point cache size
     *
     * The database engine may buffer read and write operations in an
     * internal cache. This value defines the cache size in bytes (octets).
     *
     * Default: 500 MB
     *}
    CacheSize : TRDBUInt64;

  public
    destructor Destroy(); override;

    {*!
     * \brief Default constructor
     *
     * All properties are set to default values.
     *}
    constructor Create(const Context : TRDBContext); reintroduce; overload;

    {*!
     * \brief Copy constructor
     *
     * All properties are copied from the given settings object.
     *}
    constructor Create(const Settings : TRDBPointcloudOpenSettings); overload;

    {*!
     * \brief Assignment operator
     *
     * All properties are copied from the given settings object.
     *}
    function Assign(const Settings : TRDBPointcloudOpenSettings) : TRDBPointcloudOpenSettings;

    (*!
     * \brief Load settings from JSON string
     *
     * This function parses the given JSON string and applies all available
     * properties - missing properties are silently ignored (i.e. the value
     * remains unchanged). When parsing the JSON string fails, an exception
     * is thrown.
     *
     * Example JSON string:
     *
     *     {
     *         "cache_size": 524288000
     *     }
     *)
    procedure Load(const JSON : String);

    {*!
     * \brief Save settings to JSON string
     * \see load()
     *}
    function Save() : String;

  private
    FContext : TRDBContext;
    FHandle  : TRDBPointcloudOpenSettingsHandle;

  public
    property Handle : TRDBPointcloudOpenSettingsHandle read FHandle;
  end;

//---< TOOLS >------------------------------------------------------------------

//______________________________________________________________________________
{*!
 * \brief Read settings from library
 * \note For wrapper internal use only.
 *}
procedure PointcloudOpenSettingsRead(const Target : TRDBPointcloudOpenSettings);

//______________________________________________________________________________
{*!
 * \brief Post settings to library
 * \note For wrapper internal use only.
 *}
procedure PointcloudOpenSettingsPost(const Source : TRDBPointcloudOpenSettings);

{******************************************************************************}
{***} IMPLEMENTATION {*********************************************************}
{******************************************************************************}

//---< TRDBPointcloudOpenSettings::PUBLIC >-------------------------------------

destructor TRDBPointcloudOpenSettings.Destroy();
begin
  if (FContext <> nil) and (FHandle <> nil) then
  begin
    rdb_pointcloud_open_settings_delete(FContext.Handle, FHandle);
  end;
  inherited;
end;

constructor TRDBPointcloudOpenSettings.Create(const Context : TRDBContext);
begin
  inherited Create;
  FContext := Context; FHandle := nil;
  FContext.Check(rdb_pointcloud_open_settings_new(FContext.Handle, FHandle));
  PointcloudOpenSettingsRead(Self);
end;

constructor TRDBPointcloudOpenSettings.Create(const Settings : TRDBPointcloudOpenSettings);
begin
  Create(Settings.FContext);
  Self.Assign(Settings);
end;

function TRDBPointcloudOpenSettings.Assign(const Settings : TRDBPointcloudOpenSettings) : TRDBPointcloudOpenSettings;
begin
  Self.Load(Settings.Save());
  Result := Self;
end;

procedure TRDBPointcloudOpenSettings.Load(const JSON : String);
begin
  FContext.Check(rdb_pointcloud_open_settings_json_load(
    FContext.Handle, FHandle, TRDBString(AnsiToUtf8(JSON))
  ));
  PointcloudOpenSettingsRead(Self);
end;

function TRDBPointcloudOpenSettings.Save() : String;
var
  JSON : TRDBString;
begin
  PointcloudOpenSettingsPost(Self);
  FContext.Check(rdb_pointcloud_open_settings_json_save(
    FContext.Handle, FHandle, JSON
  ));
  Result := AsSTDString(JSON);
end;

//---< TOOLS >------------------------------------------------------------------

procedure PointcloudOpenSettingsRead(const Target : TRDBPointcloudOpenSettings);
begin
  Target.FContext.Check(rdb_pointcloud_open_settings_get_cache_size_64(
    Target.FContext.Handle, Target.FHandle, Target.CacheSize
  ));
end;

procedure PointcloudOpenSettingsPost(const Source : TRDBPointcloudOpenSettings);
begin
  Source.FContext.Check(rdb_pointcloud_open_settings_set_cache_size_64(
    Source.FContext.Handle, Source.FHandle, Source.CacheSize
  ));
end;

end.
