"""
Inscoper API Example Script: Snap Image (Synchronous)
=====================================================
This script demonstrates how to synchronously snap an image from the camera and plot it.

Configuration Prerequisites:
---------------------------
1. Environment Variable: Ensure 'InscoperConfigsPath' is defined in your environment
   and points to your Inscoper configurations folder.
2. Configuration Name: This script assumes a hardware configuration named "singleCamera".
   Change it below if your configuration is named differently.
3. Device Names: Change target camera names (e.g., "MyCamera") to match your setup.
"""

# --8<-- [start:main_logic]


import os
import numpy as np
import matplotlib.pyplot as plt
import inscoper_api


# Macro to all Inscoper configurations
CONFIG_PATH = os.environ['InscoperConfigsPath']

my_bridge = inscoper_api.Bridge()

# Load a specific configuration file
my_bridge.loadConfigFile(os.sep.join([CONFIG_PATH, "singleCamera"]))

# Initialize all the devices that were loaded from the configuration file
my_bridge.initDevices()

# Retrieve a list of the names of all successfully loaded and initialized devices
devices = my_bridge.getLoadedDevices()
print("Loaded devices: ", my_bridge.getLoadedDevices())

# Retrieve the specific camera object from the bridge using its configured name ("Camera")
my_camera = my_bridge.getCamera("MyCamera")

# Command the camera to take a single picture (snap an image)
# The argument '0' is the camera channel index (0 for mono)
image = my_camera.snapImage(0)

# Get the raw image data. This is typically returned as a flat 1D array of pixel values
image_data = image.getImageData()

image_width = image.getWidth()
image_height = image.getHeight()

# Get the total size of a single pixel in bytes
pixel_size_bytes = image.getPixelSize()

# Get the bit depth of the image (e.g., 8-bit, 12-bit, or 16-bit)
bit_depth = image.getBitDepth()

# Calculate the number of bytes used to represent a single intensity value
# For example, an 8-bit image uses 1 byte per value (8 // 8), a 16-bit image uses 2 bytes (16 // 8)
bytes_per_value = bit_depth // 8

# Calculate the number of values per pixel
# For a grayscale image, this is usually 1
values_per_pixel = pixel_size_bytes // bytes_per_value

print("Image width: ", image_width)
print("Image height: ", image_height)
print("Number of values per pixel: ", values_per_pixel)

# Reshape the flat 1D raw image data array into a numpy array
img = np.reshape(image_data, (image_height, image_width, values_per_pixel))

plt.imshow(img[:,:,0], cmap="gray")
plt.show()

# Safely close the connection to the hardware, release resources, and disconnect devices
my_bridge.close()

# --8<-- [end:main_logic]
