#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：ObjectiveOffsetModel.py
@Description：
@Author：XSH
@Time：2025/12/20 15:24
@Department：研发部
@Copyright：©2025 乐辰生物
"""
from PyQt5 import Qt
from datetime import datetime, date
import copy
from AppSettings.Settings import *
from AppCore.AppDBModels.CoreModel import (CoreModel, DBManager, dbController)
from sqlalchemy.orm import declarative_base, mapper, sessionmaker, Session
from sqlalchemy.orm import (declarative_base, Mapped, mapped_column, relationship, mapper, sessionmaker)
from sqlalchemy import Table, Engine, create_engine, Column, ForeignKey, and_, or_, insert, delete, update, select, func, ColumnElement,distinct
from sqlalchemy.types import (Text, VARCHAR, REAL, Float, Integer, String, SmallInteger, DateTime, Date, ARRAY,Boolean, JSON)
from sqlalchemy.orm.decl_api import DeclarativeBase, MetaData
from AppUtils.utils import *
from AppCore.Levels import *

class ObjectiveOffsetModel(CoreModel):
    __tablename__ = 't_ObjectiveOffsetModel'
    Information                     : Mapped[str    ] = mapped_column(Text, default=''      , nullable=True , doc='　说明信息　　', comment='　说明信息　　')
    Level                           : Mapped[int    ] = mapped_column(primary_key=True      , nullable=False, doc='　物镜类型　　', comment='　物镜类型　　')
    XPosition                       : Mapped[float  ] = mapped_column(default=0             , nullable=True , doc='校准点Ｘ轴位置', comment='校准点Ｘ轴位置')
    YPosition                       : Mapped[float  ] = mapped_column(default=0             , nullable=True , doc='校准点Ｙ轴位置', comment='校准点Ｙ轴位置')
    ZPosition                       : Mapped[float  ] = mapped_column(default=0             , nullable=True , doc='校准点Ｚ轴位置', comment='校准点Ｚ轴位置')
    ExposureTime                    : Mapped[float  ] = mapped_column(default=0             , nullable=True , doc='　曝光时间　　', comment='　曝光时间　　')
    OffsetX                         : Mapped[float  ] = mapped_column(default=0             , nullable=True , doc='　Ｘ轴偏移量　', comment='　Ｘ轴偏移量　')
    OffsetY                         : Mapped[float  ] = mapped_column(default=0             , nullable=True , doc='　Ｙ轴偏移量　', comment='　Ｙ轴偏移量　')
    OffsetZ                         : Mapped[float  ] = mapped_column(default=0             , nullable=True , doc='　Ｚ轴偏移量　', comment='　Ｚ轴偏移量　')
    IsCalibrate                     : Mapped[float  ] = mapped_column(default=0             , nullable=True , doc='　校准状态　　', comment='　校准状态　　')

    def __init__(self, **args):
        super().__init__()
        self.initialize()
        self.initParameter(**args)


    def setLevel(self, level: int):
        self.Level = int(level) if isinstance(level, (int, float)) and level in ObjectiveLevel.all() else ObjectiveLevel.Objective1
        self.flushInfo()
    def initParameter(self, **args):
        super(ObjectiveOffsetModel, self).initParameter(**args)
        self.flushInfo()

    def initValue(self):
        super(ObjectiveOffsetModel, self).initValue()
        self.Information                      = '１　　倍物镜相机参数'
        self.Level                            = ObjectiveLevel.Objective1
        self.OffsetX                          = 0
        self.OffsetY                          = 0
        self.OffsetZ                          = 0
        self.IsCalibrate                      = 0
        self.ZPosition                        = 0
        self.ExposureTime                     = 0


    def flushInfo(self):
        if self.Level == ObjectiveLevel.Objective1    :
            self.Information = '１　　倍物镜相机参数'
        elif self.Level == ObjectiveLevel.Objective10   :
            self.Information = '１０　倍物镜相机参数'
        elif self.Level == ObjectiveLevel.Objective20   :
            self.Information = '２０　倍物镜相机参数'
        elif self.Level == ObjectiveLevel.Objective40   :
            self.Information = '４０　倍物镜相机参数'
        elif self.Level == ObjectiveLevel.Objective63   :
            self.Information = '６３　倍物镜相机参数'
        elif self.Level == ObjectiveLevel.Objective100  :
            self.Information = '１００倍物镜相机参数'
        elif self.Level == ObjectiveLevel.ObjectiveNone :
            self.Information = '未知物镜相机参数　　'

    @classmethod
    def getObjectiveConfig(cls, level: int) -> 'ObjectiveOffsetModel':
        item: cls
        if level in ObjectiveLevel.all():
            try:
                dbController.initEngine()
                with Session(dbController.Engine) as session:
                    item = session.query(cls).filter(cls.Level == level).first()
                    session.close()
            except Exception as e:
                AppUtils.print_Exception(e)
                item = cls.Instance(level=level)
        else:
            item = cls.Instance(level=level)
        return item

    @classmethod
    def getConfig(cls, level: int) -> 'ObjectiveOffsetModel':
        item: cls
        if level in ObjectiveLevel.all():
            try:
                dbController.initEngine()
                with Session(dbController.Engine) as session:
                    item = session.query(cls).filter(cls.Level == level).first()
                    session.close()
            except Exception as e:
                AppUtils.print_Exception(e)
                item = cls.Instance(level=level)
        else:
            item = cls.Instance(level=level)

        return item


    @classmethod
    def setOffsetX(cls, level: int, offsetX: float) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(level, int) or not isinstance(offsetX, (int, float)):
            return
        try:
            with DBManager.Session() as session:
                try:
                    session.query(cls).filter(cls.Level == level).update({cls.OffsetX: offsetX})
                    session.commit()
                    isWrong = RECODE_SUCCEED
                except Exception as ex:
                    AppUtils.print_Exception(ex)

                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return isWrong

    @classmethod
    def setOffsetY(cls, level: int, offsetY: float):
        isWrong: int = RECODE_FAILURE
        if not isinstance(level, int) or not isinstance(offsetY, (int, float)):
            return
        try:
            with DBManager.Session() as session:
                try:
                    session.query(cls).filter(cls.Level == level).update({cls.OffsetY: offsetY})
                    session.commit()
                    isWrong = RECODE_SUCCEED
                except Exception as ex:
                    AppUtils.print_Exception(ex)

                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return isWrong

    @classmethod
    def setOffsetZ(cls, level: int, offsetZ: float):
        isWrong: int = RECODE_FAILURE
        if not isinstance(level, int) or not isinstance(offsetZ, (int, float)):
            return
        try:
            with DBManager.Session() as session:
                try:
                    session.query(cls).filter(cls.Level == level).update({cls.OffsetZ: offsetZ})
                    session.commit()
                    isWrong = RECODE_SUCCEED
                except Exception as ex:
                    AppUtils.print_Exception(ex)

                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return isWrong

    @classmethod
    def setOffsetXY(cls, level: int, offsetX: float, offsetY: float):
        isWrong: int = RECODE_FAILURE
        if not isinstance(level, int) or not isinstance(offsetX, (int, float)) or not isinstance(offsetY, (int, float)):
            return
        try:
            with DBManager.Session() as session:
                try:
                    session.query(cls).filter(cls.Level == level).update({cls.OffsetX: offsetX, cls.OffsetY: offsetY})
                    session.commit()
                    isWrong = RECODE_SUCCEED
                except Exception as ex:
                    AppUtils.print_Exception(ex)

                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return isWrong


    @classmethod
    def getOffsetX(cls, level: int) -> float:
        offset: float = 0.0
        item: cls
        try:
            with DBManager.Session() as session:
                item = session.query(cls).filter(cls.Level == level).first()
                if item is not None:
                    offset = item.OffsetX
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return offset

    @classmethod
    def getOffsetY(cls, level: int) -> float:
        offset: float = 0.0
        item: cls
        try:
            with DBManager.Session() as session:
                item = session.query(cls).filter(cls.Level == level).first()
                if item is not None:
                    offset = item.OffsetY
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return offset

    @classmethod
    def getOffsetZ(cls, level: int) -> float:
        offset: float = 0.0
        item: cls
        try:
            with DBManager.Session() as session:
                item = session.query(cls).filter(cls.Level == level).first()
                if item is not None:
                    offset = item.OffsetZ
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return offset

    @classmethod
    def getOffsetXY(cls, level: int) -> (float, float):
        offset_x: float = 0.0
        offset_y: float = 0.0
        item: cls
        try:
            with DBManager.Session() as session:
                item = session.query(cls).filter(cls.Level == level).first()
                if item is not None:
                    offset_x = item.OffsetX
                    offset_y = item.OffsetY
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return offset_x, offset_y

    @classmethod
    def getPositionXYZ(cls, level: int) -> (float, float, float):
        x: float = None
        y: float = None
        z: float = None
        item: cls
        try:
            with DBManager.Session() as session:
                item = session.query(cls).filter(cls.Level == level).first()
                if item is not None:
                    x = item.XPosition
                    y = item.YPosition
                    z = item.ZPosition
                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return x, y, z

    @classmethod
    def setPositionXYZ(cls, level: int, x: float, y: float, z: float):
        isWrong: int = RECODE_FAILURE
        try:
            with DBManager.Session() as session:
                try:
                    session.query(cls).filter(cls.Level == level).update({cls.XPosition: x, cls.YPosition: y, cls.ZPosition: z})
                    session.commit()
                    isWrong = RECODE_SUCCEED
                except Exception as ex:
                    AppUtils.print_Exception(ex)
                    isWrong = RECODE_FAILURE
                    session.rollback()

                session.close()
        except Exception as e:
            AppUtils.print_Exception(e)
        return isWrong

    @classmethod
    def initModels(cls) -> list:
        items: list[cls] = [
            cls.instance(Information      = '１　　倍物镜相机参数'    ,Level                      = ObjectiveLevel.Objective1          ,OffsetX = 0,OffsetY = 0,OffsetZ = 0,IsCalibrate=0, XPosition = 0, YPosition = 0,ZPosition    = 0, ExposureTime = 0,),
            cls.instance(Information      = '１０　倍物镜相机参数'    ,Level                      = ObjectiveLevel.Objective10         ,OffsetX = 0,OffsetY = 0,OffsetZ = 0,IsCalibrate=0, XPosition = 0, YPosition = 0,ZPosition    = 0, ExposureTime = 0,),
            cls.instance(Information      = '２０　倍物镜相机参数'    ,Level                      = ObjectiveLevel.Objective20         ,OffsetX = 0,OffsetY = 0,OffsetZ = 0,IsCalibrate=0, XPosition = 0, YPosition = 0,ZPosition    = 0, ExposureTime = 0,),
            cls.instance(Information      = '４０　倍物镜相机参数'    ,Level                      = ObjectiveLevel.Objective40         ,OffsetX = 0,OffsetY = 0,OffsetZ = 0,IsCalibrate=0, XPosition = 0, YPosition = 0,ZPosition    = 0, ExposureTime = 0,),
            cls.instance(Information      = '６３　倍物镜相机参数'    ,Level                      = ObjectiveLevel.Objective63         ,OffsetX = 0,OffsetY = 0,OffsetZ = 0,IsCalibrate=0, XPosition = 0, YPosition = 0,ZPosition    = 0, ExposureTime = 0,),
            cls.instance(Information      = '１００倍物镜相机参数'    ,Level                      = ObjectiveLevel.Objective100        ,OffsetX = 0,OffsetY = 0,OffsetZ = 0,IsCalibrate=0, XPosition = 0, YPosition = 0,ZPosition    = 0, ExposureTime = 0,),
            cls.instance(Information      = '未知物镜相机参数　　'    ,Level                      = ObjectiveLevel.ObjectiveNone       ,OffsetX = 0,OffsetY = 0,OffsetZ = 0,IsCalibrate=0, XPosition = 0, YPosition = 0,ZPosition    = 0, ExposureTime = 0,),
        ]

        return items

    @classmethod
    def Instance(cls, level: int, **args):
        result: cls = cls.__new__(cls)
        result.__init__()
        result.Level = level
        result.initParameter(**args)
        return result




    __field__ = (
        'Information'   ,
        'Level'         ,
        'XPosition'     ,
        'YPosition'     ,
        'ZPosition'     ,
        'ExposureTime'  ,
        'OffsetX'       ,
        'OffsetY'       ,
        'OffsetZ'       ,
        'IsCalibrate'   ,
    )

    __types__ = (
        str     ,
        int     ,
        float   ,
        float   ,
        float   ,
        float   ,
        float   ,
        float   ,
        float   ,
        int     ,
    )

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

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

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

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

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

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

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

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

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

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