#!D:\IDE\Anaconda3\envs\Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
 @Author: Administrator
 @FileName: SlideModelInterface.py
 @DateTime: 2025/6/22 14:51
 @SoftWare: PyCharm
 @Author  ：xsh
"""
from PyQt5 import Qt
from datetime import datetime, date
import copy
import numpy as np
import cv2

from AppSettings.Settings import *
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 *
from AppCore.AppRequestModels.CameraRequest                         import CameraRequest
from AppCore.AppDBModels.ConfigModels.ObjectiveModel                import ObjectiveModel
from AppCore.AppDBModels.ConfigModels.FocusingConfigModel           import FocusingConfigModel
from AppCore.AppDBModels.TrayModels.TrayModel                       import TrayModel
from AppCore.AppDBModels.StateModels.CustomScanningModel            import CustomScanningModel
from AppCore.AppDBModels.TemplateModels.ScanTemplate                import ScanTemplate, Collectsettings, Previewsettings
from AppCore.AppDBModels.WeightModels.PreviewClassifierModel        import PreviewClassifierModel
from AppCore.AppDBModels.WeightModels.PreferredClassifierModel      import PreferredClassifierModel
from AppCore.AppDBModels.WeightModels.CollectClassifierModel        import CollectClassifierModel
class SlideModelInterface(DBInterface, DeclarativeBase):
    ID                  : int                               # '数据ＩＤ　　'
    Level               : int                               # '当前状态　　'
    ObjectiveLevel      : int                               # '物镜类型　　'
    ChamberGroupNumber  : int                               # '片仓组号　　'
    ChamberRowNumber    : int                               # '片仓行号　　'
    TrayNumber          : int                               # '托盘编号　　'
    LState              : int                               # '左边状态　　'
    RState              : int                               # '右边状态　　'
    RowNumber           : int                               # '图片行号　　'
    ColNumber           : int                               # '图片列号　　'
    ImageScore          : int                               # '图片评分　　'
    IsSave              : int                               # '是否保存　　'
    ImageCellX          : int                               # '小图中心Ｘ　'
    ImageCellY          : int                               # '小图中心Ｙ　'
    ImageCellWidth      : int                               # '小图宽度　　'
    ImageCellHeight     : int                               # '小图高度　　'
    ImageCellScore      : int                               # '小图评分　　'
    ImageCellType       : int                               # '小图类型　　'
    ScanTemplateID      : int                               # '模板ＩＤ　　'
    Index               : int                               # '数据序号　　'
    Position_X          : float                             # '托盘位置Ｘ　'
    Position_Y          : float                             # '托盘位置Ｙ　'
    Position_Z          : float                             # '托盘位置Ｚ　'
    CodeString          : str                               # '二维码编号　'
    SpecimenNumber      : str                               # '样本编号　　'
    SlideNumber         : str                               # '玻片编号　　'
    LineNumber          : str                               # '样本线号　　'
    FocusingSavePath    : str                               # '焦点数据　　'
    ScanningSavePath    : str                               # '平扫数据　　'
    SlideDataSavePath   : str                               # '玻片信息　　'
    SavePath            : str                               # '保存路径　　'
    InfoPath            : str                               # '保存路径　　'
    CollectCount        : int                               # '采集数量　　'
    PreviewCount        : int                               # '预选数量　　'
    Case_ID             : int                               # '数据序号　　'
    CreateTime          : datetime                          # '创建时间　　'
    SlideTable          : TrayModel                         # '托盘参数　　'
    Objective           : ObjectiveModel                    # '物镜参数　　'
    Focusing            : FocusingConfigModel               # '定焦参数　　'
    ScanTemplate        : ScanTemplate                      # '扫描模板　　'
    Preview             : Previewsettings                   # '模板参数　　'
    Collect             : Collectsettings                   # '模板参数　　'
    PreviewClassifier   : PreviewClassifierModel            # '预选模型　　'
    PreferredClassifier : PreferredClassifierModel          # '采集模型　　'
    CollectClassifier   : CollectClassifierModel            # '优选模型　　'
    Camera              : CameraRequest                     # '相机数据　　'
    @classmethod
    def instance(cls, **args):
        result: cls = cls.__new__(cls)
        result.__init__(**args)
        return result
    @classmethod
    def slidetable_instance(cls, chamber_number: int, chamber_row_number: int, tray_number: int, row_number: int = 1, col_number: int = 1, **args):
        result: cls = cls.__new__(cls)
        result.__init__(**args)
        result.ChamberGroupNumber   = chamber_number
        result.ChamberRowNumber     = chamber_row_number
        result.TrayNumber           = tray_number
        result.RowNumber            = row_number
        result.ColNumber            = col_number
        result.CreateTime           = datetime.now()
        cls.setSlidePosition(result.TrayNumber, result)
        return result
    def initValue(self):
        super(SlideModelInterface, self).initProperty()
        self.initCamera()

    def initProperty(self):
        super(SlideModelInterface, self).initProperty()
        self.ID                   = None
        self.Level                = ScanStatusLevel.Default_Status
        self.ObjectiveLevel       = ObjectiveLevel.ObjectiveNone
        self.ChamberGroupNumber   = 1
        self.ChamberRowNumber     = 1
        self.TrayNumber           = ModuleLevel.ModuleTraySlide1
        self.LState               = 0
        self.RState               = 0
        self.RowNumber            = 1
        self.ColNumber            = 1
        self.ImageScore           = 0
        self.IsSave               = 0
        self.ImageCellX           = 0
        self.ImageCellY           = 0
        self.ImageCellWidth       = 0
        self.ImageCellHeight      = 0
        self.ImageCellScore       = 0
        self.ImageCellType        = 0
        self.Index                = 0
        self.Position_X           = 0.0
        self.Position_Y           = 0.0
        self.Position_Z           = 0.0
        self.CodeString           = 0.0
        self.SpecimenNumber       = ''
        self.SlideNumber          = ''
        self.LineNumber           = ''
        self.ScanningSavePath     = ''
        self.SlideDataSavePath    = ''
        self.SavePath             = ''
        self.InfoPath             = ''
        self.CollectCount         = 0
        self.PreviewCount         = 0
        self.CreateTime           = datetime.now()


    def toObject(self, slide):
        if isinstance(slide, self.__class__):
            slide.initParameter(**self.to_field())
            slide.ID = self.ID
            slide.setParameter(self.index           , self.slideTable          , self.objective           ,
                               self.focusing        , self.scantemplate        , self.preview             ,
                               self.collect         , self.previewClassifier   , self.preferredClassifier ,
                               self.collectClassifier)
        pass

    def asObject(self, slide):
        if isinstance(slide, self.__class__):
            self.initParameter(**slide.to_field())
            self.ID = self.ID
            self.setParameter (slide.index           , slide.slidetable          , slide.objective           ,
                               slide.focusing        , slide.scantemplate        , slide.preview             ,
                               slide.collect         , slide.previewClassifier   , slide.preferredClassifier ,
                               slide.collectClassifier)
        pass
    def setPath(self,IsSave              : int = 0,SavePath            : str = None,FocusingSavePath    : str = None, ScanningSavePath    : str = None, SlideDataSavePath   : str = None):
        self.IsSave               = 1 if isinstance(IsSave, (int, bool)) and IsSave else 0
        self.SavePath             = SavePath          if isinstance(SavePath         , str) else None
        self.FocusingSavePath     = FocusingSavePath  if isinstance(FocusingSavePath , str) else None
        self.ScanningSavePath     = ScanningSavePath  if isinstance(ScanningSavePath , str) else None
        self.SlideDataSavePath    = SlideDataSavePath if isinstance(SlideDataSavePath, str) else None

    def setSlideParameter(self, Objective            : int = None ,ChamberGroupNumber   : int = None ,ChamberRowNumber     : int = None ,IsSave               : int = None ,Index                : int = None ,CollectCount         : int = None ,PreviewCount         : int = None ):
        self.ObjectiveLevel       = Objective             if isinstance(Objective               , int) else self.ObjectiveLevel
        self.ChamberGroupNumber   = ChamberGroupNumber    if isinstance(ChamberGroupNumber      , int) else self.ChamberGroupNumber
        self.ChamberRowNumber     = ChamberRowNumber      if isinstance(ChamberRowNumber        , int) else self.ChamberRowNumber
        self.IsSave               = 1                      if isinstance(IsSave, (int, bool)) and IsSave else 0
        self.Index                = Index                 if isinstance(Index                   , int) else None
        self.CollectCount         = CollectCount          if isinstance(CollectCount            , int) else None
        self.PreviewCount         = PreviewCount          if isinstance(PreviewCount            , int) else None

    def setPosition(self, Position_X: (float, int) = None,Position_Y: (float, int) = None,Position_Z: (float, int) = None):
        self.Position_X           = Position_X if isinstance(Position_X, (float, int)) else self.Position_X
        self.Position_Y           = Position_Y if isinstance(Position_Y, (float, int)) else self.Position_Y
        self.Position_Z           = Position_Z if isinstance(Position_Z, (float, int)) else self.Position_Z


    def setLocation(self, ChamberNumber: int = None, ChamberRowNumber: int = None,TrayNumber: int = None, Objective: int = None, Level: int = None, RowNumber: int = None, ColNumber: int = None):
        self.ChamberGroupNumber     = ChamberNumber         if isinstance(ChamberNumber         , int) else self.ChamberGroupNumber
        self.ChamberRowNumber       = ChamberRowNumber      if isinstance(ChamberRowNumber      , int) else self.ChamberRowNumber
        self.TrayNumber             = TrayNumber            if isinstance(TrayNumber            , int) else self.TrayNumber
        self.ObjectiveLevel         = Objective             if isinstance(Objective             , int) else self.ObjectiveLevel
        self.Level                  = Level                 if isinstance(Level                 , int) else self.Level
        self.RowNumber              = RowNumber             if isinstance(RowNumber             , int) else self.RowNumber
        self.ColNumber              = ColNumber             if isinstance(ColNumber             , int) else self.ColNumber

    def setChamberLocation(self, ChamberNumber: int = None, ChamberRowNumber: int = None,TrayNumber: int = None, Objective: int = None, Level: int = None, RowNumber: int = None, ColNumber: int = None):
        self.ChamberGroupNumber     = ChamberNumber         if isinstance(ChamberNumber         , int) else self.ChamberGroupNumber
        self.ChamberRowNumber       = ChamberRowNumber      if isinstance(ChamberRowNumber      , int) else self.ChamberRowNumber
        self.TrayNumber             = TrayNumber            if isinstance(TrayNumber            , int) else self.TrayNumber
        self.ObjectiveLevel         = Objective             if isinstance(Objective             , int) else self.ObjectiveLevel
        self.Level                  = Level                 if isinstance(Level                 , int) else self.Level
        self.RowNumber              = RowNumber             if isinstance(RowNumber             , int) else self.RowNumber
        self.ColNumber              = ColNumber             if isinstance(ColNumber             , int) else self.ColNumber


    def setTrayLocation(self, ChamberNumber: int = None, ChamberRowNumber: int = None,TrayNumber: int = None, RowNumber: int = None, ColNumber: int = None):
        self.ChamberGroupNumber     = ChamberNumber         if isinstance(ChamberNumber         , int) else self.ChamberGroupNumber
        self.ChamberRowNumber       = ChamberRowNumber      if isinstance(ChamberRowNumber      , int) else self.ChamberRowNumber
        self.TrayNumber             = TrayNumber            if isinstance(TrayNumber            , int) else self.TrayNumber
        self.RowNumber              = RowNumber             if isinstance(RowNumber             , int) else self.RowNumber
        self.ColNumber              = ColNumber             if isinstance(ColNumber             , int) else self.ColNumber

    def setCell(self, ImageCellX      : (float, int),ImageCellY      : (float, int),ImageCellWidth  : (float, int),ImageCellHeight : (float, int),ImageCellScore  : (float, int),ImageCellType   : (float, int)):
        self.ImageCellX           = ImageCellX       if isinstance(ImageCellX      , (float, int)) else 0
        self.ImageCellY           = ImageCellY       if isinstance(ImageCellY      , (float, int)) else 0
        self.ImageCellWidth       = ImageCellWidth   if isinstance(ImageCellWidth  , (float, int)) else 0
        self.ImageCellHeight      = ImageCellHeight  if isinstance(ImageCellHeight , (float, int)) else 0
        self.ImageCellScore       = ImageCellScore   if isinstance(ImageCellScore  , (float, int)) else 0
        self.ImageCellType        = ImageCellType    if isinstance(ImageCellType   , (float, int)) else 0

    def setSpecimen(self, CodeString           : str = None,SpecimenNumber       : str = None,SlideNumber          : str = None,LineNumber           : str = None,LState               : int = None,RState               : int = None):
        self.CodeString         = CodeString     if isinstance(CodeString           , str) else None
        self.LState             = 1 if isinstance(LState, (int, bool)) and LState else 0
        self.RState             = 1 if isinstance(RState, (int, bool)) and RState else 0
        self.SpecimenNumber     = f'{SpecimenNumber}' if SpecimenNumber is not None else self.CodeString
        self.SlideNumber        = f'{SlideNumber   }' if SlideNumber    is not None else f'{self.ChamberRowNumber}'
        self.LineNumber         = f'{LineNumber    }' if LineNumber     is not None else None



































    __field__ = (
        'ID'                    ,
        'Level'                 ,
        'ObjectiveLevel'        ,
        'ChamberGroupNumber'    ,
        'ChamberRowNumber'      ,
        'TrayNumber'            ,
        'LState'                ,
        'RState'                ,
        'RowNumber'             ,
        'ColNumber'             ,
        'ImageScore'            ,
        'IsSave'                ,
        'ImageCellX'            ,
        'ImageCellY'            ,
        'ImageCellWidth'        ,
        'ImageCellHeight'       ,
        'ImageCellScore'        ,
        'ImageCellType'         ,
        'ScanTemplateID'        ,
        'Index'                 ,
        'Position_X'            ,
        'Position_Y'            ,
        'Position_Z'            ,
        'CodeString'            ,
        'SpecimenNumber'        ,
        'SlideNumber'           ,
        'LineNumber'            ,
        'FocusingSavePath'      ,
        'ScanningSavePath'      ,
        'SlideDataSavePath'     ,
        'SavePath'              ,
        'CollectCount'          ,
        'PreviewCount'          ,
        'Case_ID'               ,
        'CreateTime'            ,
    )
    __types__ = (
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        int      ,
        float    ,
        float    ,
        float    ,
        str      ,
        str      ,
        str      ,
        str      ,
        str      ,
        str      ,
        str      ,
        str      ,
        int      ,
        int      ,
        int      ,
        datetime ,
    )

    __header__ = (
        '数据ＩＤ　　',
        '当前状态　　',
        '物镜类型　　',
        '片仓组号　　',
        '片仓行号　　',
        '托盘编号　　',
        '左边状态　　',
        '右边状态　　',
        '图片行号　　',
        '图片列号　　',
        '图片评分　　',
        '是否保存　　',
        '小图中心Ｘ　',
        '小图中心Ｙ　',
        '小图宽度　　',
        '小图高度　　',
        '小图评分　　',
        '小图类型　　',
        '模板ＩＤ　　',
        '数据序号　　',
        '托盘位置Ｘ　',
        '托盘位置Ｙ　',
        '托盘位置Ｚ　',
        '二维码编号　',
        '样本编号　　',
        '玻片编号　　',
        '样本线号　　',
        '焦点数据　　',
        '平扫数据　　',
        '玻片信息　　',
        '保存路径　　',
        '采集数量　　',
        '预选数量　　',
        '数据序号　　',
        '创建时间　　',
    )
    def setParameter(self, index, slidetable, objective, focusing, scantemplate, preview, collect, previewClassifier, preferredClassifier, collectClassifier):
        self.SlideTable               = slidetable          if isinstance(slidetable         , TrayModel               ) else None      #
        self.Objective                = objective           if isinstance(objective          , ObjectiveModel          ) else None      #
        self.Focusing                 = focusing            if isinstance(focusing           , FocusingConfigModel     ) else None      #
        self.ScanTemplate             = scantemplate        if isinstance(scantemplate       , ScanTemplate            ) else None      #
        self.Preview                  = preview             if isinstance(preview            , Previewsettings         ) else None      #
        self.Collect                  = collect             if isinstance(collect            , Collectsettings         ) else None      #
        self.PreviewClassifier        = previewClassifier   if isinstance(previewClassifier  , PreviewClassifierModel  ) else None      #
        self.PreferredClassifier      = preferredClassifier if isinstance(preferredClassifier, PreferredClassifierModel) else None      #
        self.CollectClassifier        = collectClassifier   if isinstance(collectClassifier  , CollectClassifierModel  ) else None      #
        self.Index                    = index if isinstance(index, int) else 0                    #


    def copy(self):
        result = self.__class__.__new__(self.__class__)
        result.__init__()
        result.as_field(self.to_field())
        if self.hasCamera:
            result.initCamera()
            result.camera.ImageSource = self.toImage()

        result.setParameter   (self.index           , self.slidetable          , self.objective           ,
                               self.focusing        , self.scantemplate        , self.preview             ,
                               self.collect         , self.previewClassifier   , self.preferredClassifier ,
                               self.collectClassifier)
        result.Index = self.index
        return result

    def to_save_field(self, is_primary: bool = True) -> dict[str, object]:
        buffer: dict[str, object] = {}
        primary: str = ''
        try:
            primary = DBInterface.get_primary_name(self)
        except Exception as e:
            primary = ''
        for index, _property in enumerate(self.__field__):
            if is_primary:
                buffer[_property] = getattr(self, _property, None)
            else:
                if _property != primary:
                    buffer[_property] = getattr(self, _property, None)
        return buffer




    @classmethod
    def copyInstance(cls, slide: object, box: list = None):
        result: cls = cls.__new__(cls)
        result.__init__()
        if isinstance(slide, SlideModelInterface):
            result.as_field(slide.to_field())
            if slide.hasCamera:
                result.initCamera()
                result.camera.ImageSource = slide.toImage()
            result.SlideTable               = slide.slidetable
            result.Objective                = slide.objective
            result.Focusing                 = slide.focusing
            result.ScanTemplate             = slide.scantemplate
            result.Preview                  = slide.preview
            result.Collect                  = slide.collect
            result.PreviewClassifier        = slide.previewClassifier
            result.PreferredClassifier      = slide.preferredClassifier
            result.CollectClassifier        = slide.collectClassifier
            result.Index                    = slide.index
        else:
            result.fromObject(slide)
        result.setCellBox(box)
        return result
        pass

    @classmethod
    def DataInstance(cls, slide: object, box: list = None):
        result: cls = cls.__new__(cls)
        result.__init__()
        if isinstance(slide, SlideModelInterface):
            result.as_field(slide.to_field())
            result.setParameter(slide.index                 , slide.slidetable          ,slide.objective           ,
                                slide.focusing              ,slide.scantemplate         ,slide.preview             ,
                                slide.collect               ,slide.previewClassifier    ,slide.preferredClassifier ,
                                slide.collectClassifier    )
        result.setCellBox(box)
        return result

    @classmethod
    def copyDataInstance(cls, slide: object, box: list = None):
        result: cls = cls.__new__(cls)
        result.__init__()
        if isinstance(slide, SlideModelInterface):
            result.as_field(slide.to_field(False))
        else:
            result.fromObject(slide)
        result.setCellBox(box)

        return result

    @classmethod
    def SlideInstance(cls, slide: 'SlideModelInterface', box: list):
        result: cls = cls.__new__(cls)
        result.__init__()
        if slide is not None:
            result.initParameter(**slide.to_field())
            result.ID = None
            result.setParameter(slide.index                 , slide.slidetable          ,slide.objective           ,
                                slide.focusing              ,slide.scantemplate         ,slide.preview             ,
                                slide.collect               ,slide.previewClassifier    ,slide.preferredClassifier ,
                                slide.collectClassifier    )

        result.setCellBox(box)
        return result

    @classmethod
    def CellInstance(cls, box: list, **args):
        result: cls = cls.__new__(cls)
        result.__init__()
        result.initParameter(**args)
        result.deserialize(args)
        result.setCellBox(box)
        return result

    def setCellBox(self, box: list):
        if isinstance(box, list) and len(box) >= 6:
            self.ImageCellX       = box[0]
            self.ImageCellY       = box[1]
            self.ImageCellWidth   = box[2]
            self.ImageCellHeight  = box[3]
            self.ImageCellScore   = box[4]
            self.ImageCellType    = box[5]

    def fromObject(self, other: object):
        if other is None:
            return
        if isinstance(other, dict):
            for index, _property in enumerate(self.__field__):
                if _property in other:
                    setattr(self, _property, AppConvert.ObjectConvert(other.get(_property, None), self.__types__[index]))
        elif isinstance(other, SlideModelInterface):
            for index, _property in enumerate(self.__field__):
                setattr(self, _property, getattr(other, _property, None))

            self.setParameter  (other.index                 ,other.slidetable           ,other.objective           ,
                                other.focusing              ,other.scantemplate         ,other.preview             ,
                                other.collect               ,other.previewClassifier    ,other.preferredClassifier ,
                                other.collectClassifier    )

            self.initCamera()
            if other.hasImageSource:
                self.camera.ImageSource = other.toImage()
    @classmethod
    def InitCheckStatus(cls, Chamber_Number: int) -> int:
        isWrong: int = RECODE_FAILURE
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(Chamber_Number, 1)
        items: list[cls]
        item: cls
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber).update({
                    cls.LState          : 0                               ,
                    cls.RState          : 0                               ,
                    cls.CodeString      : None                            ,
                    cls.SpecimenNumber  : None                            ,
                    cls.LineNumber      : None                            ,
                    cls.SlideNumber     : None                            ,
                    cls.Level           : ScanStatusLevel.Default_Status  ,
                    cls.CollectCount    : 0                               ,
                    cls.PreviewCount    : 0                               ,
                })
                session.commit()
                session.close()
            isWrong = RECODE_SUCCEED
        except Exception as e:
            isWrong = RECODE_FAILURE
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return isWrong

    @classmethod
    def InitAllCheckStatus(cls) -> int:
        isWrong: int = RECODE_FAILURE
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        ChamberNumber: int
        RowNumber: int
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).update({
                    cls.LState          : 0                               ,
                    cls.RState          : 0                               ,
                    cls.CodeString      : None                            ,
                    cls.SpecimenNumber  : None                            ,
                    cls.LineNumber      : None                            ,
                    cls.SlideNumber     : None                            ,
                    cls.Level           : ScanStatusLevel.Default_Status  ,
                    cls.CollectCount    : 0                               ,
                    cls.PreviewCount    : 0                               ,
                })

                session.commit()
                session.close()
            isWrong = RECODE_SUCCEED
        except Exception as e:
            isWrong = RECODE_FAILURE
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return isWrong

    @classmethod
    def setEmptyData(cls):
        isWrong: int = RECODE_FAILURE
        ChamberNumber: int
        RowNumber: int
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).update({
                    cls.LState              : 0                                 ,
                    cls.RState              : 0                                 ,
                    cls.CodeString          : None                              ,
                    cls.SpecimenNumber      : None                              ,
                    cls.LineNumber          : None                              ,
                    cls.SlideNumber         : None                              ,
                    cls.Level               : ScanStatusLevel.Default_Status    ,
                    cls.CollectCount        : 0                                 ,
                    cls.PreviewCount        : 0                                 ,
                    cls.ChamberGroupNumber  : 0                                 ,
                    cls.ChamberRowNumber    : 0                                 ,
                })

                session.commit()
                session.close()
            isWrong = RECODE_SUCCEED
        except Exception as e:
            isWrong = RECODE_FAILURE
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return isWrong
    @classmethod
    def getStatusModel(cls, chamber_number: int, row_number: int) -> 'SlideModelInterface':
        from AppSettings.SystemSetting import SystemSetting, SystemConfig, SystemConfig
        ChamberNumber   : int
        RowNumber       : int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        item: cls = cls.instance()
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber, cls.ChamberRowNumber == RowNumber).first()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)

        return item

    @classmethod
    def getChamberSlide(cls, chamber_number: int, row_number: int) -> 'SlideModelInterface':
        from AppSettings.SystemSetting import SystemSetting, SystemConfig, SystemConfig
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        item: cls = cls.instance()
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber, cls.ChamberRowNumber == RowNumber).first()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)

        return item

    @classmethod
    def setChamberSlideScanningDateTime(cls, chamber_number: int, row_number: int, scanningDateTime: Qt.QDateTime):
        from AppSettings.SystemSetting import SystemSetting, SystemConfig, SystemConfig
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        try:
            scanning_DateTime: datetime
            if isinstance(scanningDateTime, Qt.QDateTime):
                scanning_DateTime = scanningDateTime.toPyDateTime()
            elif isinstance(scanningDateTime, datetime):
                scanning_DateTime = scanningDateTime
            else:
                scanning_DateTime = datetime.now()

            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber, cls.ChamberRowNumber == RowNumber).update({'CreateTime': scanning_DateTime})
                session.commit()
                session.close()
        except Exception as e:

            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)

    @classmethod
    def getChamberSlideScanningDateTime(cls, chamber_number: int, row_number: int) -> datetime:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig, SystemConfig
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        item: cls = cls.instance()
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber, cls.ChamberRowNumber == RowNumber).first()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
            item = cls.instance()
        return item.CreateTime

    @classmethod
    def getChamberModel(cls, chamber_number: int, row_number: int) -> list['SlideModelInterface']:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        items : list[cls] = []
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                items = session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber, cls.ChamberRowNumber == RowNumber).all()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)

        return items
    @classmethod
    def getPointModel(cls, tray_number: int, row_number: int, col_number: int) -> 'SlideModelInterface':
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        _level: int = tray_number if tray_number == ModuleLevel.ModuleTraySlide2 else ModuleLevel.ModuleTraySlide1
        RowNumber: int
        ColNumber: int
        RowNumber, ColNumber = SystemConfig.getPointNumbers(row_number, col_number)
        item: cls = None
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.RowNumber  == RowNumber        ,
                                                 cls.ColNumber  == ColNumber        ,
                                                 cls.TrayNumber == _level           ).first()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return item

    @classmethod
    def setChamberLStatus(cls, chamber_number: int, row_number: int, l_status: (bool, int)):
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        item: cls
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber,
                                          cls.ChamberRowNumber == RowNumber).update(
                    {
                        cls.LState: 1 if isinstance(l_status, (bool, int)) and l_status else 0,
                    })
                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return RECODE_SUCCEED

    @classmethod
    def setChamberTrayStatus(cls, chamber_number: int, status: (int, bool)):
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, 1)
        MinRowNumber: int
        MaxRowNumber: int
        state: int = 1 if isinstance(status, (int, bool)) and status else 0
        item: cls
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber).update(
                    {
                        cls.LState: state,
                        cls.RState: state,
                    })
                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return RECODE_SUCCEED

    @classmethod
    def setChamberTraySlideStatus(cls, chamber_number: int, row_number: int, status: (int, bool)):
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        MinRowNumber: int
        MaxRowNumber: int
        state: int = 1 if isinstance(status, (int, bool)) and status else 0
        item: cls
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber, cls.ChamberRowNumber==RowNumber).update(
                    {
                        cls.LState: state,
                        cls.RState: state,
                    })
                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return RECODE_SUCCEED

    @classmethod
    def setChamberDetectorStatus(cls, status: list[int]):
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        ChamberNumber: int
        RowNumber: int
        # ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, 1)
        MinRowNumber: int
        MaxRowNumber: int
        MinRowNumber, MaxRowNumber = SystemConfig.getChamberRange()
        state: int = 1 if isinstance(status, (int, bool)) and status else 0
        item: cls
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                for chamber_number in range(MinRowNumber, MaxRowNumber + 1):
                    try:
                        state = 1 if isinstance(status[chamber_number - 1], (int, bool)) and status[chamber_number - 1] else 0
                    except Exception as e:
                        state = 0
                    session.query(cls).filter(cls.ChamberGroupNumber == chamber_number).update(
                        {
                            cls.LState: state,
                            cls.RState: state,
                        })

                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return RECODE_SUCCEED

    @classmethod
    def setLStatus(cls, chamber_number: int, status: list[int]):
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        ChamberNumber   : int
        RowNumber       : int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, 1)
        MinRowNumber    : int
        MaxRowNumber    : int
        MinRowNumber, MaxRowNumber = SystemConfig.getRowRange()

        item: cls
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                for RowNumber, state in enumerate(status):
                    session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber, cls.RowNumber == RowNumber + 1).update(
                        {
                            cls.LState: state,
                        })
                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return RECODE_SUCCEED

    @classmethod
    def setRStatus(cls, chamber_number: int, status: list[int]):
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, 1)
        MinRowNumber: int
        MaxRowNumber: int
        MinRowNumber, MaxRowNumber = SystemConfig.getRowRange()

        item: cls
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                for RowNumber, state in enumerate(status):
                    session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber, cls.RowNumber == RowNumber + 1).update(
                        {
                            cls.RState: state,
                        })
                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return RECODE_SUCCEED

    @classmethod
    def changedScanStatus(cls, chamber_number: int, row_number: int, level: int):
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ChamberGroupNumber == chamber_number, cls.ChamberRowNumber == row_number).update(
                    {
                        cls.Level : level,
                    })
                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)

    @classmethod
    def setChamberRStatus(cls, chamber_number: int, row_number: int, r_status: (bool, int)):
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        item: cls
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber,
                                          cls.ChamberRowNumber == RowNumber).update(
                    {
                        cls.RState: 1 if isinstance(r_status, (bool, int)) and r_status else 0,
                    })
                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return 1

    @classmethod
    def setChamberScanningStatus(cls, chamber_number: int, row_number: int, level: int):
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ChamberGroupNumber == chamber_number, cls.ChamberRowNumber == row_number).update(
                    {
                        cls.Level: level if level in ScanStatusLevel.all() else ScanStatusLevel.Default_Status
                     })
                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)

    @classmethod
    def setScanningStatus(cls, chamber_number: int, row_number: int, level: int):
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ChamberGroupNumber == chamber_number,
                                          cls.ChamberRowNumber == row_number).update(
                    {
                        cls.Level: level if level in ScanStatusLevel.all() else ScanStatusLevel.Default_Status
                    })
                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)


    @classmethod
    def setCurrentScanningStatus(cls, chamber_number: int, row_number: int, level: int, template_id: int = None):
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ChamberGroupNumber == chamber_number, cls.ChamberRowNumber == row_number).update(
                    {
                        cls.Level: level if level in ScanStatusLevel.all() else ScanStatusLevel.Default_Status,
                        cls.ScanTemplateID: template_id,

                    })
                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)

    @classmethod
    def setGroupScanningStatus(cls, chamber_number: int, level: int):
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ChamberGroupNumber == chamber_number).update(
                    {
                        cls.Level: level if level in ScanStatusLevel.all() else ScanStatusLevel.Default_Status
                    })
                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)

    @classmethod
    def setGroupScanningSlideStatus(cls, chamber_number: int, level: int, l_status: (bool, int), r_status: (bool, int)):
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                try:
                    session.query(cls).filter(cls.ChamberGroupNumber == chamber_number).update(
                        {
                            cls.Level: level if level in ScanStatusLevel.all() else ScanStatusLevel.Default_Status,
                            cls.LState: 1 if isinstance(l_status, (bool, int)) and l_status else 0,
                            cls.RState: 1 if isinstance(r_status, (bool, int)) and r_status else 0,
                        })
                except Exception as controlE:
                    session.rollback()
                else:
                    session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)

    @classmethod
    def setChamberStatus(cls, chamber_number: int, row_number: int, l_status: (bool, int), r_status: (bool, int)):
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong = 0
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        items: list[cls] = []
        item: cls
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber,
                                          cls.ChamberRowNumber == RowNumber).update(
                    {
                        cls.LState: 1 if isinstance(l_status, (bool, int)) and l_status else 0,
                        cls.RState: 1 if isinstance(r_status, (bool, int)) and r_status else 0,
                     })
                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return 1

    @classmethod
    def setChamberStatusModel(cls, chamber_number: int, row_number: int, l_status: (bool, int), r_status: (bool, int), codeString: str):
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong = 0
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        items: list[cls] = []
        item: cls
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber,
                                          cls.ChamberRowNumber == RowNumber).update(
                    {
                        cls.LState: 1 if isinstance(l_status, (bool, int)) and l_status else 0,
                        cls.RState: 1 if isinstance(r_status, (bool, int)) and r_status else 0,
                        cls.CodeString: '' if not isinstance(codeString, str) else codeString
                    })
                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return 1

    @classmethod
    def setCodeString(cls, chamber_number: int, row_number: int, codeString: str):
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong         = 0
        ChamberNumber   : int
        RowNumber       : int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        cls.model_update({cls.CodeString: codeString}, cls.ChamberGroupNumber == ChamberNumber, cls.ChamberRowNumber == RowNumber)


    @classmethod
    def setChamberCodeString(cls, chamber_number: int, row_number: int, codeString: str, specimen_no : str = None,slide_no    : str = None,line_no     : str = None):
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong         = 0
        ChamberNumber   : int
        RowNumber       : int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        item: cls
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber, cls.ChamberRowNumber == RowNumber).update(
                    {
                        cls.CodeString      :   codeString  ,
                        cls.SpecimenNumber  :   specimen_no ,
                        cls.LineNumber      :   line_no     ,
                        cls.SlideNumber     :   slide_no    ,
                    }
                )
                session.commit()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return 1

    @classmethod
    def getChamberLStatus(cls, chamber_number: int, row_number: int) -> int:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong = 0
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        item: cls
        l_status: int = 0
        r_status: int = 0
        code    : str = ''
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber,
                                                  cls.ChamberRowNumber == RowNumber).first()
                if item is not None:
                    l_status = item.LState
                    r_status = item.RState
                    code     = item.CodeString
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return l_status

    @classmethod
    def getChamberRStatus(cls, chamber_number: int, row_number: int) -> int:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong = 0
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        item: cls
        l_status: int = 0
        r_status: int = 0
        code: str = ''
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber,
                                                 cls.ChamberRowNumber == RowNumber).first()
                if item is not None:
                    l_status = item.LState
                    r_status = item.RState
                    code = item.CodeString
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return r_status

    @classmethod
    def getCheckSlideStatus(cls, chamber_number: int, row_number: int) -> (int, int, str):
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong         : int = RECODE_FAILURE
        ChamberNumber   : int
        RowNumber       : int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        item: cls
        l_status        : int = 0
        r_status        : int = 0
        codestring      : str = ''
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber, cls.ChamberRowNumber == RowNumber).first()
                if item is not None:
                    l_status    = item.LState
                    r_status    = item.RState
                    codestring  = item.CodeString
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return l_status, r_status, codestring

    @classmethod
    def getBeginTraySlide(cls, level: int):
        result: cls = cls.__new__(cls)
        result.__init__()
        tray_model: TrayModel = TrayModel.getTrayModel(level)
        result.RowNumber          = 1
        result.ColNumber          = 1
        result.Position_X         = tray_model.Position_X
        result.Position_Y         = tray_model.Position_Y
        result.Position_Z         = tray_model.Position_Z
        return result

    @classmethod
    def IsCheckAvailable(cls, chamber_number: int, row_number: int) -> int:
        """
        获取当前行的玻片状态是否正确
        :param chamber_number:
        :param row_number:
        :return:
        """
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong: int = RECODE_FAILURE
        ChamberNumber   : int
        RowNumber       : int
        item            : cls
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber, cls.ChamberRowNumber == RowNumber).first()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return item is not None and not item.IsCheckError() and item.IsCheck()

    @classmethod
    def IsCheckEmpty(cls, chamber_number: int, row_number: int) -> int:
        """
        获取当前行的玻片状态是否正确
        :param chamber_number:
        :param row_number:
        :return:
        """
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong: int = RECODE_FAILURE
        ChamberNumber: int
        RowNumber: int
        item: cls
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber, cls.ChamberRowNumber == RowNumber).first()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return item is not None and item.isPlace()

    @classmethod
    def IsPlaceAvailable(cls, chamber_number: int, row_number: int) -> int:
        """
        获取当前行的玻片状态是否正确
        :param chamber_number:
        :param row_number:
        :return:
        """
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong: int = RECODE_FAILURE
        ChamberNumber: int
        RowNumber: int
        item: cls
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber, cls.ChamberRowNumber == RowNumber).first()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return item is not None and item.isPlace()

    @classmethod
    def IsPlace(cls, chamber_number: int, row_number: int) -> int:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong         : int = RECODE_FAILURE
        MinChamberNumber: int
        MaxChamberNumber: int
        MinRowNumber    : int
        MaxRowNumber    : int
        MinRowNumber    , MaxRowNumber       = SystemConfig.getRowRange      ()
        MinChamberNumber, MaxChamberNumber   = SystemConfig.getChamberRange  ()
        if MinChamberNumber <= chamber_number <= MaxChamberNumber:
            isWrong = RECODE_SUCCEED if cls.IsCheckEmpty(chamber_number, row_number) else RECODE_FAILURE
        return isWrong

    @classmethod
    def IsPlaceAvailable(cls, chamber_number: int, row_number: int) -> int:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong: int = RECODE_FAILURE
        MinChamberNumber: int
        MaxChamberNumber: int
        MinRowNumber: int
        MaxRowNumber: int
        MinRowNumber, MaxRowNumber = SystemConfig.getRowRange()
        MinChamberNumber, MaxChamberNumber = SystemConfig.getChamberRange()
        if MinChamberNumber <= chamber_number <= MaxChamberNumber:
            isWrong = RECODE_SUCCEED if cls.IsCheckEmpty(chamber_number, row_number) else RECODE_FAILURE
        return isWrong

    @classmethod
    def IsPickAvailable(cls, chamber_number: int, row_number: int) -> int:
        """
        获取当前行的玻片是否可以取
        :param chamber_number:
        :param row_number:
        :return:
        """
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong         : int = RECODE_FAILURE
        MinChamberNumber: int
        MaxChamberNumber: int
        MinRowNumber    : int
        MaxRowNumber    : int
        MinRowNumber    , MaxRowNumber       = SystemConfig.getRowRange      ()
        MinChamberNumber, MaxChamberNumber   = SystemConfig.getChamberRange  ()
        if MinChamberNumber <= chamber_number <= MaxChamberNumber:
            RowNumber      : int = min(MaxRowNumber, max(MinRowNumber, row_number   ))
            if cls.IsCheckAvailable(chamber_number, RowNumber):
                return RECODE_SUCCEED

        return isWrong

    @classmethod
    def count(cls) -> int:
        count: int = 0
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                count = session.query(func.count(cls.ID)).scalar()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return count

    @classmethod
    def getChamberStatus(cls, chamber_number: int, row_number: int) -> (int, int):
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong = 0
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        item: cls
        l_status: int = 0
        r_status: int = 0
        code: str = ''
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber,
                                                 cls.ChamberRowNumber == RowNumber).first()
                if item is not None:
                    l_status = item.LState
                    r_status = item.RState
                    code = item.CodeString
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return l_status, r_status

    @classmethod
    def getChamberCodeString(cls, chamber_number: int, row_number: int) -> str:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        isWrong = 0
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        item: cls
        l_status: int = 0
        r_status: int = 0
        code: str = ''
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ChamberGroupNumber == ChamberNumber,
                                                 cls.ChamberRowNumber == RowNumber).first()
                if item is not None:
                    l_status = item.LState
                    r_status = item.RState
                    code = item.CodeString
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return code

    def toImage(self, w: int = -1, h: int = -1) -> np.ndarray:
        return None if not self.hasCamera else self.camera.toImage(w, h)


    def toQImage(self, w: int = -1, h: int = -1) -> Qt.QImage:
        return None if not self.hasCamera else self.camera.toQImage(w, h)


    def toBase64(self, w: int = -1, h: int = -1) -> Qt.QImage:
        return None if not self.hasCamera else self.camera.toBase64(w, h)


    @property
    def slidetable          (self) -> TrayModel                        :
        return None if not self.has_SlideTable          else self.SlideTable

    @property
    def objective           (self) -> ObjectiveModel                   :
        return None if not self.has_Objective           else self.Objective

    @property
    def focusing            (self) -> FocusingConfigModel              :
        return None if not self.has_Focusing            else self.Focusing

    @property
    def scantemplate        (self) -> ScanTemplate                     :
        return None if not self.has_ScanTemplate        else self.ScanTemplate

    @property
    def preview             (self) -> Previewsettings                  :
        return None if not self.has_Preview             else self.Preview

    @property
    def collect             (self) -> Collectsettings                  :
        return None if not self.has_Collect             else self.Collect

    @property
    def previewClassifier   (self) -> PreviewClassifierModel           :
        return None if not self.has_PreviewClassifier   else self.PreviewClassifier

    @property
    def preferredClassifier (self) -> PreferredClassifierModel         :
        return None if not self.has_PreferredClassifier else self.PreferredClassifier

    @property
    def collectClassifier   (self) -> CollectClassifierModel           :
        return None if not self.has_CollectClassifier   else self.CollectClassifier

    @property
    def index(self) -> int:
        return 0 if not self.has_Index else self.Index

    @property
    def camera              (self) -> CameraRequest                    :
        return None if not self.has_Camera              else self.Camera


    @property
    def hasImageScore(self) -> bool:
        return self.hasCamera and self.camera.hasImageSource

    def setImageSource(self, image: np.ndarray):
        if not self.hasCamera:
            self.initCamera()
        self.camera.ImageSource = image


    @property
    def hasImageSource(self) -> bool:
        return self.hasCamera and self.camera.hasImageSource

    @property
    def hasPosition(self) -> bool:
        return self.has_Position_X and self.has_Position_Y and self.has_Position_Z

    @property
    def hasCamera(self) -> bool:
        return hasattr(self, 'Camera') and isinstance(self.Camera, CameraRequest)

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

    @property
    def isMicronucleus(self) -> bool:
        return self.has_ObjectiveLevel and ObjectiveLevel.isMicronucleus(self.ObjectiveLevel)

    @property
    def isMono(self) -> bool:
        return not self.has_ObjectiveLevel or  not ObjectiveLevel.isMicronucleus(self.ObjectiveLevel)









    @property
    def hasSlideTable             (self) -> bool:
        return hasattr(self, 'SlideTable'            ) and isinstance(self.SlideTable             , TrayModel               )

    @property
    def hasObjective              (self) -> bool:
        return hasattr(self, 'Objective'             ) and isinstance(self.Objective              , ObjectiveModel          )

    @property
    def hasFocusing               (self) -> bool:
        return hasattr(self, 'Focusing'              ) and isinstance(self.Focusing               , FocusingConfigModel     )

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

    @property
    def hasPreview                (self) -> bool:
        return hasattr(self, 'Preview'               ) and isinstance(self.Preview                , Previewsettings         )

    @property
    def hasCollect                (self) -> bool:
        return hasattr(self, 'Collect'               ) and isinstance(self.Collect                , Collectsettings         )

    @property
    def hasPreviewClassifier      (self) -> bool:
        return hasattr(self, 'PreviewClassifier'     ) and isinstance(self.PreviewClassifier      , PreviewClassifierModel  )

    @property
    def hasPreferredClassifier    (self) -> bool:
        return hasattr(self, 'PreferredClassifier'   ) and isinstance(self.PreferredClassifier    , PreferredClassifierModel)

    @property
    def hasCollectClassifier      (self) -> bool:
        return hasattr(self, 'CollectClassifier'     ) and isinstance(self.CollectClassifier      , CollectClassifierModel  )

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    @property
    def hasIndex(self) -> bool:
        return hasattr(self, 'Index') and isinstance(self.Index, (float, int))

    @property
    def has_Position_X           (self) -> bool:
        return hasattr(self, 'Position_X'          ) and isinstance(self.Position_X          , (float, int)            )

    @property
    def has_Position_Y           (self) -> bool:
        return hasattr(self, 'Position_Y'          ) and isinstance(self.Position_Y          , (float, int)            )

    @property
    def has_Position_Z           (self) -> bool:
        return hasattr(self, 'Position_Z'          ) and isinstance(self.Position_Z          , (float, int)            )

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

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

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

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

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

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

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

    @property
    def has_CreateTime           (self) -> bool:
        return hasattr(self, 'CreateTime'          ) and isinstance(self.CreateTime          , datetime                )

    @property
    def has_SlideTable           (self) -> bool:
        return hasattr(self, 'SlideTable'          ) and isinstance(self.SlideTable          , TrayModel               )

    @property
    def has_Objective            (self) -> bool:
        return hasattr(self, 'Objective'           ) and isinstance(self.Objective           , ObjectiveModel          )

    @property
    def has_Focusing             (self) -> bool:
        return hasattr(self, 'Focusing'            ) and isinstance(self.Focusing            , FocusingConfigModel     )

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

    @property
    def has_Preview              (self) -> bool:
        return hasattr(self, 'Preview'             ) and isinstance(self.Preview             , Previewsettings         )

    @property
    def has_Collect              (self) -> bool:
        return hasattr(self, 'Collect'             ) and isinstance(self.Collect             , Collectsettings         )

    @property
    def has_PreviewClassifier    (self) -> bool:
        return hasattr(self, 'PreviewClassifier'   ) and isinstance(self.PreviewClassifier   , PreviewClassifierModel  )

    @property
    def has_PreferredClassifier  (self) -> bool:
        return hasattr(self, 'PreferredClassifier' ) and isinstance(self.PreferredClassifier , PreferredClassifierModel)

    @property
    def has_CollectClassifier    (self) -> bool:
        return hasattr(self, 'CollectClassifier'   ) and isinstance(self.CollectClassifier   , CollectClassifierModel  )

    @property
    def has_Camera               (self) -> bool:
        return hasattr(self, 'Camera'              ) and isinstance(self.Camera              , CameraRequest           )






































































    def initCamera(self):
        buffer: dict[str, object] = {
            'ResultNumber'   : RECODE_FAILURE       ,
            'ID'             : self.ID              ,
            'ImageSource'    : None                 ,
            'ImageJson'      : None                 ,
            'StartTime'      : datetime.now()       ,
            'FinishTime'     : None                 ,
        }
        if not self.hasCamera:
            self.Camera = CameraRequest(**buffer)
        else:
            self.Camera.deserialize(buffer)

    def initScanTemplate(self):
        if not self.hasScanTemplate:
            self.ScanTemplate = self.get(and_(ScanTemplate.is_default== 1, ScanTemplate.ID==1))


    def serialize(self) -> dict[str, object]:
        buffer: dict[str, object] = super(SlideModelInterface, self).serialize()
        buffer['Index'                      ] = self.index                 #
        buffer['SlideTable'                 ] = self.slidetable             .serialize() if self.has_SlideTable             else {}#
        buffer['Objective'                  ] = self.objective              .serialize() if self.has_Objective              else {}#
        buffer['Focusing'                   ] = self.focusing               .serialize() if self.has_Focusing               else {}#
        buffer['ScanTemplate'               ] = self.scantemplate           .serialize() if self.has_ScanTemplate           else {}#
        buffer['Preview'                    ] = self.preview                .serialize() if self.has_Preview                else {}#
        buffer['Collect'                    ] = self.collect                .serialize() if self.has_Collect                else {}#
        buffer['PreviewClassifier'          ] = self.previewClassifier      .serialize() if self.has_PreviewClassifier      else {}#
        buffer['PreferredClassifier'        ] = self.preferredClassifier    .serialize() if self.has_PreferredClassifier    else {}#
        buffer['CollectClassifier'          ] = self.collectClassifier      .serialize() if self.has_CollectClassifier      else {}#
        buffer['Camera'                     ] = self.camera                 .serialize() if self.has_Camera                 else {}

        return buffer

    def deserialize(self, buffer: dict[str, object]):
        super(SlideModelInterface, self).deserialize(buffer)
        self.initCamera()
        self.Index                  = AppConvert.ObjectConvert(            buffer.get('Index'               , None), int)
        self.SlideTable             = TrayModel                .instance(**buffer.get('SlideTable'          , None))
        self.Objective              = ObjectiveModel           .instance(**buffer.get('Objective'           , None))
        self.Focusing               = FocusingConfigModel      .instance(**buffer.get('Focusing'            , None))
        self.ScanTemplate           = ScanTemplate             .instance(**buffer.get('ScanTemplate'        , None))
        self.Preview                = Previewsettings          .instance(**buffer.get('Preview'             , None))
        self.Collect                = Collectsettings          .instance(**buffer.get('Collect'             , None))
        self.PreviewClassifier      = PreviewClassifierModel   .instance(**buffer.get('PreviewClassifier'   , None))
        self.PreferredClassifier    = PreferredClassifierModel .instance(**buffer.get('PreferredClassifier' , None))
        self.CollectClassifier      = CollectClassifierModel   .instance(**buffer.get('CollectClassifier'   , None))
        self.Camera                 = CameraRequest            .instance(**buffer.get('Camera'              , None))

    @property
    def traynumber(self) -> int:
        return self.TrayNumber if self.TrayNumber in ModuleLevel.trays() else ModuleLevel.ModuleTraySlide1

    @property
    def slidetableNumber(self) -> int:
        return self.TrayNumber if self.TrayNumber in ModuleLevel.trays() else ModuleLevel.ModuleTraySlide1

    def leftCheck(self):
        return 1 if self.has_LState and self.LState == 1 else 0

    def rightCheck(self):
        return 1 if self.has_RState and self.RState == 1 else 0

    def IsCheck(self) -> bool:
        return self.leftCheck() and self.rightCheck()

    def isPlace(self) -> bool:
        return (self.has_LState and self.has_RState and self.LState == 0 and self.RState == 0) or (not self.has_LState and not self.has_RState)

    def IsCheckError(self) -> bool:
        try:
            return self.LState != self.RState
        except Exception as e:
            return True

    def IsMoveValid(self) -> bool:
        return self.hasPosition

    def SetLCheck(self, value: (int, bool)):
        if isinstance(value, int):
            self.LState = abs(value) % 2
        elif isinstance(value, bool):
            self.LState = 1 if isinstance(value, bool) and value else 0
        else:
            self.LState = 0


    def SetRCheck(self, value: (int, bool)):
        if isinstance(value, int):
            self.RState = abs(value) % 2
        elif isinstance(value, bool):
            self.RState = 1 if isinstance(value, bool) and value else 0
        else:
            self.RState = 0

    def isEmpty(self) -> bool:
        return self.has_CodeString and len(self.CodeString) <= 0





    @classmethod
    def getChamberCount(cls) -> int:
        slide_count: int = 0
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                slide_count = session.query(func.count(cls.ID)).filter(cls.LState == 1, cls.RState == 1).scalar()
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return slide_count

    @classmethod
    def getChamberGroupCount(cls, ChamberNumber: int) -> int:
        slide_count: int = 0
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                slide_count = session.query(func.count(cls.ID)).filter(cls.LState == 1, cls.RState == 1, cls.ChamberGroupNumber==ChamberNumber).scalar()
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return slide_count


    @classmethod
    def getTraySlideItem(cls, level: int):
        item: cls = None
        _level: int = TrayLevel.getTrayNumber(level)
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ID == _level).first()
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return item

    @classmethod
    def getTempTraySlideItem(cls) -> 'SlideModelInterface':
        item: cls = None
        _level: int = ModuleLevel.ModuleTraySlide3
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ID == ModuleLevel.ModuleTraySlide3).first()
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return item

    @classmethod
    def getPickTraySlideItem(cls) -> 'SlideModelInterface':
        item: cls = None
        _level: int = 4
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ID == 4).first()
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return item

    @classmethod
    def getDropTraySlideItem(cls) -> 'SlideModelInterface':
        item: cls = None
        _level: int = 5
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(cls.ID == 5).first()
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return item

    @classmethod
    def setTraySlideItem(cls, level: int, **args):
        item: cls = None
        _level: int = TrayLevel.getTrayNumber(level)
        model: cls = cls.instance(**args)
        buffer: dict[str, object] = model.to_field(False)
        if model.has_ID:
            buffer.pop('ID')
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ID == _level).update(buffer)
                session.commit()
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return

    @classmethod
    def setSlideTableData(cls, level: int, data: dict[str, object]):
        item: cls = None
        _level: int = TrayLevel.getTrayNumber(level)
        model: cls = cls.instance()
        model.as_field(data, False)
        model.TrayNumber = _level
        buffer: dict[str, object] = model.to_field(False)
        if model.has_ID:
            buffer.pop('ID')
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ID == _level).update(buffer)
                session.commit()
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return

    @classmethod
    def setTempSlideTableData(cls, data: dict[str, object]):
        item: cls = None
        _level: int = ModuleLevel.ModuleTraySlide3
        model: cls = cls.instance()
        model.as_field(data, False)
        model.TrayNumber = _level
        buffer: dict[str, object] = model.to_field(False)
        if model.has_ID:
            buffer.pop('ID')
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ID == _level).update(buffer)
                session.commit()
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return

    @classmethod
    def setPickSlideTableData(cls, data: dict[str, object]):
        item: cls = None
        _level: int = 4
        model: cls = cls.instance()
        model.as_field(data, False)
        model.TrayNumber = _level
        buffer: dict[str, object] = model.to_field(False)
        if model.has_ID:
            buffer.pop('ID')
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ID == _level).update(buffer)
                session.commit()
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return

    @classmethod
    def setDropSlideTableData(cls, data: dict[str, object]):
        item: cls = None
        _level: int = 5
        model: cls = cls.instance()
        model.as_field(data, False)
        model.TrayNumber = _level
        buffer: dict[str, object] = model.to_field(False)
        if model.has_ID:
            buffer.pop('ID')
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                session.query(cls).filter(cls.ID == _level).update(buffer)
                session.commit()
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return
    @classmethod
    def getItems(cls, TrayNumber: int, points: list[list[int]], objective: int) -> list:
        from AppLog.logHelper import logDB
        ChamberNumber   : int
        RowNumber       : int
        Point           : list[int]
        item            : cls
        items           : list[cls] = []
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        tray: TrayModel = TrayModel.getTrayModel(TrayNumber)
        if tray is None:
            return items
        try:
            for index, Point in enumerate(points):
                item = cls.instance(ID=index + 1, TrayNumber=TrayNumber)
                item.RowNumber      = Point[0]
                item.ColNumber      = Point[1]
                item.ObjectiveLevel = objective
                cls.setModelPosition(tray, item)
                items.append(item)
        except Exception as e:
            logDB << AppUtils.toString(e)
        return items

    @classmethod
    def getTrayItems(cls, tray_model: 'TrayModel', points: list[list[int]], objective: int = 2) -> list:
        from AppLog.logHelper import logDB
        ChamberNumber: int
        RowNumber: int
        Point: list[int]
        item: cls
        items: list[cls] = []
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        if not isinstance(tray_model, TrayModel):
            return items
        item: cls
        try:
            TrayNumber  : int = tray_model.Level        #
            MaxRowNumber: int = tray_model.MaxRowNumber * 2 if objective == ObjectiveLevel.Objective20 else tray_model.MaxRowNumber
            MaxColNumber: int = tray_model.MaxColNumber * 2 if objective == ObjectiveLevel.Objective20 else tray_model.MaxColNumber
            MinRowNumber: int = tray_model.MinRowNumber
            MinColNumber: int = tray_model.MinColNumber
            for index, Point in enumerate(points):
                item = cls.instance(ID=index + 1, TrayNumber=TrayNumber)
                item.RowNumber = min(max(MinRowNumber, Point[0]), MaxRowNumber)
                item.ColNumber = min(max(MinColNumber, Point[1]), MaxColNumber)
                item.ObjectiveLevel = objective
                # cls.setModelPosition(tray1, item, 1, 1, ObjectiveLevel.ObjectiveNone, '')
                items.append(item)
        except Exception as e:
            logDB << AppUtils.toString(e)
        return items

    @classmethod
    def getCellItems(cls, isBeginRow: bool = True) -> list:
        from AppLog.logHelper import logDB
        ChamberNumber: int
        RowNumber: int
        Point: list[int]
        item: cls
        models: list[cls] = []
        _filter: list = []
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                row_models: list[cls] = session.query(cls).order_by(cls.ImageCellScore.desc()).all()
                models.extend(row_models)
                session.close()
        except Exception as e:
            logDB << AppUtils.toString(e)
        return models
    @classmethod
    def getFocusingItems(cls, tray_model: DBInterface, points: list[list[int]], chamber_number: int = 1, row_number: int = 1, objective: int = 2, is_save: int = 0) -> list:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig, SystemConfig
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        models: list[cls] = []
        if not isinstance(tray_model, TrayModel):
            return []

        ChamberNumber   : int
        RowNumber       : int
        TrayNumber      : int   = tray_model.Level
        MaxRowNumber: int = tray_model.MaxRowNumber
        MaxColNumber: int = tray_model.MaxColNumber
        if ObjectiveLevel.isMicronucleus(objective):
            MaxRowNumber = tray_model.MaxRowNumber20X
            MaxColNumber = tray_model.MaxColNumber20X
        MinRowNumber    : int = tray_model.MinRowNumber
        MinColNumber    : int = tray_model.MinColNumber
        ChamberNumber   , RowNumber     = SystemConfig.getChamberNumbers(chamber_number, row_number)
        items: list[cls] = cls.getItems(TrayNumber, points, objective)
        model: cls
        for index, item in enumerate(items):
            model = item.copy()
            model.setTrayLocation(ChamberNumber, RowNumber, TrayNumber, min(max(item.RowNumber, MinRowNumber), MaxRowNumber), min(max(item.ColNumber, MinColNumber), MaxColNumber))
            model.ObjectiveLevel    = objective
            cls.setModelPosition(tray_model, model, True)
            model.IsSave            = is_save
            model.Level             = ScanStatusLevel.Low_First_Focus_Status
            models.append(model)
        return models

    @classmethod
    def getScanningItems(cls, tray_model: DBInterface, points: list[list[int]], chamber_number: int = 1, row_number: int = 1, objective: int = 2, is_save: int = 0) -> list:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        models: list[cls] = []
        if not isinstance(tray_model, TrayModel):
            return []
        ChamberNumber   : int
        RowNumber       : int
        MaxRowNumber    : int = tray_model.MaxRowNumber
        MaxColNumber    : int = tray_model.MaxColNumber
        if ObjectiveLevel.isMicronucleus(objective):
            MaxRowNumber = tray_model.MaxRowNumber20X
            MaxColNumber = tray_model.MaxColNumber20X
        MinRowNumber    : int = tray_model.MinRowNumber
        MinColNumber    : int = tray_model.MinColNumber
        TrayNumber      : int   = tray_model.Level
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        items: list[cls] = cls.getTrayItems(tray_model, points, objective)
        model: cls
        for item in items:
            model = item.copy()
            model.setTrayLocation(ChamberNumber, RowNumber, TrayNumber, min(max(item.RowNumber, MinRowNumber), MaxRowNumber), min(max(item.ColNumber, MinColNumber), MaxColNumber))
            model.ObjectiveLevel    = objective
            cls.setModelPosition    (tray_model, model, objective == ObjectiveLevel.Objective20)
            model.IsSave            = is_save
            model.Level             = ScanStatusLevel.LowScanning_Status
            models.append(model)
        return models

    @classmethod
    def getOilDropingItems(cls, tray_model: DBInterface, points: list[list[int]], OffsetRowNumber: int, OffsetColNumber: int, chamber_number: int = 1, row_number: int = 1, objective: int = 2, is_save: int = 0) -> list:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        models: list[cls] = []
        if not isinstance(tray_model, TrayModel):
            return []
        ChamberNumber               : int
        RowNumber                   : int
        TrayNumber                  : int   = tray_model.Level
        ChamberNumber, RowNumber            = SystemConfig.getChamberNumbers(chamber_number, row_number)
        items: list[cls] = cls.getItems(TrayNumber, points, objective)
        model: cls
        for index, item in enumerate(items):
            model = item.copy()
            model.setTrayLocation(ChamberNumber, RowNumber, TrayNumber,
                                  item.RowNumber + OffsetRowNumber    ,
                                  item.ColNumber + OffsetColNumber    )

            cls.setModelPosition(tray_model, model)
            model.ObjectiveLevel = objective
            model.IsSave = is_save
            models.append(model)
        return models

    @classmethod
    def getSourceOilDropingItems(cls, tray_model: DBInterface, points: list[list[int]],  chamber_number: int = 1, row_number: int = 1, objective: int = 2, is_save: int = 0) -> list:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        models: list[cls] = []
        if not isinstance(tray_model, TrayModel):
            return []
        ChamberNumber: int
        RowNumber: int
        TrayNumber: int = tray_model.Level
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        MaxColNumber: int = tray_model.MaxColNumber
        MaxRowNumber: int = tray_model.MaxRowNumber
        MinColNumber: int = tray_model.MinColNumber
        MinRowNumber: int = tray_model.MinRowNumber
        items: list[cls] = cls.getItems(TrayNumber, points, objective)
        model: cls
        for index, item in enumerate(items):
            model = item.copy()
            model.setTrayLocation(ChamberNumber, RowNumber, TrayNumber  ,
                                  item.RowNumber ,
                                  item.ColNumber
            )
            cls.setModelPosition(tray_model, model)
            model.ObjectiveLevel = objective
            model.IsSave = is_save
            models.append(model)
        return models

    @classmethod
    def getSourceOilDropingPoint(cls, tray_model: DBInterface, points: list[int],  chamber_number: int = 1, row_number: int = 1, objective: int = 2, OffsetRowNumber: int = 0, OffsetColNumber: int = 0, is_save: int = 0) -> list:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        models: list[cls] = []
        if not isinstance(tray_model, TrayModel):
            return []
        ChamberNumber   : int
        RowNumber       : int
        TrayNumber  : int = tray_model.Level
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        items: list[cls] = cls.getItems(TrayNumber, [points], objective)
        model: cls
        for index, item in enumerate(items):
            model = item.copy()
            model.setTrayLocation(ChamberNumber, RowNumber, TrayNumber,
                                  item.RowNumber + OffsetRowNumber,
                                  item.ColNumber + OffsetColNumber)
            cls.setModelPosition(tray_model, model)
            model.ObjectiveLevel = objective
            model.IsSave = is_save
            models.append(model)
        return models

    @classmethod
    def getAnointingItems(cls, tray_model: DBInterface, points: list[list[int]], chamber_number: int = 1, row_number: int = 1, objective: int = 2,  is_save: int = 0) -> list:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        models: list[cls] = []
        if not isinstance(tray_model, TrayModel):
            return []
        ChamberNumber: int
        RowNumber: int
        TrayNumber: int = tray_model.Level
        MaxColNumber: int = tray_model.MaxColNumber
        MaxRowNumber: int = tray_model.MaxRowNumber
        MinColNumber: int = tray_model.MinColNumber
        MinRowNumber: int = tray_model.MinRowNumber

        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        items: list[cls] = cls.getItems(TrayNumber, points)
        model: cls

        for index, item in enumerate(items):
            model = item.copy()
            model.setTrayLocation(ChamberNumber, RowNumber, TrayNumber, min(max(item.RowNumber, MinRowNumber), MaxRowNumber), min(max(item.ColNumber, MinColNumber), MaxColNumber))
            cls.setModelPosition(tray_model, model)
            model.ObjectiveLevel = objective
            model.IsSave = is_save
            models.append(model)
        return models


    @classmethod
    def getCellFocusingItems(cls, tray_model: DBInterface, chamber_number: int = 1, row_number: int = 1, objective: int = 2, is_save: int = 0) -> list:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig, SystemConfig
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        models: list[cls] = []
        if not isinstance(tray_model, TrayModel):
            return []
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        items: list[cls] = cls.getCellItems()
        model: cls
        TrayNumber  : int = tray_model.Level
        MaxColNumber: int = tray_model.MaxColNumber
        MaxRowNumber: int = tray_model.MaxRowNumber
        MinColNumber: int = tray_model.MinColNumber
        MinRowNumber: int = tray_model.MinRowNumber
        for index, item in enumerate(items):
            model = item.copy()
            model.setTrayLocation(ChamberNumber, RowNumber, TrayNumber, min(max(item.RowNumber , MinRowNumber), MaxRowNumber), min(max(item.ColNumber , MinColNumber), MaxColNumber))
            cls.setCellPoint(tray_model, model)
            model.setSlideParameter(objective, ChamberNumber, RowNumber, is_save, index + 1, 0, 0)
            models.append(model)
        return models

    @classmethod
    def getCellFocusingItems(cls, tray_model: DBInterface, chamber_number: int = 1, row_number: int = 1,
                             objective: int = 2, is_save: int = 0) -> list:
        from AppSettings.SystemSetting import SystemSetting, SystemConfig, SystemConfig
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        models: list[cls] = []
        if not isinstance(tray_model, TrayModel):
            return []
        ChamberNumber: int
        RowNumber: int
        ChamberNumber, RowNumber = SystemConfig.getChamberNumbers(chamber_number, row_number)
        items: list[cls] = cls.getCellItems()
        model: cls
        TrayNumber  : int = tray_model.Level
        MaxColNumber: int = tray_model.MaxColNumber
        MaxRowNumber: int = tray_model.MaxRowNumber
        MinColNumber: int = tray_model.MinColNumber
        MinRowNumber: int = tray_model.MinRowNumber
        for index, item in enumerate(items):
            model = item.copy()
            model.setTrayLocation(ChamberNumber, RowNumber, TrayNumber,
                                  min(max(item.RowNumber, MinRowNumber), MaxRowNumber),
                                  min(max(item.ColNumber, MinColNumber), MaxColNumber))
            cls.setCellPoint(tray_model, model)
            model.setSlideParameter(objective, ChamberNumber, RowNumber, is_save, index + 1, 0, 0)
            models.append(model)
        return models


    @classmethod
    def setModelPosition(cls, tray_model: 'TrayModel', model: 'SlideModelInterface', isLowFocusing: bool = False):
        if model is None:
            return
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        if not isinstance(tray_model, TrayModel):
            return
        TrayNumber      : int   = tray_model.Level
        Position_X      : float = tray_model.Position_X
        Position_Y      : float = tray_model.Position_Y
        StepX           : float = abs(tray_model.Step_X)
        StepY           : float = abs(tray_model.Step_Y)
        if isLowFocusing:
            if model.ObjectiveLevel == ObjectiveLevel.Objective20:
                StepX = abs(tray_model.Step_X_20X)
                StepY = abs(tray_model.Step_Y_20X)
        RowNumber       : int = model.RowNumber
        ColNumber       : int = model.ColNumber
        x: float
        y: float
        from AppSettings.AppStatusSetting import AppStatus
        x, y = AppStatus.get_slide_tray_position_xy(RowNumber, ColNumber, Position_X, Position_Y, StepX, StepY)
        model.setPosition(x, y)
        model.setTrayLocation(TrayNumber, RowNumber, ColNumber)
        return

    @classmethod
    def setSlidePosition(cls, tray_number: int, model: 'SlideModelInterface'):
        if model is None:
            return
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        tray_model: TrayModel = TrayModel.getTrayConfig(tray_number)
        if not isinstance(tray_model, TrayModel):
            return
        TrayNumber      : int   = tray_model.Level
        Position_X      : float = tray_model.Position_X
        Position_Y      : float = tray_model.Position_Y
        StepX           : float = abs(tray_model.Step_X)
        StepY           : float = abs(tray_model.Step_Y)
        if model.ObjectiveLevel == ObjectiveLevel.Objective20:
            StepX = abs(tray_model.Step_X_20X)
            StepY = abs(tray_model.Step_Y_20X)
        RowNumber       : int = model.RowNumber
        ColNumber       : int = model.ColNumber
        x: float
        y: float
        from AppSettings.AppStatusSetting import AppStatusSetting, AppStatus
        x, y = AppStatus.get_slide_tray_position_xy(RowNumber, ColNumber, Position_X, Position_Y, abs(StepX), abs(StepY))
        model.setPosition(x, y)
        # MinPositionX: float = tray_model.Position_X - (tray_model.MaxRowNumber * abs(StepX))
        # MinPositionY: float = tray_model.Position_Y
        # MaxPositionX: float = tray_model.Position_X
        # MaxPositionY: float = tray_model.Position_Y + (tray_model.MaxColNumber * abs(StepY))
        # model.Position_X = min(max(MinPositionX, model.Position_X), MaxPositionX)
        # model.Position_Y = min(max(MinPositionY, model.Position_Y), MaxPositionY)
        model.setTrayLocation(TrayNumber, RowNumber, ColNumber)
        return


    @classmethod
    def setCellPoint(cls, tray_model: 'TrayModel', model: 'SlideModelInterface'):
        if model is None:
            return
        from AppSettings.SystemSetting import SystemSetting, SystemConfig
        from AppSettings.AppStatusSetting import AppStatusSetting, AppStatus
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        from AppCore.AppAlgorithms.SlidePointUtils import SlidePointUtils
        from AppCore.AppDBModels.ConfigModels.ObjectiveOffsetModel import ObjectiveOffsetModel
        from AppCore.AppDBModels.CameraModels.CameraInterface  import CameraInterface  #
        camera          : CameraInterface = AppStatus.getCameraModel(ObjectiveLevel.Objective10)
        if not isinstance(tray_model, TrayModel) or not isinstance(camera, CameraInterface):
            return
        TrayNumber      : int   = tray_model.Level
        Position_X      : float = tray_model.Position_X
        Position_Y      : float = tray_model.Position_Y
        StepX           : float = tray_model.Step_X
        StepY           : float = tray_model.Step_Y
        Axis_Offset_X   : float = camera.Axis_Offset_X
        Axis_Offset_Y   : float = camera.Axis_Offset_Y
        Image_Offset_W  : float = camera.Image_Offset_W
        Image_Offset_H  : float = camera.Image_Offset_H
        RowNumber       : int = model.RowNumber
        ColNumber       : int = model.ColNumber
        # Offset: ObjectiveOffsetModel = ObjectiveOffsetModel.getConfig(model.ObjectiveLevel)
        # Axis_Offset_X = Offset.OffsetX
        # Axis_Offset_Y = Offset.OffsetY
        x: float
        y: float
        x, y = AppStatus.get_slide_tray_position_xy(RowNumber, ColNumber, Position_X, Position_Y, StepX, StepY)
        move_w, move_h = SlidePointUtils.detect_point_transforms(model.ImageCellX       , model.ImageCellY      ,
                                                                 tray_model.Image_W     , tray_model.Image_H    ,
                                                                 abs(StepX)             , abs(StepY)            ,
                                                                 Axis_Offset_X          , Axis_Offset_Y         ,
                                                                 Image_Offset_W         , Image_Offset_H        )

        model.setPosition(x - move_w, y - move_h)
        # MinPositionX: float = tray_model.Position_X - (tray_model.MaxRowNumber * abs(StepX))
        # MinPositionY: float = tray_model.Position_Y
        # MaxPositionX: float = tray_model.Position_X
        # MaxPositionY: float = tray_model.Position_Y + (tray_model.MaxColNumber * abs(StepY))
        # model.Position_X = min(max(MinPositionX, model.Position_X), MaxPositionX)
        # model.Position_Y = min(max(MinPositionY, model.Position_Y), MaxPositionY)
        model.TrayNumber = TrayNumber
        model.RowNumber  = RowNumber
        model.ColNumber  = ColNumber
        return

    @classmethod
    def set100XCellPoint(cls, tray_model: 'TrayModel', model: 'SlideModelInterface'):
        if model is None:
            return
        from AppSettings.SystemSetting import SystemConfig, SystemSetting
        from AppSettings.AppStatusSetting import AppStatusSetting, AppStatus
        from AppCore.AppDBModels.TrayModels.TrayModel import TrayModel
        from AppCore.AppAlgorithms.SlidePointUtils import SlidePointUtils
        from AppCore.AppDBModels.CameraModels.CameraModel import CameraModel, CameraInterface  #
        camera: CameraInterface = CameraModel.getConfig(ObjectiveLevel.Objective100)
        if not isinstance(tray_model, TrayModel) or not isinstance(camera, CameraInterface):
            return
        TrayNumber      : int   = tray_model.Level
        x               : float = round(float(Decimal(f'{model.Position_X}')), 4)
        y               : float = round(float(Decimal(f'{model.Position_Y}')), 4)
        Axis_Offset_X   : float = camera.Axis_Offset_X
        Axis_Offset_Y   : float = camera.Axis_Offset_Y
        Image_Offset_W  : float = camera.Image_Offset_W
        Image_Offset_H  : float = camera.Image_Offset_H
        move_w, move_h = SlidePointUtils.detect_point_transforms_100X(model.ImageCellX       , model.ImageCellY      ,
                                                                      tray_model.Image_W     , tray_model.Image_H    ,
                                                                      Axis_Offset_X          , Axis_Offset_Y         ,
                                                                      Image_Offset_W         , Image_Offset_H         )
        model.setPosition(x - move_w, y - move_h)
        model.TrayNumber = TrayNumber
        return



