#!D:\IDE\Anaconda3\envs\Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName   : CameraInterface.py
@Account    : Administrator
@Time       : 2025/8/28 14:07
@Author     : xsh
@Description: 
"""
from PyQt5 import Qt
from datetime import datetime, date
import copy
from AppInterfaces.AppDBInterface import (DBManager, dbController, DBInterface)
from sqlalchemy.orm import declarative_base, mapper, sessionmaker, Session
from sqlalchemy.orm import (declarative_base, Mapped, mapped_column, relationship, mapper, sessionmaker)
from sqlalchemy import Table, Engine, create_engine, Column, ForeignKey, and_, or_, insert, delete, update, select, func, ColumnElement,distinct
from sqlalchemy.types import (Text, VARCHAR, REAL, Float, Integer, String, SmallInteger, DateTime, Date, ARRAY,Boolean, JSON)
from sqlalchemy.orm.decl_api import DeclarativeBase, MetaData
from AppUtils.utils import *
from AppCore.Levels import *


class CameraInterface(DBInterface, DeclarativeBase):
    Information                         : str       #  '说明信息　　'
    Level                               : int       #  '物镜类型　　'     2
    ExposureMode                        : int       #  '曝光模式　　'     0
    TriggerMode                         : int       #  '触发模式　　'     0
    ShutterMode                         : int       #  '快门模式　　'     0
    ExposureAuto                        : int       #  '自动曝光　　'     0 ('Off', 'Once', 'Continuous')
    GainAuto                            : int       #  '自动增益　　'     ('Off', 'Once', 'Continuous')
    Width                               : int       #  '图像宽度　　'     2040
    Height                              : int       #  '图像高度　　'     2040
    BalanceWhiteAuto                    : int       #  '自动白平恒　'     ('Off', 'Once', 'Continuous') (0, 1, 2)
    ImageCount                          : int       #  '图像采集数量'
    ExposureTime                        : float     #  '曝光时间　　'     60
    ColorTransformationSelector         : float     #  '颜色转换表　'
    Gain                                : float     #  '增益数值　　'     0.0
    Gamma                               : float     #  '伽马数值　　'     1.0
    BlackLevel                          : float     #  '图像亮度　　'     0.0
    Axis_Offset_X                       : float     #  '位置偏移量　'
    Axis_Offset_Y                       : float     #  '位置偏移量　'
    Image_Offset_W                      : float     #  '像素偏移量　'
    Image_Offset_H                      : float     #  '像素偏移量　'
    PixelFormat                         : str       #  '图像格式　　'     ('BayerBG8', 'BayerBG12', 'BayerBG12p')
    LightSourcePreset                   : str       #  '光源预设　　'     ('Off', 'Daylight5000K', 'Daylight6500K', 'Tungsten2800K')
    VendorName                          : str       #  '相机厂家名称'
    ModelName                           : str       #  '相机型号名称'
    CenterX                             : bool      #  '水平居中　　'     True
    CenterY                             : bool      #  '垂直居中　　'     True
    ReverseX                            : bool      #  '水平镜像　　'     False
    ReverseY                            : bool      #  '垂直镜像　　'     False
    AberrationExposureTime              : float     #  '畸变曝光时间'
    MicronucleusExposureTime            : float     #  '微核曝光时间'
    KaryotypingExposureTime             : float     #  '核型曝光时间'
    def initDefaultModel(self):
        self.Information                        = '未知物镜相机参数　　'
        self.Level                              = ObjectiveLevel.ObjectiveNone #
        self.ExposureMode                       = 1                            #
        self.TriggerMode                        = 0                            #
        self.ShutterMode                        = 0                            #
        self.ExposureAuto                       = 0                            #
        self.GainAuto                           = 0                            #
        self.Width                              = 2040                         #
        self.Height                             = 2040                         #
        self.BalanceWhiteAuto                   = 0                            #
        self.ImageCount                         = 1                            #
        self.ExposureTime                       = 200.0                        #
        self.ColorTransformationSelector        = 0                            #
        self.Gain                               = 0.0                          #
        self.Gamma                              = 1.0                          #
        self.BlackLevel                         = 0.0                          #
        self.Axis_Offset_X                      = 0.0                          #
        self.Axis_Offset_Y                      = 0.0                          #
        self.Image_Offset_W                     = 1.0                          #
        self.Image_Offset_H                     = 1.0                          #
        self.PixelFormat                        = 'BayerRG8'                   #
        self.LightSourcePreset                  = 'Daylight5000K'              #
        self.VendorName                         = 'Basler'                     #
        self.ModelName                          = 'ML400-90C'                  # acA2040-90um
        self.CenterX                            = True                         #
        self.CenterY                            = True                         #
        self.ReverseX                           = False                        #
        self.ReverseY                           = False                        #
        self.AberrationExposureTime             = 65.0                          #
        self.MicronucleusExposureTime           = 65.0                          #
        self.KaryotypingExposureTime            = 65.0                          #


    @classmethod
    def instance(cls, **args):
        result: cls = cls.__new__(cls)
        result.__init__(**args)
        return result
    
    @classmethod
    def defaultModel(cls):
        result: cls = cls.__new__(cls)
        result.__init__()
        result.initDefaultModel()
        return result
    
    def flushInfo(self):
        if self.Level == ObjectiveLevel.Objective1    :
            self.Information = '１　　倍物镜相机参数'
        elif self.Level == ObjectiveLevel.Objective10   :
            self.Information = '１０　倍物镜相机参数'
        elif self.Level == ObjectiveLevel.Objective20   :
            self.Information = '２０　倍物镜相机参数'
        elif self.Level == ObjectiveLevel.Objective40   :
            self.Information = '４０　倍物镜相机参数'
        elif self.Level == ObjectiveLevel.Objective63   :
            self.Information = '６３　倍物镜相机参数'
        elif self.Level == ObjectiveLevel.Objective100  :
            self.Information = '１００倍物镜相机参数'
        else:
            self.Information = '未知物镜相机参数　　'
    
    def initParameter(self, **args):
        super(CameraInterface, self).initParameter(**args)
        self.flushInfo()


    def isAberration(self) -> bool:
        return self.isMono()

    def isMicronucleus(self) -> bool:
        return not self.isMono()

    def isKaryotyping(self) -> bool:
        return self.isMono()

    def isMono(self) -> bool:
        return self.PixelFormat == 'Mono8'

    @classmethod
    def getOffset(cls, level: int) -> (float, float, float, float):
        _level: int = ObjectiveLevel.ObjectiveNone if level not in ObjectiveLevel.all() else level
        item: CameraInterface = cls.Primary(_level)
        if item is None:
            item = cls.defaultModel()
        return item.Axis_Offset_Y, item.Axis_Offset_X, item.Image_Offset_W, item.Image_Offset_H
    @classmethod
    def getObjectiveConfig(cls, level: int) -> 'CameraInterface':
        _level: int = ObjectiveLevel.ObjectiveNone if level not in ObjectiveLevel.all() else level
        item: CameraInterface = cls.Primary(_level)
        if item is None:
            item = cls.defaultModel()
        return item


    @classmethod
    def getConfig(cls, level: int) -> 'CameraInterface':
        _level: int = ObjectiveLevel.ObjectiveNone if level not in ObjectiveLevel.all() else level
        item: CameraInterface = cls.Primary(_level)
        if item is None:
            item = cls.defaultModel()
        return item
    __header__ = (
        '说明信息　　',
        '物镜类型　　',
        '曝光模式　　',
        '触发模式　　',
        '快门模式　　',
        '自动曝光　　',
        '自动增益　　',
        '图像宽度　　',
        '图像高度　　',
        '自动白平恒　',
        '图像采集数量',
        '曝光时间　　',
        '颜色比例　　',
        '颜色比例　　',
        '颜色比例　　',
        '增益数值　　',
        '伽马数值　　',
        '图像亮度　　',
        '位置偏移量　',
        '位置偏移量　',
        '像素偏移量　',
        '像素偏移量　',
        '图像格式　　',
        '光源预设　　',
        '水平居中　　',
        '垂直居中　　',
        '水平镜像　　',
        '垂直镜像　　',
    )
    
    
    
    __field__ = (
        'Information'                  ,
        'Level'                        ,
        'ExposureMode'                 ,
        'TriggerMode'                  ,
        'ShutterMode'                  ,
        'ExposureAuto'                 ,
        'GainAuto'                     ,
        'Width'                        ,
        'Height'                       ,
        'BalanceWhiteAuto'             ,
        'ImageCount'                   ,
        'ExposureTime'                 ,
        'ColorTransformationSelector'  ,
        'Gain'                         ,
        'Gamma'                        ,
        'BlackLevel'                   ,
        'Axis_Offset_X'                ,
        'Axis_Offset_Y'                ,
        'Image_Offset_W'               ,
        'Image_Offset_H'               ,
        'PixelFormat'                  ,
        'LightSourcePreset'            ,
        'VendorName'                   ,
        'ModelName'                    ,
        'CenterX'                      ,
        'CenterY'                      ,
        'ReverseX'                     ,
        'ReverseY'                     ,
    )
    
    
    __types__ = (
        str   ,
        int   ,
        int   ,
        int   ,
        int   ,
        int   ,
        int   ,
        int   ,
        int   ,
        int   ,
        int   ,
        float ,
        float ,
        float ,
        float ,
        float ,
        float ,
        float ,
        float ,
        float ,
        str   ,
        str   ,
        str   ,
        str   ,
        bool  ,
        bool  ,
        bool  ,
        bool  ,
    )

    @property
    def hasInformation                 (self) -> bool:
        return hasattr(self, 'Information'          ) and isinstance(self.Information                 , str       )

    @property
    def hasLevel                       (self) -> bool:
        return hasattr(self, 'Level'                ) and isinstance(self.Level                       , int       )

    @property
    def hasExposureMode                (self) -> bool:
        return hasattr(self, 'ExposureMode'         ) and isinstance(self.ExposureMode                , int       )

    @property
    def hasTriggerMode                 (self) -> bool:
        return hasattr(self, 'TriggerMode'          ) and isinstance(self.TriggerMode                 , int       )

    @property
    def hasShutterMode                 (self) -> bool:
        return hasattr(self, 'ShutterMode'          ) and isinstance(self.ShutterMode                 , int       )

    @property
    def hasExposureAuto                (self) -> bool:
        return hasattr(self, 'ExposureAuto'         ) and isinstance(self.ExposureAuto                , int       )

    @property
    def hasGainAuto                    (self) -> bool:
        return hasattr(self, 'GainAuto'             ) and isinstance(self.GainAuto                    , int       )

    @property
    def hasWidth                       (self) -> bool:
        return hasattr(self, 'Width'                ) and isinstance(self.Width                       , int       )

    @property
    def hasHeight                      (self) -> bool:
        return hasattr(self, 'Height'               ) and isinstance(self.Height                      , int       )

    @property
    def hasBalanceWhiteAuto            (self) -> bool:
        return hasattr(self, 'BalanceWhiteAuto'     ) and isinstance(self.BalanceWhiteAuto            , int       )

    @property
    def hasImageCount                  (self) -> bool:
        return hasattr(self, 'ImageCount'           ) and isinstance(self.ImageCount                  , int       )

    @property
    def hasExposureTime                (self) -> bool:
        return hasattr(self, 'ExposureTime'         ) and isinstance(self.ExposureTime                , float     )

    @property
    def hasR_BalanceRatio              (self) -> bool:
        return hasattr(self, 'R_BalanceRatio'       ) and isinstance(self.R_BalanceRatio              , float     )

    @property
    def hasG_BalanceRatio              (self) -> bool:
        return hasattr(self, 'G_BalanceRatio'       ) and isinstance(self.G_BalanceRatio              , float     )

    @property
    def hasB_BalanceRatio              (self) -> bool:
        return hasattr(self, 'B_BalanceRatio'       ) and isinstance(self.B_BalanceRatio              , float     )

    @property
    def hasGain                        (self) -> bool:
        return hasattr(self, 'Gain'                 ) and isinstance(self.Gain                        , float     )

    @property
    def hasGamma                       (self) -> bool:
        return hasattr(self, 'Gamma'                ) and isinstance(self.Gamma                       , float     )

    @property
    def hasBlackLevel                  (self) -> bool:
        return hasattr(self, 'BlackLevel'           ) and isinstance(self.BlackLevel                  , float     )

    @property
    def hasAxis_Offset_X               (self) -> bool:
        return hasattr(self, 'Axis_Offset_X'        ) and isinstance(self.Axis_Offset_X               , float     )

    @property
    def hasAxis_Offset_Y               (self) -> bool:
        return hasattr(self, 'Axis_Offset_Y'        ) and isinstance(self.Axis_Offset_Y               , float     )

    @property
    def hasImage_Offset_W              (self) -> bool:
        return hasattr(self, 'Image_Offset_W'       ) and isinstance(self.Image_Offset_W              , float     )

    @property
    def hasImage_Offset_H              (self) -> bool:
        return hasattr(self, 'Image_Offset_H'       ) and isinstance(self.Image_Offset_H              , float     )

    @property
    def hasPixelFormat                 (self) -> bool:
        return hasattr(self, 'PixelFormat'          ) and isinstance(self.PixelFormat                 , str       )

    @property
    def hasLightSourcePreset           (self) -> bool:
        return hasattr(self, 'LightSourcePreset'    ) and isinstance(self.LightSourcePreset           , str       )

    @property
    def hasCenterX                     (self) -> bool:
        return hasattr(self, 'CenterX'              ) and isinstance(self.CenterX                     , bool      )

    @property
    def hasCenterY                     (self) -> bool:
        return hasattr(self, 'CenterY'              ) and isinstance(self.CenterY                     , bool      )

    @property
    def hasReverseX                    (self) -> bool:
        return hasattr(self, 'ReverseX'             ) and isinstance(self.ReverseX                    , bool      )

    @property
    def hasReverseY                    (self) -> bool:
        return hasattr(self, 'ReverseY'             ) and isinstance(self.ReverseY                    , bool      )

    