struct cdorganizer_controller;
struct cdorganizer_handle;

/**
 * Get a handle to an instance of the cdorganizer controller (cdorganizerd)
 * @param path Path to the domain socket
 * @return Handle to an instance of the cdorganizer controller
 */
struct cdorganizer_controller* cdorganizer_controller_init(const char* path);

/**
 * Get a list of detected organizers
 * @param controller Controller handle
 * @return Array of device ID strings
 */
const char** cdorganizer_controller_list_organizers(struct cdorganizer_controller *controller);

/**
 * Claim a detected organizer
 * @param controller Controller handle
 * @param id Device ID string
 * @return cdorganizer device handle
 */
struct cdorganizer_handle* cdorganizer_controller_claim_organizer(struct cdorganizer_controller *controller,
                                                                  const char* id);

/**
 * Release a claimed organizer
 * @param controller Controller handle
 * @param handle cdorganizer device handle
 * @return 0 on success, -1 on failure
 */
int cdorganizer_controller_release_organizer(struct cdorganizer_controller *controller,
                                             struct cdorganizer_handle *handle);

/**
 * Register an event handler with the controller
 * @param controller Controller handle
 * @param func Event handler function
 */
void cdorganizer_controller_register_event_handler(struct cdorganizer_controller *controller,
                                                   void(*func)(struct cdorganizer_controller*,
                                                               unsigned int, void*));

/* cdorganizer */
struct cdorganizer_vendor_cmd {
    int id;
    const char* name;
    const char* description;
};

/**
 * Insert disc into organizer
 * @param handle cdorganizer device handle
 * @param slot Requested slot number for the disc
 * @return Actual slot number, or -1 on error
 */
int cdorganizer_insert_disc(struct cdorganizer_handle *handle, int slot);

/**
 * Eject disc from organizer
 * @param handle cdorganizer device handle
 * @param slot Slot number for the disc
 * @return Slot number on success, or -1 on error
 */
int cdorganizer_eject_disc(struct cdorganizer_handle *handle, int slot);

/**
 * Get the number of slots in the organizer
 * @param handle cdorganizer device handle
 * @return Number of slots, or -1 on error
 */
int cdorganizer_get_max_slots(struct cdorganizer_handle *handle);

/**
 * Get the organizer's device ID
 * @param handle cdorganizer device handle
 * @return Device ID as a unique string
 */
const char* cdorganizer_get_device_id(struct cdorganizer_handle *handle);

/**
 * Get the organizer's user-friendly device name
 * @param handle cdorganizer device handle
 * @return Device name as a user-readable string (i.e. "Dacal DC300")
 */
const char* cdorganizer_get_device_name(struct cdorganizer_handle *handle);

/**
 * Get the organizer's last error message
 * @param handle cdorganizer device handle
 * @return Error message string
 */
const char* cdorganizer_get_last_error(struct cdorganizer_handle *handle);

/**
 * Get the organizer's vendor commands
 * @param handle cdorganizer device handle
 * @return Null-terminated array of vendor commands
 */
struct vendor_cmd** cdorganizer_get_vendor_cmds(struct cdorganizer_handle *handle);

/**
 * Execute a vendor command
 * @param handle cdorganizer device handle
 * @param cmd Vendor command
 * @return 0 on success, -1 on error
 */
int cdorganizer_exec_vendor_cmd(struct cdorganizer_handle *handle,
                                struct cdorganizer_vendor_cmd *cmd);

/**
 * Register an event handler with the organizer
 * @param handle cdorganizer device handle
 * @param func Event handler function
 */
void cdorganizer_register_event_handler(struct cdorganizer_handle *handle,
                                        void(*func)(struct cdorganizer_handle*,
                                                    unsigned int, void*));