##############################################################################
#
#    GNU Health: The Free Health and Hospital Information System
#    Copyright (C) 2008-2026 Luis Falcon <lfalcon@gnusolidario.org>
#    Copyright (C) 2011-2026 GNU Solidario <health@gnusolidario.org>
#
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import gnuhealth.rpc as rpc
from gnuhealth.common import warning, message
import gettext
from datetime import datetime
import sys
import os

try:
    import cv2
except ImportError:
    pass


def set_attachment(data, frame):
    # Store the frame in a container
    _ = get_gettext()
    rc, container = cv2.imencode(".png", frame)
    container = container.tostring()
    document_model = data['model']
    ref = document_model + ',' + str(data['ids'][0])
    timestamp = str(datetime.now())
    attach_name = "GNU Health Camera " + timestamp

    # Store the attachment
    save_attach = rpc.execute(
        'model', 'ir.attachment', 'create',
        [{'name': attach_name,
          'type': 'data',
          'resource': ref,
          'description': None,
          'data': container,
          }], rpc.CONTEXT)

    if save_attach:
        message(
            _('Attachment is saved, Please refresh the view!'),
        )
        return True


def get_help():
    _ = get_gettext()
    message(
        _("========== GNU Health Camera Help ==========\n\n"
          "a = Attach media file in the current model\n\n"
          "[space] = Set the picture in model (when available)\n\n"
          "h = This help message\n\n"
          "q = Quit the camera application\n\n"))
    return True


def set_media(data, frame):
    # Store the frame in a container
    rc, container = cv2.imencode(".png", frame)
    container = container.tobytes()
    document_model = data['model']

    field_info = {
        'party.party': 'photo',
        'gnuhealth.patient.ecg': 'ecg_strip'}
    target_field = field_info.get(document_model)

    if (target_field):
        rpc.execute(
            'model', document_model, 'write',
            data['ids'],
            {target_field: container}, rpc.CONTEXT)

        return True
    else:
        return False


def main(data):
    _ = get_gettext()

    if "cv2" not in sys.modules:
        warning(
            _('Please install "opencv-python" and restart gnuhealth-client.'),
            _('CV2 library is not found!'))
        return

    # Allow only one record
    if (len(data['ids']) == 0):
        warning(
            _('Please choose one record associated to this picture / video'),
            _('You need to select a record !'),
        )
        return

    if (len(data['ids']) > 1):
        warning(
            _('Please choose only one record for this picture / video'),
            _('Multiple records selectd !'),
        )
        return

    # Open the camera device
    cap = cv2.VideoCapture(0)

    if (not cap.isOpened()):
        warning(
            _('Please ensure that your camera is working properly.'),
            _('No Camera is found!'),
        )
        return
    else:
        print("Camera device or fp opened..")

    while True:
        # Grab the frames
        try:
            rc, frame = cap.read()
        except BaseException:
            cleanup()

        # Display the resulting frame
        title = 'Camera:  [h]:Help  [q]:Quit  [a]:Attach  [SPC]:Photo'

        cv2.imshow(title, frame)

        keypressed = cv2.waitKey(1)

        if keypressed == ord(' '):
            cv2.imshow("Preview", frame)

            # Make a backup copy
            cv2.imwrite('/tmp/gnuhealth_snapshot_preview.png', frame)

            # call set media
            set_media(data, frame)

        if keypressed == ord('a'):
            cv2.imshow("Preview", frame)
            # Make a backup copy
            cv2.imwrite('/tmp/gnuhealth_snapshot_preview.png', frame)

            # call set media
            set_attachment(data, frame)
            break

        # Cleanup / Destroy window when q key is pressed or when closing
        # the window via alt+f4
        if (keypressed == ord('q')):
            break

        if keypressed == ord('h'):
            get_help()

    cleanup(cap)


def get_plugins(model):
    _ = get_gettext()
    return [
        (_('GNU Health camera'), main),
    ]


def get_gettext():
    try:
        localedir = os.path.dirname(os.path.abspath(__file__)) + '/locale'
        lang = gettext.translation('gnuhealth_camera', localedir=localedir)
        return lang.gettext
    except BaseException:
        return gettext.gettext


def cleanup(cap):
    # Release the camera capture
    cap.release()
    cv2.destroyAllWindows()
