#ifndef F3DCLIOptions_h
#define F3DCLIOptions_h

#include <string_view>
#include <vector>

namespace F3D
{
/**
 * A struct to configure a complete cxxopts CLI options
 * F3D uses exclusively string options except for a few true boolean option (eg: `--version`)
 * LongName: The long name, eg: `axis`
 * ShortName: The short name, eg: `x`
 * HelpText: The help text, for display only when using `--help`
 * ValueHelper: Used in help but also to discrimate between boolean option or not
 * ImplicitValue: The implicit value when option is provided without a value
 */
struct CLIOption
{
  std::string_view LongName;
  std::string_view ShortName;
  std::string_view HelpText;
  std::string_view ValueHelper;
  std::string_view ImplicitValue;
};

/**
 * A struct to group option into categories
 */
struct CLIGroup
{
  std::string_view GroupName;
  std::vector<CLIOption> Options;
};

/**
 * The CLIOptions array will be generated by CMake from
 * resources/cli-options.json. To add or update CLI options please update the
 * JSON file.
 */
// clang-format off
static inline const std::array<CLIGroup, 9> CLIOptions = {{
  { "Applicative",
    {
      { "output", "", "Render to file", "<png file>", "" },
      { "no-background", "", "No background when render to file", "<bool>", "1" },
      { "help", "h", "Print help", "", "" },
      { "version", "", "Print version details", "", "" },
      { "list-readers", "", "Print the list of readers", "", "" },
      { "force-reader", "", "Force a specific reader to be used, disregarding the file extension", "<reader>", "" },
      { "list-bindings", "", "Print the list of interaction bindings and exits, ignored with `--no-render`, only considers the first file group.", "<bool>", "1" },
      { "config", "", "Specify the configuration file to use. absolute/relative path or filename/filestem to search in configuration file locations", "<filePath/filename/fileStem>", "" },
      { "no-config", "", "Do not read the configuration file", "<bool>", "1" },
      { "no-render", "", "Do not render anything and quit right after loading the first file, use with --verbose to recover information about a file.", "<bool>", "1" },
      { "rendering-backend", "", "Backend to use when rendering (auto|glx|wgl|egl|osmesa)", "<string>", "" },
      { "list-rendering-backends", "", "Print the list of rendering backends available on this system", "", "" },
      { "max-size", "", "Maximum size in Mib of a file to load, leave empty for unlimited", "<size in Mib>", "" },
      { "dpi-aware", "", "Scale font and window resolution according to system scale", "<bool>", "1" },
      { "watch", "", "Watch current file and automatically reload it whenever it is modified on disk", "<bool>", "1" },
      { "frame-rate", "", "Frame rate used to refresh animation and other repeated tasks (watch, UI). Does not impact rendering frame rate.", "<fps>", "" },
      { "load-plugins", "", "List of plugins to load separated with a comma", "<paths or names>", "" },
      { "scan-plugins", "", "Scan standard directories for plugins and display available plugins (result can be incomplete)", "", "" },
      { "screenshot-filename", "", "Screenshot filename", "<filename>", "" },
    }
  },
  { "General",
    {
      { "verbose", "", "Set verbose level, providing more information about the loaded data in the console output", "{debug, info, warning, error, quiet}", "debug" },
      { "loading-progress", "", "Show loading progress bar", "<bool>", "1" },
      { "animation-progress", "", "Show animation progress bar", "<bool>", "1" },
      { "multi-file-mode", "", "Choose the behavior when opening multiple files. \"single\" will show one file at a time, \"all\" will show all files in a single scene, \"dir\" will show files from the same directory in the same scene.", "<single|all|dir>", "" },
      { "multi-file-regex", "", "Regular expression pattern to group files. Captured groups are replaced with \"*\" so that, for example, the pattern \"part(\\d+)\" would group files \"foo-part1.xyz\" and \"foo-part2.xyz\" together as \"foo-part*.xyz\"", "<regex>", "" },
      { "recursive-dir-add", "", "Add directories recursively", "<bool>", "1" },
      { "remove-empty-file-groups", "", "Remove file groups that results into an empty scene", "<bool>", "1" },
      { "up", "", "Up direction", "<direction>", "" },
      { "axis", "x", "Show axes", "<bool>", "1" },
      { "grid", "g", "Show grid", "<bool>", "1" },
      { "x-color", "", "Color of the X axis", "<color>", "" },
      { "y-color", "", "Color of the Y axis", "<color>", "" },
      { "z-color", "", "Color of the Z axis", "<color>", "" },
      { "grid-absolute", "", "Position grid at the absolute origin instead of below the model", "<bool>", "1" },
      { "grid-unit", "", "Size of grid unit square, automatically computed by default", "<value>", "" },
      { "grid-subdivisions", "", "Number of grid subdivisions", "<value>", "" },
      { "grid-color", "", "Color of main grid lines", "<color>", "" },
      { "axes-grid", "", "Enable grid axis", "<bool>", "1" },
      { "edges", "e", "Show cell edges", "<bool>", "1" },
      { "armature", "", "Enable armature visualization", "<bool>", "1" },
      { "camera-index", "", "Select the camera to use", "<index>", "" },
      { "interaction-style", "k", "Interaction style", "<style>", "2d" },
      { "interaction-trackball", "", "Enable trackball interaction (deprecated, use --interaction-style=trackball)", "<bool>", "1" },
      { "invert-zoom", "", "Invert zoom direction with right mouse click", "<bool>", "1" },
      { "animation-autoplay", "", "Automatically start animation", "<bool>", "1" },
      { "animation-index", "", "Select animation to show (deprecated)", "<index>", "" },
      { "animation-indices", "", "Select animations to show", "<index,index,index>", "" },
      { "animation-speed-factor", "", "Set animation speed factor", "<ratio>", "" },
      { "animation-time", "", "Set animation time to load", "<time>", "" },
      { "font-file", "", "Path to a FreeType compatible font file", "<file_path>", "" },
      { "font-scale", "", "Scale fonts", "<ratio>", "" },
      { "font-color", "", "Set font color", "<color>", "" },
      { "backdrop-opacity", "", "UI backdrop opacity", "<value>", "" },
      { "command-script", "", "Path to a script file containing commands to execute", "<file_path>", "" },
      { "normal-glyphs", "", "Enable normal glyphs", "<bool>", "1" },
    }
  },
  { "Material",
    {
      { "point-sprites", "o", "Select point sprites type (\"none\", \"sphere\", \"gaussian\", \"circle\", \"stddev\", \"bound\")", "<string>", "sphere" },
      { "point-sprites-type", "", "Point sprites type (deprecated)", "<sphere|gaussian>", "" },
      { "point-sprites-size", "", "Point sprites sphere size", "<size>", "" },
      { "point-sprites-absolute-size", "", "Do not scale point sprites size by scene size", "<bool>", "1" },
      { "point-size", "", "Point size when showing vertices, model specified by default", "<size>", "" },
      { "line-width", "", "Line width when showing edges, model specified by default", "<width>", "" },
      { "backface-type", "", "Backface type, can be visible or hidden, model specified by default", "<visible|hidden>", "" },
      { "color", "", "Solid color", "<color>", "" },
      { "opacity", "", "Opacity", "<opacity>", "" },
      { "roughness", "", "Roughness coefficient (0.0-1.0)", "<roughness>", "" },
      { "metallic", "", "Metallic coefficient (0.0-1.0)", "<metallic>", "" },
      { "base-ior", "", "Index Of Refraction of the base layer (1.0-2.5)", "<base-ior>", "" },
      { "hdri-file", "", "Path to an image file that can be used as a light source and skybox", "<file path>", "" },
      { "hdri-ambient", "f", "Enable HDRI ambient lighting", "<bool>", "1" },
      { "hdri-skybox", "j", "Enable HDRI skybox background", "<bool>", "1" },
      { "texture-matcap", "", "Path to a texture file containing a material capture", "<file path>", "" },
      { "texture-base-color", "", "Path to a texture file that sets the color of the object", "<file path>", "" },
      { "texture-material", "", "Path to a texture file that sets the Occlusion, Roughness and Metallic values of the object", "<file path>", "" },
      { "texture-emissive", "", "Path to a texture file that sets the emitted light of the object", "<file path>", "" },
      { "textures-transform", "", "3x3 matrix to transform textures", "<transform2d>", "" },
      { "emissive-factor", "", "Emissive factor. This value is multiplied with the emissive color when an emissive texture is present", "<color>", "" },
      { "texture-normal", "", "Path to a texture file that sets the normal map of the object", "<file path>", "" },
      { "checkerboard", "", "Apply checkerboard texture to objects", "<bool>", "1" },
      { "normal-scale", "", "Normal scale affects the strength of the normal deviation from the normal texture", "<normalScale>", "" },
      { "unlit", "", "Ignore shading and make the material unlit", "<bool>", "1" },
    }
  },
  { "Window",
    {
      { "background-color", "", "Background color", "<color>", "" },
      { "resolution", "", "Window resolution", "<width,height>", "" },
      { "position", "", "Window position", "<x,y>", "" },
      { "fps", "z", "Display rendering frame per second", "<bool>", "1" },
      { "filename", "n", "Display filename", "<bool>", "1" },
      { "metadata", "m", "Display file metadata", "<bool>", "1" },
      { "scene-hierarchy", "", "Display the scene hierarchy widget", "<bool>", "1" },
      { "notifications", "", "Display notifications", "<bool>", "1" },
      { "hdri-filename", "", "Display hdri filename", "<bool>", "1" },
      { "blur-background", "u", "Blur background", "<bool>", "1" },
      { "blur-coc", "", "Blur circle of confusion radius", "<value>", "" },
      { "light-intensity", "", "Light intensity", "<value>", "" },
    }
  },
  { "Scientific visualization",
    {
      { "scalar-coloring", "s", "Color by a scalar array", "<bool>", "1" },
      { "coloring-array", "", "Name of the array to color with", "<array_name>", "" },
      { "coloring-component", "y", "Component from the array to color with. -1 means magnitude, -2 or the short option, -y, means direct scalars", "<comp_index>", "-2" },
      { "coloring-by-cells", "c", "Use an array from the cells", "<bool>", "1" },
      { "coloring-range", "", "Custom range for the coloring by array, automatically computed by default", "<min,max>", "" },
      { "coloring-scalar-bar", "b", "Show scalar bar", "<bool>", "1" },
      { "colormap-file", "", "Specify a colormap image", "<filePath/filename/fileStem>", "" },
      { "colormap-discretization", "", "Specify number of colors in colormap", "<int>", "" },
      { "colormap", "", "Specify a custom colormap (ignored if \"colormap-file\" is specified)", "<color_list>", "" },
      { "volume-opacity-map", "", "Specify a custom opacity map for volume rendering", "<opacity_list>", "" },
      { "volume-opacity-file", "", "Specify a custom opacity map image for volume rendering", "<filePath/filename/fileStem>", "" },
      { "volume", "v", "Show volume if the file is compatible", "<bool>", "1" },
      { "volume-inverse", "i", "Inverse opacity function for volume rendering", "<bool>", "1" },
    }
  },
  { "Camera",
    {
      { "camera-position", "", "Camera position (overrides camera direction and camera zoom factor if any)", "<X,Y,Z>", "" },
      { "camera-focal-point", "", "Camera focal point", "<X,Y,Z>", "" },
      { "camera-view-up", "", "Camera view up", "<direction>", "" },
      { "camera-view-angle", "", "Camera view angle (non-zero, in degrees)", "<angle>", "" },
      { "camera-direction", "", "Camera direction", "<direction>", "" },
      { "camera-zoom-factor", "", "Camera zoom factor (non-zero)", "<factor>", "" },
      { "camera-azimuth-angle", "", "Camera azimuth angle (in degrees), performed after other camera options", "<angle>", "" },
      { "camera-elevation-angle", "", "Camera elevation angle (in degrees), performed after other camera options", "<angle>", "" },
      { "camera-orthographic", "", "Use an orthographic camera", "<bool>", "1" },
    }
  },
  { "Raytracing",
    {
      { "raytracing", "r", "Enable raytracing", "<bool>", "1" },
      { "raytracing-samples", "", "Number of samples per pixel", "<samples>", "" },
      { "raytracing-denoise", "d", "Denoise the image", "<bool>", "1" },
    }
  },
  { "PostFX (OpenGL)",
    {
      { "blending", "p", "Select translucency blending mode (\"none\", \"ddp\", \"sort\", \"sort_cpu\" or \"stochastic\")", "<string>", "ddp" },
      { "translucency-support", "", "Enable translucency blending (deprecated)", "<bool>", "1" },
      { "ambient-occlusion", "q", "Enable ambient occlusion providing approximate shadows for better depth perception, implemented using SSAO", "<bool>", "1" },
      { "anti-aliasing", "a", "Select anti-aliasing method (\"none\", \"fxaa\", \"ssaa\" or \"taa\")", "<string>", "fxaa" },
      { "anti-aliasing-mode", "", "Select anti-aliasing method (\"fxaa\", \"ssaa\" or \"taa\") (deprecated)", "<string>", "fxaa" },
      { "tone-mapping", "t", "Enable Tone Mapping, providing balanced coloring", "<bool>", "1" },
      { "final-shader", "", "Execute the final shader at the end of the rendering pipeline", "<GLSL code>", "" },
      { "display-depth", "", "Display depth buffer as grayscale image or with a colormap if \"--scalar-coloring\" is specified", "<bool>", "1" },
    }
  },
  { "Testing",
    {
      { "reference", "", "Reference", "<png file>", "" },
      { "reference-threshold", "", "Testing threshold", "<threshold>", "" },
      { "interaction-test-record", "", "Path to an interaction log file to record interactions events to", "<file_path>", "" },
      { "interaction-test-play", "", "Path to an interaction log file to play interaction events from when loading a file", "<file_path>", "" },
    }
  },
}};
// clang-format on
}

#endif
