"""Camera commands.

Original author: Mark Zvilius, 20-July-2019
For: The Sexton Corp
"""
import E2Protocol
import E2Configs

class Commands:
    """Provide handlers for commands.

    Commands come from housing buttons and/or keyboard keypresses
    (during testing/development).
    """

    def __init__(self, cameras=None, display=None, video=None):
        """Constructor.

        cameras -- CameraGroup instance
        display -- ParamGrid instance
        video -- VideoWindow instance
        """
        self.cameras = cameras
        self.display = display
        self.video = video


    #
    # The handlers send the command to the cameras, then update the
    # display with the new value and/or an error message.
    #
    # TODO: Need to improve these handlers for better DRY.
    #

    def wb_up(self):
        """Increase white-balance setting."""
        (new_value,errmsg) = E2Configs.setting_up(E2Protocol.KEY_WB)
        if new_value is None:
            return (-1,errmsg)

        (status,errmsg) = self.cameras.change_wb(new_value)
        if self.display is not None:
            self.display.update_wb(new_value)
            if status != 0: self.display.update_errmsg(errmsg)
            else: self.display.clear_errmsg()


    def wb_dn(self):
        """Decrease white-balance setting."""
        (new_value,errmsg) = E2Configs.setting_dn(E2Protocol.KEY_WB)
        if new_value is None:
            return (-1,errmsg)

        (status,errmsg) = self.cameras.change_wb(new_value)
        if self.display is not None:
            self.display.update_wb(new_value)
            if status != 0: self.display.update_errmsg(errmsg)
            else: self.display.clear_errmsg()


    def iso_up(self):
        """Increase iso setting."""
        (new_value,errmsg) = E2Configs.setting_up(E2Protocol.KEY_ISO)
        if new_value is None:
            return (-1,errmsg)

        (status,errmsg) = self.cameras.change_iso(new_value)
        if self.display is not None:
            self.display.update_iso(new_value)
            if status != 0: self.display.update_errmsg(errmsg)
            else: self.display.clear_errmsg()


    def iso_dn(self):
        """Decrease iso setting."""
        (new_value,errmsg) = E2Configs.setting_dn(E2Protocol.KEY_ISO)
        if new_value is None:
            return (-1,errmsg)

        (status,errmsg) = self.cameras.change_iso(new_value)
        if self.display is not None:
            self.display.update_iso(new_value)
            if status != 0: self.display.update_errmsg(errmsg)
            else: self.display.clear_errmsg()


    def shutter_up(self):
        """Increase shutter setting."""
        (new_value,errmsg) = E2Configs.setting_up(E2Protocol.KEY_SHUTTER)
        if new_value is None:
            return (-1,errmsg)

        (status,errmsg) = self.cameras.change_shutter(new_value)
        if self.display is not None:
            self.display.update_shutter(new_value)
            if status != 0: self.display.update_errmsg(errmsg)
            else: self.display.clear_errmsg()


    def shutter_dn(self):
        """Decrease shutter setting."""
        (new_value,errmsg) = E2Configs.setting_dn(E2Protocol.KEY_SHUTTER)
        if new_value is None:
            return (-1,errmsg)

        (status,errmsg) = self.cameras.change_shutter(new_value)
        if self.display is not None:
            self.display.update_shutter(new_value)
            if status != 0: self.display.update_errmsg(errmsg)
            else: self.display.clear_errmsg()


    def fstop_toggle(self):
        """Toggle f-stop (iris) setting."""
        (new_value,errmsg) = E2Configs.setting_wrap(E2Protocol.KEY_IRIS)
        if new_value is None:
            return (-1,errmsg)

        (status,errmsg) = self.cameras.change_fstop(new_value)
        if self.display is not None:
            self.display.update_fstop(new_value)
            if status != 0: self.display.update_errmsg(errmsg)
            else: self.display.clear_errmsg()

    ##
    #   Change video-encoder setting.
    #
    #   @param  self        Object pointer.
    #
    def encoder_toggle(self):
        (new_value,errmsg) = E2Configs.setting_wrap(E2Protocol.KEY_ENCODER)
        if new_value is None:
            return (-1,errmsg)

        self.stop_video()

        (status,errmsg) = self.cameras.change_encoder(new_value)
        if self.display is not None:
            self.display.update_encoder(new_value)
            if status != 0: self.display.update_errmsg(errmsg)

        self.video.restart()


    def record_toggle(self):
        """Recording start/stop."""
        (status,errmsg) = self.cameras.command_record_toggle()
        if self.display is not None:
            self.display.update_recording( self.cameras.recording )
            if status != 0: self.display.update_errmsg(errmsg)
            else: self.display.clear_errmsg()


    def cam_dn(self):
        """Decrease camera number on video display."""
        camera_id = self.video.command_camera_down()
        if self.display is not None:
            self.display.update_camera(camera_id)


    def cam_up(self):
        """Increase camera number on video display."""
        camera_id = self.video.command_camera_up()
        if self.display is not None:
            self.display.update_camera(camera_id)

    ##
    #   Stop video display (for testing).
    #
    #   @param  self        Object pointer.
    #
    def stop_video(self):
        self.video.stop()
        cam = self.video.get_camera()
        (status,errmsg) = cam.wait_for_stream_idle()
        if status != 0: self.display.update_errmsg(errmsg)

    ##
    #   Start video display (for testing).
    #
    #   @param  self        Object pointer.
    #
    def start_video(self):
        self.video.restart()

    def update_camera_temperature(self):
        """Read camera temperature and update on display."""
        (status,result) = self.cameras.get_temperature()
        if self.display is not None:
            if status == 0:
                self.display.update_temperature(result)
            else:
                self.display.update_errmsg(result)

