//Pascal &or the FreePascal use of nintendo 2ds, 3ds regime
//
// Copyright (c) 2013, 2015, 2017 Kenneth Dwayne Lee Bsc.
// all rights reserved.
//

  {*
   * @file nim.h
   * @brief NIM (network installation management) service.
   *
   * This service is used to download and install titles from Nintendo's CDN.
   *
   * We differentiate between two different kinds of downloads:
   *
   * - "active" downloads, which are downloads started with @ref NIMS_StartDownload or @ref NIMS_StartDownloadSimple. The process must keep polling the current status using @ref NIMS_GetProgress.
   * - "tasks", which are downloads started with @ref NIMS_RegisterTask. These are only processed in sleep mode.
    }
    
  type
     NIM_InstallationMode = (IM_DEFAULT := 0,IM_UNKNOWN1,IM_UNKNOWN2,IM_REINSTALL);
     
  {/ Current state of a NIM download/installation. }
  {/< Download not yet initialized }
  {/< Download initialized }
  {/< Downloading and installing TMD }
  {/< Initializing save data }
  {/< Downloading and installing contents }
  {/< Waiting before calling AM_CommitImportTitles }
  {/< Running AM_CommitImportTitles }
  {/< Title installation finished }
  {/< (unknown error regarding title version) }
  {/< Creating the .ctx file? }
  {/< Irrecoverable error encountered (e.g. out of space) }
  {/< Invalid state }

     NIM_DownloadState = (DS_NOT_INITIALIZED := 0,DS_INITIALIZED,
       DS_DOWNLOAD_TMD,DS_PREPARE_SAVE_DATA,
       DS_DOWNLOAD_CONTENTS,DS_WAIT_COMMIT,
       DS_COMMITTING,DS_FINISHED,DS_VERSION_ERROR,
       DS_CREATE_CONTEXT,DS_CANNOT_RECOVER,
       DS_INVALID);
  {/ Input configuration for NIM download/installation tasks. }
  {/< Title ID }
  {/< Title version }
  {/< Always 0 }
  {/< Age for the HOME Menu parental controls }
  {/< Media type, see @ref FS_MediaType enum }
  {/< Padding }
  {/< Unknown input, seems to be always 0 }

     NIM_TitleConfig = record
          titleId : u64;
          version : u32;
          unknown_0 : u32;
          ratingAge : u8;
          mediaType : u8;
          padding : array[0..1] of u8;
          unknown_1 : u32;
       end;
   PNIM_TitleConfig  = ^NIM_TitleConfig;

  {/ Output struct for NIM downloads/installations in progress. }
  {/< State, see NIM_DownloadState enum }
  {/< Last result code in NIM }
  {/< Amount of bytes that have been downloaded }
  {/< Amount of bytes that need to be downloaded in total }

     NIM_TitleProgress = record
          state : u32;
          lastResult : s32;
          downloadedSize : u64;
          totalSize : u64;
       end;
  PNIM_TitleProgress  = ^NIM_TitleProgress;
  
  {*
   * @brief Initializes nim:s. This uses networking and is blocking.
   * @param buffer A buffer for internal use. It must be at least 0x20000 bytes long.
   * @param buffer_len Length of the passed buffer.
    }

  function nimsInit(buffer:pointer; buffer_len:u32):s32;cdecl;external;

  {*
   * @brief Initializes nim:s with the given TIN. This uses networking and is blocking.
   * @param buffer A buffer for internal use. It must be at least 0x20000 bytes long.
   * @param buffer_len Length of the passed buffer.
   * @param TIN The TIN to initialize nim:s with. If you do not know what a TIN is or why you would want to change it, use @ref nimsInit instead.
    }
(* Const before type ignored *)
  function nimsInitWithTIN(buffer:pointer; buffer_len:u32; TIN:pcchar):s32;cdecl;external;

  {/ Exits nim:s. }
  procedure nimsExit;cdecl;external;

  {/ Gets the current nim:s session handle. }
  function nimsGetSessionHandle:pHandle;cdecl;external;

  {*
   * @brief Sets an attribute.
   * @param attr Name of the attribute.
   * @param val Value of the attribute.
    }
  function NIMS_SetAttribute(attr:pchar; val:pchar):s32;cdecl;external;

  {*
   * @brief Checks if nim wants a system update.
   * @param want_update Set to true if a system update is required. Can be NULL.
    }
  function NIMS_WantUpdate(want_update:boolean):s32;cdecl;external;

  {*
   * @brief Makes a TitleConfig struct for use with @ref NIMS_RegisterTask, @ref NIMS_StartDownload or @ref NIMS_StartDownloadSimple.
   * @param cfg Struct to initialize.
   * @param titleId Title ID to download and install.
   * @param version Version of the title to download and install.
   * @param ratingAge Age for which the title is aged; used by parental controls in HOME Menu.
   * @param mediaType Media type of the title to download and install.
    }
  procedure NIMS_MakeTitleConfig(cfg:PNIM_TitleConfig; titleId:u64; version:u32; ratingAge:u8; mediaType:FS_MediaType);cdecl;external;

  {*
   * @brief Registers a background download task with NIM. These are processed in sleep mode only.
   * @param cfg Title config to use. See @ref NIMS_MakeTitleConfig.
   * @param name Name of the title in UTF-8. Will be displayed on the HOME Menu. Maximum 73 characters.
   * @param maker Name of the maker/publisher in UTF-8. Will be displayed on the HOME Menu. Maximum 37 characters.
    }
  function NIMS_RegisterTask(cfg:PNIM_TitleConfig; name:pchar; maker:pchar):s32;cdecl;external;

  {*
   * @brief Checks whether a background download task for the given title is registered with NIM.
   * @param titleId Title ID to check for.
   * @param registered Whether there is a background download task registered.
    }
  function NIMS_IsTaskRegistered(titleId:u64; registered:boolean):s32;cdecl;external;

  {*
   * @brief Unregisters a background download task.
   * @param titleId Title ID whose background download task to cancel.
    }
  function NIMS_UnregisterTask(titleId:u64):s32;cdecl;external;

  {*
   * @brief Starts an active download with NIM. Progress can be checked with @ref NIMS_GetProcess. Do not exit the process while a download is in progress without calling @ref NIMS_CancelDownload.
   * @param cfg Title config to use. See @ref NIMS_MakeTitleConfig.
   * @param mode The installation mode to use. See @ref NIM_InstallationMode.
    }
  function NIMS_StartDownload(cfg:PNIM_TitleConfig; mode:NIM_InstallationMode):s32;cdecl;external;

  {*
   * @brief Starts an active download with NIM with default installation mode; cannot reinstall titles. Progress can be checked with @ref NIMS_GetProcess. Do not exit the process while a download is in progress without calling @ref NIMS_CancelDownload.
   * @param cfg Title config to use. See @ref NIMS_MakeTitleConfig.
    }
  function NIMS_StartDownloadSimple(cfg:PNIM_TitleConfig):s32;cdecl;external;

  {*
   * @brief Checks the status of the current active download.
   * @param tp Title progress struct to write to. See @ref NIM_TitleProgress.
    }
  function NIMS_GetProgress(tp:PNIM_TitleProgress):s32;cdecl;external;

  {*
   * @brief Cancels the current active download with NIM.
    }
  function NIMS_CancelDownload:s32;cdecl;external;