import os
from abc import ABCMeta, abstractmethod
from enum import Enum
from pathlib import Path

#import ogr as ogr
#import osgeo

#print(osgeo)
from osgeo import ogr


#from PkkXml.plugins.XmlPkk.DbKptDirectory import KptСatalog
#from PkkXml.plugins.XmlPkk.Utils.DlgProgressBar import DlgProgressBar
#from PkkXml.plugins.XmlPkk.Utils.TaskProgress import PkkXmlProcess
from rosreestrXml.ui.tools.OutDrv.DbDocuments import DocumentsDb
from rosreestrXml.ui.tools.OutDrv.mapcatalog import MapCatalog
from rosreestrXml.ui.tools.KPT.kptTools.DbKptDirectory import KptСatalog
from rosreestrXml.ui.tools.utils.TaskProgress import PkkXmlProcess


class TypeGeo(Enum):
    POINTS=1
    POLYLINE=2
class TypeGeometryProviderOgr:
    MapInfo=1
    EFAL =2
    SQLITE=3
    GPKG=4
class AbstactClassDbGeo(metaclass = ABCMeta):
    __path=None
    def __init__(self):
        pass


    @abstractmethod
    def Create(self, path_out:str):
        pass

    @abstractmethod
    def Save(self,name,points,att,type):
        pass

    @abstractmethod
    def Close(self):
        pass
class DbGeoOgr:
    __dp=None
    __ds=None
    __dbCatalog=None
    __dbDocuments=None
    __outPathDb=None
    __typeInit=True
    def __init__(self,dbCatalog,pathOutDb=None,typeInit=False):
        self.__dbCatalog=dbCatalog
        self.__outPathDb=pathOutDb
        self.__typeInit=typeInit
        #self.initDs(pathOutDb)
    def initDs(self,pathOutDb=None):
        ''' нициализация gdal выходного datasource
        pathOutDb - путь на файл ds
        typeInit - создание нового ( True ) или открыть существующий
        '''

        if self.__typeInit :
            self.Create(self.__outPathDb, TypeGeometryProviderOgr.GPKG)
        else:
            self.Open(self.__outPathDb)
        self.__dbDocuments = DocumentsDb(self.__outPathDb)
    def setDbDocuments(self,dbDoc):

        self.__dbDocuments=dbDoc
    def initCatalog(self):
        if self.__dbCatalog is None:
            self.__dbCatalog = KptСatalog()
        return self.__dbCatalog
    def setTypeAdd(self,typeAdd):
        self.__typeInit=typeAdd
    @property
    def DataSource(self):
        return self.__ds
    @property
    def PropertyDB(self):
        property = {}
        property["DataSource"] = self
        property['Catalog'] = self.__dbCatalog
        property['Documents'] = self.__dbDocuments
        property['TypeInitData']=self.__typeInit
        return property
    def Open(self,path_db):
        if not os.path.exists(path_db):
            self.Create(self.__outPathDb, TypeGeometryProviderOgr.GPKG)
            return

        self.__ds=ogr.Open(path_db,1)
        if self.__ds is None:
            print("Error open:"+path_db)

        jkl=0
    def Create(self,path_db,typeDb:TypeGeometryProviderOgr):
        self.__path_db=path_db
        if typeDb==TypeGeometryProviderOgr.SQLITE:

            self.__dp=ogr.GetDriverByName('SQLite')
            #drv = ogr.GetDriverByName('GPKG')
            self.__ds= self.__dp.CreateDataSource(path_db, options=['SPATIALITE=YES'])
            self.__mapCatalog = MapCatalog(self.__path_db)
            return True
        elif typeDb==TypeGeometryProviderOgr.GPKG:
            self.__dp = ogr.GetDriverByName('GPKG')
            if Path(path_db).exists():
                os.remove(path_db)
            self.__ds = self.__dp.CreateDataSource(path_db)
            self.__mapCatalog = MapCatalog(self.__path_db)
            return True
        else:
            self.__ds=None
            return False
    def Save(self,objKPT):
        if objKPT is None:
            return
        from rosreestrXml.ui.tools.KPT.under_construction.ObjectUnderConstraction import RecordUnderCostraction
        if isinstance(objKPT,RecordUnderCostraction):
            layer=None
            objKPT.Save(self.__dbDocuments)
        else:
            layer=objKPT.CreateLayer(self.__ds,self.__typeInit)
        #layer.StartTransaction()
            objKPT.Write(layer,self.__dbCatalog,self.__mapCatalog)
        #layer.CommitTransaction()
        if isinstance(layer,ogr.Layer):
            layer=None

    def Close(self):
        if self.__dbCatalog is not None:
            self.__dbCatalog.close()
        if self.__dbDocuments is not None:
            self.__dbDocuments.close()
        self.__mapCatalog.Close()
        self.__ds=None
        #self.__mapCatalog = MapCatalog(self.__path_db)
    def runProcess(self,listObjKpt):
        kpt_process = PkkXmlProcess()
        count_obj=len(listObjKpt)
        procent_item=int(100/count_obj)
        property_process = {}
        property_process['Catalog']=self.__dbCatalog
        property_process['Documents'] = self.__dbDocuments
        property_process['DataSource']=self.__ds
        for i in range(count_obj):
            print(listObjKpt[i])
            listObjKpt[i].setProcentStart(i*procent_item)
        '''
        dlg = DlgProgressBar(kpt_process)
        kpt_process.setDopProperty(property_process)
        kpt_process.setClsProgressBar(dlg)
        kpt_process.setProcess(listObjKpt)
        dlg.exec(100)
        '''
        print("End Process")
def LayerExist(ds,name_layer):
    for id_layer in range(ds.GetLayerCount()):
        layer=ds.GetLayerByIndex(id_layer)
        name=layer.GetName()
        if name==name_layer:
            return True
    return False
def DeleteLayer(ds,name_layer):
    ds.DeleteLayer(name_layer)
    return



