import axipy
from PySide2.QtCore import QObject
from axipy import provider_manager, CoordSystem, Geometry, data_manager, Feature,GeometryType
from osgeo import ogr
from osgeo.ogr import wkbUnknown, wkbPoint, wkbLineString,wkbPolygon,wkbMultiPoint, wkbMultiLineString, wkbMultiPolygon, wkbGeometryCollection


def getOGRwkbGeometryType(int_type):
    if int_type==0:
        return   wkbUnknown
    if int_type==1:
        return    wkbPoint
    if int_type==2:
        return     wkbLineString
    if int_type==3:
        return     wkbPolygon
    if int_type==4:
        return     wkbMultiPoint
    if int_type==5:
        return      wkbMultiLineString
    if int_type==6:
        return       wkbMultiPolygon
    if int_type==7:
        return        wkbGeometryCollection
    return wkbUnknown
def cloneFeature(ft:axipy.da.Feature)->axipy.da.Feature:
    items=ft.items()
    geometry=ft.geometry.clone()
    style=ft.style.clone()
    ft_out=Feature()
    for item in items:
        ft_out[item[0]]=item[1]
    ft_out.geometry=geometry
    ft_out.style=style
    return ft_out

class CopyOgcSpatial(QObject):
    __isCancel = False

    def copy(self, table_source: str, dest_table: str, geometry_filter: Geometry,name_layer=None,name_out_driver=None):
        self.__isCancel = False
        ds_source=ogr.Open(table_source)
        if ds_source is None:
            return False
        layer_source=None
        if name_layer is None:
            layer_source=ds_source.GetLayer()
        else:
            layer_source=ds_source.GetLayerByName(name_layer)
        if layer_source is None:
            ds_source=None
            return False
        source_def = layer_source.GetLayerDefn()
        try:
            if name_out_driver is None:
                driver_dest=ds_source.GetDriver()
            else:
                driver_dest=driver = ogr.GetDriverByName(name_out_driver)
            ds_out=driver_dest.CreateDataSource(dest_table)
            source_srs = layer_source.GetSpatialRef()
            name_source_layer=layer_source.GetName()
            layer_out = ds_out.CreateLayer(name_source_layer, source_srs, geom_type=layer_source.GetGeomType(), options=['ENCODING=UTF-8'])
            #layer_out = ds_out.CreateLayer(name_source_layer, source_srs, geom_type=ds_source.GetMetadata(),
            #                               options=['OVERWRITE=YES'])
            ''' копируем структуру'''
            for i in range(0, source_def.GetFieldCount()):
                def_ft = source_def.GetFieldDefn(i)
                layer_out.CreateField(def_ft)
            layer_source.SetSpatialFilter(geometry_filter)
            for feature in layer_source:
                ft_out=feature.Clone()
                #ft_out = ogr.Feature(layer_out.GetLayerDefn())
                geometry_source=feature.GetGeometryRef()
                isIntrsect=geometry_filter.Intersects(geometry_source)
                if not isIntrsect:
                    geometry_source=None
                    ft_out=None

                    continue
                new_geometry=geometry_filter.Intersection(geometry_source)
                if new_geometry is None:
                    geometry_source = None
                    ft_out = None
                    continue
                #print(geometry_source.GetGeometryName())
                ft_out.SetGeometry(new_geometry)
                layer_out.CreateFeature(ft_out)
                new_geometry=None
                geometry_source=None
                ft_out = None
        except Exception as ex:
            pass
        finally:
            if layer_source is not None:
                layer_source=None
            if ds_source is not None:
                ds_source=None
            if layer_out is not None:
                layer_out=None
            if ds_out is not None:
                ds_out=None
        return True


class CopyTabSpatial(QObject):
    '''
    Класс фонового копирования таблицы
    '''
    __isCancel=False
    def copy(self,table_source:str,dest_table:str,geometry_filter:Geometry):
        self.__isCancel=False
        tab_source=None
        tab_dest=None
        if geometry_filter is None:
            return False
        table_source = provider_manager.open_hidden({'src': table_source})
        if table_source is None:
            return False
        try:
            schema_source = table_source.schema
            definition = {'src': dest_table,
                          'schema': schema_source,
                          'hidden': True
                          }
            tab_dest = provider_manager.tab.create_open(dest_table, schema_source)
            geo_bound = geometry_filter.bounds
            if not (table_source.coordsystem==geometry_filter.coordsystem):
                geo_bound=geometry_filter.reproject(table_source.coordsystem).bounds
            item_sel = table_source.itemsInRect(geo_bound)
            out_ft = []
            for ft in item_sel:
                if self.__isCancel:
                    break
                if ft.geometry.intersects(geometry_filter):
                    #if ft.geometry.type == GeometryType.Text or ft.geometry.type == GeometryType.Point:
                    if ft.geometry.type == GeometryType.Text :
                        out_ft.append(ft)

                    else:
                        geo_intersect = ft.geometry.intersection(geometry_filter)
                        if geo_intersect is not None:
                            ft_out = cloneFeature(ft)
                            ft_out.geometry = geo_intersect
                            out_ft.append(ft_out)

            if len(out_ft) > 0:
                tab_dest.insert(out_ft)
                tab_dest.commit()
            tab_dest.close()
        except Exception as ex:
            jkl=0
            pass
        finally:
            if tab_source is not None:
                tab_source.close
            if tab_dest is not None:
                tab_dest.close()

