{
  "$schema": "http://json-schema.org/draft-07/schema",
  "title": "ScanView Configuration",
  "description": "Schema for SDK JSON configurations",
  "type": "object",
  "properties": {
    "scanViewConfigDescription": {
      "description": "An optional description for the entire ScanView configuration.",
      "type": "string"
    },
    "cameraConfig": {
      "$ref": "#/definitions/cameraConfig"
    },
    "flashConfig": {
      "$ref": "#/definitions/flashConfig"
    },
    "viewPluginConfig": {
      "$ref": "#/definitions/viewPluginConfig"
    },
    "viewPluginCompositeConfig": {
      "$ref": "#/definitions/viewPluginCompositeConfig"
    },
    "options": {
      "type": "object"
    }
  },
  "definitions": {
    "offset": {
      "description": "An optional offset (in dp) for the elements.",
      "type": "object",
      "properties": {
        "x": {
          "type": "integer",
          "default": 0
        },
        "y": {
          "type": "integer",
          "default": 0
        }
      },
      "additionalProperties": false
    },
    "cameraConfig": {
      "description": "Schema for SDK Camera Configuration",
      "type": "object",
      "properties": {
        "captureResolution": {
          "description": "The preferred resolution for video capture (720p, 1080p, 4K). This resolution is used to process images for scanning. 4K resolution is only supported for barcode scanning.",
          "type": "string"
        },
        "pictureResolution": {
          "description": "Deprecated - do not use! The preferred resolution for taking images (720, 720p, 1080, 1080p).",
          "type": "string"
        },
        "defaultCamera": {
          "description": "Preferred camera to open: FRONT (front-facing), BACK (rear-facing), EXTERNAL (external rear), EXTERNAL_FRONT (external front), TELE (iOS-only; requests the telephoto lens and is honored only on devices that have one; on Android or on iOS devices without a tele lens BACK will be used), ULTRAWIDE (requests the ultra-wide lens and is honored only on devices that have one; on devices without an ultra-wide lens BACK will be used).",
          "type": "string",
          "default": "BACK"
        },
        "zoomGesture": {
          "description": "This flag enables or disables the zoom gesture if supported.",
          "type": "boolean",
          "default": false
        },
        "focalLength": {
          "description": "The focal length.",
          "type": "number",
          "default": 0
        },
        "zoomRatio": {
          "description": "The zoom ratio to apply to the camera. When set to a value greater than 0, this property takes precedence over defaultCamera for determining which physical lens to use. For example, setting zoomRatio to 0.5 on a device with an ultra-wide lens will select that lens, regardless of the defaultCamera setting. A value of 0 means no zoom ratio is applied and the camera selection falls back to defaultCamera.",
          "type": "number",
          "default": 0
        },
        "maxZoomRatio": {
          "description": "The maximum zoom ratio.",
          "type": "number",
          "default": 0
        },
        "maxFocalLength": {
          "description": "The maximum focal length.",
          "type": "number",
          "default": 0
        },
        "fallbackCameras": {
          "description": "Optional cameras to fall back if the defaultCamera is not found.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "enableTapToFocus": {
          "description": "Allow user to tap on the preview to focus the camera on a specific area of the screen (also known as tap-to-focus). Enabled by default.",
          "type": "boolean",
          "default": true
        },
        "tapToFocusTimeoutMs": {
          "description": "(Note: this functionality is experimental - use at your own risk.) Duration in milliseconds after which tap-to-focus automatically returns to continuous autofocus mode. Range: 1000-60000ms.",
          "type": "integer",
          "default": 5000,
          "minimum": 1000,
          "maximum": 60000
        },
        "enableFlipFramesLeftRight": {
          "description": "(EXPERIMENTAL; Android-only) Mirrors the frame sideways (left-right) before it is processed, equivalent to a horizontal flip along the vertical axis. The camera preview on the screen is not affected. Disabled by default. NOTE: This has no effect when pluginConfig.barcodeConfig.fastProcessMode is true.",
          "type": "boolean",
          "default": false
        },
        "enableFlipFramesTopBottom": {
          "description": "(EXPERIMENTAL; Android-only) Turns the frame upside down (top-bottom) before it is processed, equivalent to a vertical flip along the horizontal axis. The camera preview on the screen is not affected. Disabled by default. NOTE: This has no effect when pluginConfig.barcodeConfig.fastProcessMode is true.",
          "type": "boolean",
          "default": false
        }
      },
      "required": [
        "captureResolution"
      ],
      "additionalProperties": false
    },
    "flashConfig": {
      "description": "Schema for SDK Flash Configuration",
      "type": "object",
      "properties": {
        "mode": {
          "description": "The flash mode.",
          "type": "string",
          "enum": [
            "none",
            "auto",
            "manual",
            "manual_off",
            "manual_on"
          ],
          "default": "none"
        },
        "alignment": {
          "description": "The alignment of the flash button.",
          "type": "string",
          "enum": [
            "top",
            "top_left",
            "top_right",
            "bottom",
            "bottom_left",
            "bottom_right"
          ],
          "default": "top_left"
        },
        "offset": {
          "description": "An optional offset (in dp) for the flash button.",
          "$ref": "#/definitions/offset"
        },
        "imageOn": {
          "description": "The asset name of the icon to be displayed when the flash is on.",
          "type": "string"
        },
        "imageOff": {
          "description": "The asset name of the icon to be displayed when the flash is off.",
          "type": "string"
        },
        "imageAuto": {
          "description": "The asset name of the icon to be displayed when the flash is set to auto.",
          "type": "string"
        }
      },
      "required": [],
      "additionalProperties": false
    },
    "viewPluginConfig": {
      "description": "Schema for SDK ViewPlugin Configuration",
      "type": "object",
      "properties": {
        "pluginConfig": {
          "$ref": "./plugin_config.schema.json"
        },
        "cutoutConfig": {
          "$ref": "#/definitions/viewPluginConfig/definitions/cutoutConfig"
        },
        "scanFeedbackConfig": {
          "$ref": "#/definitions/viewPluginConfig/definitions/scanFeedbackConfig"
        },
        "uiFeedbackConfig": {
          "$ref": "./uifeedback_config.schema.json"
        }
      },
      "definitions": {
        "cutoutConfig": {
          "description": "Schema for SDK Cutout Configuration",
          "type": "object",
          "properties": {
            "alignment": {
              "description": "The alignment of the cutout area.",
              "type": "string",
              "enum": [
                "top",
                "top_half",
                "center",
                "bottom_half",
                "bottom"
              ],
              "default": "center"
            },
            "width": {
              "description": "The preferred width in pixels, relating to the camera resolution. If not specified or 0, the maximum possible width will be chosen.",
              "type": "integer",
              "default": 0
            },
            "maxWidthPercent": {
              "description": "The maximum width in percent (0-100), relating to the size of the view.",
              "type": "string"
            },
            "maxHeightPercent": {
              "description": "The maximum height in percent (0-100), relating to the size of the view.",
              "type": "string"
            },
            "ratioFromSize": {
              "description": "A size constraining the ratio of width / height. If set to 0, the ratio will be equal to the full frame. For the optimal ratio for each technical capability have a look at the Technical Capabilities section at documentation.anyline.com.",
              "type": "object",
              "properties": {
                "width": {
                  "type": "number",
                  "default": 0
                },
                "height": {
                  "type": "number",
                  "default": 0
                }
              },
              "additionalProperties": false
            },
            "strokeWidth": {
              "description": "The stroke width of the cutout. If set to 0, the line will be invisible.",
              "type": "integer",
              "default": 0
            },
            "strokeColor": {
              "description": "The hex string (RRGGBB) of the stroke color. (e.g. 00CCFF).",
              "type": "string",
              "default": "0099FF"
            },
            "feedbackStrokeColor": {
              "description": "The hex string (RRGGBB) of the stroke color for visual feedback. (e.g. 00CCFF).",
              "type": "string",
              "default": "0099FF"
            },
            "cornerRadius": {
              "description": "Radius of the corners of the cutout.",
              "type": "integer",
              "default": 0
            },
            "outerColor": {
              "description": "Background color as a 6-digit (RRGGBB) or 8-digit (AARRGGBB) hex string.",
              "type": "string",
              "default": "4D000000"
            },
            "outerAlpha": {
              "description": "Optional transparency factor for the outer color (0.0 - 1.0).",
              "type": "number",
              "minimum": 0,
              "maximum": 1
            },
            "offset": {
              "description": "Position offset of the cutout, used in conjunction with alignment.",
              "$ref": "#/definitions/offset"
            },
            "animation": {
              "description": "Animation type for the cutout when initially displayed. Values: none, fade, zoom",
              "type": "string",
              "enum": [
                "none",
                "fade",
                "zoom"
              ],
              "default": "none"
            },
            "cropPadding": {
              "description": "Amount of padding to be applied to the cutout (NOTE: use positive amounts only). A crop padding truncates the visual area represented by the cutout used in optimizing scan performance for some plugins. Define as an x-y point structure.",
              "$ref": "#/definitions/offset"
            },
            "cropOffset": {
              "description": "Used in conjunction with cropPadding. This offset further adjusts the crop position after the padding is applied. Define as an x-y point structure.",
              "$ref": "#/definitions/offset"
            }
          },
          "required": [],
          "additionalProperties": false
        },
        "scanFeedbackConfig": {
          "description": "Schema for SDK ScanFeedback Configuration",
          "type": "object",
          "properties": {
            "style": {
              "description": "The style of the feedback.",
              "type": "string",
              "enum": [
                "none",
                "rect",
                "contour_rect",
                "contour_point",
                "contour_underline",
                "animated_rect"
              ],
              "default": "rect"
            },
            "animation": {
              "description": "The animation style of the feedback.",
              "type": "string",
              "enum": [
                "none",
                "traverse_single",
                "traverse_multi",
                "kitt",
                "blink",
                "resize",
                "pulse",
                "pulse_random"
              ],
              "default": "none"
            },
            "redrawTimeout": {
              "description": "The timeout to redraw the visual feedback in milliseconds.",
              "type": "integer"
            },
            "cornerRadius": {
              "description": "The corner radius of the visual feedback.",
              "type": "integer"
            },
            "animationDuration": {
              "description": "The duration of the animation in milliseconds.",
              "type": "integer"
            },
            "strokeWidth": {
              "description": "The stroke width.",
              "type": "integer"
            },
            "strokeColor": {
              "description": "The stroke color.",
              "type": "string"
            },
            "fillColor": {
              "description": "The fill color.",
              "type": "string"
            },
            "beepOnResult": {
              "description": "If true, make a beep sound when a result is found.",
              "type": "boolean"
            },
            "blinkAnimationOnResult": {
              "description": "If true, flash the view when a result is found.",
              "type": "boolean"
            },
            "vibrateOnResult": {
              "description": "If true, vibrate the device when a result is found.",
              "type": "boolean"
            }
          },
          "required": [],
          "additionalProperties": false
        }
      },
      "required": [
        "pluginConfig"
      ],
      "additionalProperties": false
    },
    "viewPluginCompositeConfig": {
      "description": "Schema for SDK ViewPlugin Configuration",
      "type": "object",
      "properties": {
        "id": {
          "description": "The ID (name) of the workflow.",
          "type": "string"
        },
        "processingMode": {
          "description": "The processing mode of the workflow (parallel, sequential, parallelFirstScan).",
          "type": "string",
          "enum": [
            "parallel",
            "sequential",
            "parallelFirstScan"
          ]
        },
        "viewPlugins": {
          "description": "The ordered list of viewPlugins, each as JSON object with a given viewPluginConfig.",
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "viewPluginConfig": {
                "$ref": "#/definitions/viewPluginConfig"
              }
            },
            "additionalProperties": false
          },
          "minItems": 1
        }
      },
      "required": [
        "id",
        "processingMode",
        "viewPlugins"
      ],
      "additionalProperties": false
    }
  },
  "oneOf": [{"required": ["viewPluginConfig"]},{"required": ["viewPluginCompositeConfig"]}],
  "required": [],
  "additionalProperties": false
}
