import time

from osgeo import ogr, osr

from rosreestrXml.ui.tools.KPT.kptTools.DbKptDirectory import KptСatalog
from rosreestrXml.ui.tools.KPT.kptTools.KPTXml import GeoPolygonFromEntitySpatial


#from PkkXml.plugins.XmlPkk.DbKptDirectory import KptСatalog
#from PkkXml.plugins.XmlPkk.KPTXml import GeoPolygonFromEntitySpatial
#from PkkXml.plugins.XmlPkk.Utils.TaskProgress import ExecutionProcess


def maxFIDLayer(db_connection,namelayer,nameCol=None):
    sql="Select Max(fid) From "+namelayer
    cursor = db_connection.cursor()
    try:
        cursor.execute(sql)
        records = cursor.fetchall()
        result = records[0]
    except:
        pass
    finally:
        cursor.close()
    return result[0]



def getStructDocuments(count:int):
    struct=[]
    for i in range(count):
        struct.append({'name': 'КодДокумента'+str(i+1), 'type': ogr.OFTString, 'width': 12})
        struct.append({'name': 'НазваниеДокумента' + str(i + 1), 'type': ogr.OFTString, 'width': 500})
        struct.append({'name': 'СерияДокумента' + str(i + 1), 'type': ogr.OFTString, 'width': 45})
        struct.append({'name': 'НомерДокумента' + str(i + 1), 'type': ogr.OFTString, 'width': 45})
        struct.append({'name': 'ДатаВыдачи' + str(i + 1), 'type': ogr.OFTString, 'width': 20})
        struct.append({'name': 'Организация' + str(i + 1), 'type': ogr.OFTString, 'width': 500})
        struct.append({'name': 'ОсобыеОтметки' + str(i + 1), 'type': ogr.OFTString, 'width': 1000})
    return struct

class ObjZone:
    __cs_prj4 = None
    __str_styleMi = None
    __reverseXY = True
    __xmlObjZone = None
    __CadastralNumber=None
    def __init__(self,tagZone,cadNumber,mi_style=None):
        self.__xmlObjZone=tagZone
        self.__str_styleMi=mi_style
        self.__CadastralNumber=cadNumber
    def setMiStyle(self,mi_style):
        self.__str_styleMi=mi_style
    @staticmethod
    def getStruct():
        struct = []

        struct.append({'name': 'КадНомер', 'type': ogr.OFTString, 'width': 50})
        struct.append({'name': 'Описание', 'type': ogr.OFTString,'width':1000})
        struct.append({'name': 'Содержание_ограничений', 'type': ogr.OFTString, 'width': 4000})
        #struct.append({'name': 'УчётныйНомер', 'type': ogr.OFTString, 'width': 254})
        #struct.extend(getStructDocuments(countDocs))
        struct.append({'name': 'MI_STYLE', 'type': ogr.OFTString, 'width': 128})
        return struct

    def Write(self, layer, dbDictionary: KptСatalog,dbDocuments,reverseXY):
        strDescription = self.__xmlObjZone.Description
        valAccountNumber = self.__xmlObjZone.AccountNumber
        geoObj = GeoPolygonFromEntitySpatial(self.__xmlObjZone.EntitySpatial,reverseXY)
        att = []
        att.append({'name': 'КадНомер', 'value': self.__CadastralNumber})
        att.append({'name': 'Описание', 'value': strDescription})
        att.append({'name': 'Содержание_ограничений', 'value': valAccountNumber})
        feature = ogr.Feature(layer.GetLayerDefn())
        #if self.__str_styleMi is not None:
        att.append({'name': 'MI_STYLE', 'value': self.__str_styleMi})
        for atr_item in att:
            # print(atr_item['name'])
            # print(atr_item['value'])
            feature.SetField(atr_item['name'], atr_item['value'])
        if geoObj is not None:
            feature.SetGeometry(geoObj)

        layer.CreateFeature(feature)
        geoObj = None
        feature = None
        #name_layer=layer.GetName()
        #max_fid=maxFIDLayer(dbDocuments.Connection,name_layer,"fid")
        #dbDocuments.Write(max_fid,self.__xmlObjZone.Documents)
        return
class ObjZones():
    __xmlZones = None
    __name = "территориальные_зоны"
    __listZone = None
    __cs_prj4 = None
    __str_styleMi = None
    __reverseXY = True
    __CadastralNumber=None
    __nameProcess="Импорт зон"
    def __init__(self,tagZones,cadastralNumber):
        #super().__init__(0, 100)
        if tagZones is None:
            return
        self.__xmlZones=tagZones
        self.__CadastralNumber=cadastralNumber
        self.__listZone=[]
        for itemtagZone in self.__xmlZones.Zone:
            self.__listZone.append(ObjZone(itemtagZone,self.__CadastralNumber,self.__str_styleMi))
    def setOutParams(self,cs_proj4,mi_style,reverseXY=True):
        self.__str_styleMi = mi_style
        self.__cs_prj4 = cs_proj4
        self.__reverseXY = reverseXY
    def setProperties(self,property):
        self.__property=property
    def Save(self,ds,dbDictionary:KptСatalog,dbDocuments=None):
        layer=self.CreateLayer(ds,self.__cs_prj4)
        self.Write(layer,dbDictionary,None,self.__property['reverseXY'])
    def setParentCadastrNumber(self,cad_number):
        self.__CadastralNumber=cad_number
    def run(self,property:dict,call_back_function=None):
        ds=property['DataSource']
        layer=self.CreateLayer(ds)
        kptCatalog=property['Catalog']
        dbDocument=property['Documents']
        curent_id=0
        print("StartSave Zones:"+str(len(self.__listZone)))
        for zone in self.__listZone:
            time.sleep(0.5)
            zone.setMiStyle(self.__str_styleMi)
            if dbDocument is not None:
                if dbDocument.IsConnect is False:
                    dbDocument.initDb()
            print(call_back_function)
            if call_back_function is not None:
                print("Send to progresBar")
                isCancel = call_back_function.SendValue(curent_id)
                if not isCancel:
                    print("write "+str(curent_id))
                    zone.Write(layer,kptCatalog,dbDocument)

            curent_id=curent_id+1
    @property
    def NameLayer(self):
        return self.__name
    @property
    def NameProcess(self):
        return self.__nameProcess
    @property
    def Count(self):
        if self.__listZone is None:
            return 0
        return len(self.__listZone)
    def CreateLayer(self,ds,createNewLayer=True):
        srs = osr.SpatialReference()
        srs.ImportFromWkt(self.__property['cs'])
        layer=None
        if not createNewLayer:
            layer=ds.GetLayer(self.__name)
            if layer is not None:
                return layer

        layer = ds.CreateLayer(self.__name, srs, geom_type=ogr.wkbUnknown)
        for fld in ObjZone.getStruct():
            # create fields
            field_cur = ogr.FieldDefn(fld['name'], fld['type'])
            type_field = fld['type']
            if fld['type'] == ogr.OFTString:
                field_cur.SetWidth(fld['width'])
            layer.CreateField(field_cur)
        if self.__str_styleMi is not None:
            field_cur = ogr.FieldDefn("MI_STYLE", ogr.OFTString)
            field_cur.SetWidth(128)
            layer.CreateField(field_cur)
        return layer
    def Write(self,layer,dbDictionary:KptСatalog,mapCatalog=None):
        if self.__listZone is None:
            return
        ''' Получаем стиль из базы'''
        mi_style = dbDictionary.GetStyle('kpt_10_style', 'Zones')
        if mi_style[0] is None:
            print(mi_style[1])
            str_mi_style = 'Pen (2, 6, 16711680) Brush (1, 16777215, 16777215)'
        else:
            str_mi_style = mi_style[0]
        #layer.StartTransaction()
        for zone in self.__listZone:
            zone.setMiStyle(str_mi_style)
            '''
            if dbDoc is not None:
                if dbDoc.IsConnect is False:
                    dbDoc.initDb()
            '''
            zone.Write(layer,dbDictionary,None,self.__property['reverseXY'])
        mapCatalog.addLayerInfoInMapCataalog(layer,self.__property['cs_mi'])
        #layer.CommitTransaction()
    def WriteItem(self,id_item,layer,dbDictionary:KptСatalog,dbDoc):
        zone = self.__listZone[id_item]
        zone.setMiStyle(self.__str_styleMi)
        if dbDoc is not None:
            if dbDoc.IsConnect is False:
                dbDoc.initDb()
        zone.Write(layer, dbDictionary, dbDoc)


