# coding = utf-8
import sys
import os
from qgis.core import *
from qgis.gui import *
from PyQt4.QtCore import QFileInfo, QSize
from PyQt4.QtGui import QDialogButtonBox
from tempfile import gettempdir

from ..dialogs.copyFromVector_dialog import CopyFromVector

from pyspatialite import dbapi2 as sqlite3

assert(__name__ == "__main__")

data_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'copyFromVector_test_data'))
args = sys.argv
app = QgsApplication(args, True)
QgsApplication.initQgis()

spatialite_file = os.path.join(gettempdir(), 'copy_test.sqlite')
if os.path.exists(spatialite_file):
    os.remove(spatialite_file)

layer = QgsVectorLayer(os.path.join(data_dir, 'source.shp'), 'source', 'ogr')
assert( layer.isValid() )
QgsMapLayerRegistry.instance().addMapLayer(layer)
layer = QgsVectorLayer(os.path.join(data_dir, 'source_point.shp'), 'source_point', 'ogr')
assert( layer.isValid() )
QgsMapLayerRegistry.instance().addMapLayer(layer)
layer = QgsVectorLayer(os.path.join(data_dir, 'source_line.shp'), 'source_line', 'ogr')
assert( layer.isValid() )
QgsMapLayerRegistry.instance().addMapLayer(layer)


layerFrom = QgsMapLayerRegistry.instance().mapLayersByName('source')[0]
QgsVectorFileWriter.writeAsVectorFormat(layerFrom, spatialite_file,
                             "utf-8", None, "SQLite", False, None ,["SPATIALITE=YES",])

layerTo = QgsVectorLayer(
        'dbname=\'{}\' table="copy_test" (geometry) sql='.format(spatialite_file),
        'copy_test', 'spatialite')
assert( layerTo.isValid() )
QgsMapLayerRegistry.instance().addMapLayer(layerTo)

with edit(layerTo):
    for f in layerTo.getFeatures():
        f['value']=None
        layerTo.updateFeature(f)

for f in layerTo.getFeatures():
    assert(f['value'].isNull())

dlg = CopyFromVector(iface=None)
dlg.cmbLayerFrom.setCurrentIndex(dlg.cmbLayerFrom.findText('source'))
dlg.cmbLayerTo.setCurrentIndex(dlg.cmbLayerTo.findText('copy_test'))

app.processEvents()

dlg.cmbFieldFrom_1.setCurrentIndex(dlg.cmbFieldFrom_1.findText('value'))
dlg.cmbFieldTo_1.setCurrentIndex(dlg.cmbFieldTo_1.findText('value'))

app.processEvents()

if len(sys.argv) > 1:
    dlg.show()
    app.exec_()
else:
    dlg.buttonBox.button(QDialogButtonBox.Ok).clicked.emit(True)
    app.processEvents()

for f in layerTo.getFeatures():
    assert(f['value'] in [5., 3.])



# test copy with a grid
xMin, yMin, xMax, yMax = (
    layerFrom.extent().xMinimum(), 
    layerFrom.extent().yMinimum(),
    layerFrom.extent().xMaximum(),
    layerFrom.extent().yMaximum())
dX = (xMax-xMin)
dY = (yMax-yMin)
xMin -= dX    
xMax += dX    
yMin -= dY    
yMax += dY    
dX *= 3
dY *= 3

with edit(layerTo):
    for f in layerTo.getFeatures():
        layerTo.deleteFeature(f.id())

    fid = 0
    for i in range(10):
        for j in range(10):
            rec = QgsGeometry.fromPolygon([[
                QgsPoint(xMin+dX*float(i)/10, yMin+dY*float(j)/10),
                QgsPoint(xMin+dX*float(i+1)/10, yMin+dY*float(j)/10),
                QgsPoint(xMin+dX*float(i+1)/10, yMin+dY*float(j+1)/10),
                QgsPoint(xMin+dX*float(i)/10, yMin+dY*float(j+1)/10)]])

            f.setGeometry(rec)
            fid += 1
            f['ogc_fid'] = fid
            f['value'] = None
            layerTo.addFeature(f)

assert(layerTo.getFeatures(QgsFeatureRequest(46)).next()['value'].isNull())
assert(layerTo.getFeatures(QgsFeatureRequest(1)).next()['value'].isNull())

dlg = CopyFromVector(iface=None)
dlg.cmbLayerFrom.setCurrentIndex(dlg.cmbLayerFrom.findText('source'))
dlg.cmbLayerTo.setCurrentIndex(dlg.cmbLayerTo.findText('copy_test'))

app.processEvents()

dlg.cmbFieldFrom_1.setCurrentIndex(dlg.cmbFieldFrom_1.findText('value'))
dlg.cmbFieldTo_1.setCurrentIndex(dlg.cmbFieldTo_1.findText('value'))
dlg.buttonBox.button(QDialogButtonBox.Ok).clicked.emit(True)

app.processEvents()

assert(layerTo.getFeatures(QgsFeatureRequest(46)).next()['value']==3.0)
assert(layerTo.getFeatures(QgsFeatureRequest(54)).next()['value']==5.0)
assert(layerTo.getFeatures(QgsFeatureRequest(1)).next()['value'].isNull())


# copy from point layer
dlg = CopyFromVector(iface=None)
dlg.cmbLayerFrom.setCurrentIndex(dlg.cmbLayerFrom.findText('source_point'))
dlg.cmbLayerTo.setCurrentIndex(dlg.cmbLayerTo.findText('copy_test'))

app.processEvents()

dlg.cmbFieldFrom_1.setCurrentIndex(dlg.cmbFieldFrom_1.findText('value'))
dlg.cmbFieldTo_1.setCurrentIndex(dlg.cmbFieldTo_1.findText('value'))

dlg.buttonBox.button(QDialogButtonBox.Ok).clicked.emit(True)
app.processEvents()

assert(layerTo.getFeatures(QgsFeatureRequest(77)).next()['value']==6.0)
assert(layerTo.getFeatures(QgsFeatureRequest(86)).next()['value']==7.0)
assert(layerTo.getFeatures(QgsFeatureRequest(1)).next()['value'].isNull())

# copy from line layer with selection
layerFrom = QgsMapLayerRegistry.instance().mapLayersByName('source_line')[0]
layerFrom.select(1)
app.processEvents()

dlg = CopyFromVector(iface=None)
dlg.check_selected.setChecked(True)
dlg.cmbLayerFrom.setCurrentIndex(dlg.cmbLayerFrom.findText('source_line'))
dlg.cmbLayerTo.setCurrentIndex(dlg.cmbLayerTo.findText('copy_test'))

app.processEvents()

dlg.cmbFieldFrom_1.setCurrentIndex(dlg.cmbFieldFrom_1.findText('value'))
dlg.cmbFieldTo_1.setCurrentIndex(dlg.cmbFieldTo_1.findText('value'))

dlg.buttonBox.button(QDialogButtonBox.Ok).clicked.emit(True)
app.processEvents()

assert(layerTo.getFeatures(QgsFeatureRequest(11)).next()['value']!=8.0)
assert(layerTo.getFeatures(QgsFeatureRequest(91)).next()['value']==9.0)
assert(layerTo.getFeatures(QgsFeatureRequest(1)).next()['value'].isNull())

# copy everything to spatialite and test
db = os.path.join(gettempdir(), "cpy_test.sqlite")
if os.path.exists(db):
    os.remove(db)
con = sqlite3.connect(db)
cur = con.cursor()
cur.execute("select InitSpatialMetaData(1)")
cur.execute("create table source_polygon(id integer primary key, value real)")
cur.execute("create table source_point(id integer primary key, value real)")
cur.execute("create table source_line(id integer primary key, value real)")
cur.execute("create table dest(id integer primary key, value real)")
cur.execute("select AddGeometryColumn('source_polygon', 'geom', 32632, 'POLYGON', 'XY')")
cur.execute("select AddGeometryColumn('source_point', 'geom', 32632, 'POINT', 'XY')")
cur.execute("select AddGeometryColumn('source_line', 'geom', 32632, 'LINESTRING', 'XY')")
cur.execute("select AddGeometryColumn('dest', 'geom', 32632, 'POLYGON', 'XY')")

for src, dst in [('source', 'source_polygon'), ('source_point', 'source_point'), ('source_line', 'source_line'), ('copy_test', 'dest')]:
    layerFrom = QgsMapLayerRegistry.instance().mapLayersByName(src)[0]
    for f in layerFrom.getFeatures():
        geom = f.geometry()
        geom.transform(QgsCoordinateTransform(layerFrom.crs(), QgsCoordinateReferenceSystem(32632)))
        cur.execute("insert into {}(geom, value) values(GeometryFromText('{}', 32632), {})".format(
            dst,
            geom.exportToWkt(), 
            f['value']))
cur.execute("update dest set value=null")
con.commit()
con.close()

# remove all layers
QgsMapLayerRegistry.instance().removeAllMapLayers()
app.processEvents()

layer = QgsVectorLayer( 'dbname=\'{}\' table="{}" (geom) sql='.format(db, 'source_polygon'), 'source_polygon', 'spatialite')
assert( layer.isValid() )
QgsMapLayerRegistry.instance().addMapLayer(layer)
layer = QgsVectorLayer( 'dbname=\'{}\' table="{}" (geom) sql='.format(db, 'source_point'), 'source_point', 'spatialite')
assert( layer.isValid() )
QgsMapLayerRegistry.instance().addMapLayer(layer)
layer = QgsVectorLayer( 'dbname=\'{}\' table="{}" (geom) sql='.format(db, 'source_line'), 'source_line', 'spatialite')
assert( layer.isValid() )
QgsMapLayerRegistry.instance().addMapLayer(layer)
layer = QgsVectorLayer( 'dbname=\'{}\' table="{}" (geom) sql='.format(db, 'dest'), 'dest', 'spatialite')
assert( layer.isValid() )
QgsMapLayerRegistry.instance().addMapLayer(layer)

layerTo = layer

# copy from point layer
dlg = CopyFromVector(iface=None)
dlg.cmbLayerFrom.setCurrentIndex(dlg.cmbLayerFrom.findText('source_point'))
dlg.cmbLayerTo.setCurrentIndex(dlg.cmbLayerTo.findText('dest'))

app.processEvents()

dlg.cmbFieldFrom_1.setCurrentIndex(dlg.cmbFieldFrom_1.findText('value'))
dlg.cmbFieldTo_1.setCurrentIndex(dlg.cmbFieldTo_1.findText('value'))

dlg.buttonBox.button(QDialogButtonBox.Ok).clicked.emit(True)
app.processEvents()

# copy from line layer with selection
layerFrom = QgsMapLayerRegistry.instance().mapLayersByName('source_line')[0]
layerFrom.select(2)
app.processEvents()

dlg = CopyFromVector(iface=None)
dlg.check_selected.setChecked(True)
dlg.cmbLayerFrom.setCurrentIndex(dlg.cmbLayerFrom.findText('source_line'))
dlg.cmbLayerTo.setCurrentIndex(dlg.cmbLayerTo.findText('dest'))

app.processEvents()

dlg.cmbFieldFrom_1.setCurrentIndex(dlg.cmbFieldFrom_1.findText('value'))
dlg.cmbFieldTo_1.setCurrentIndex(dlg.cmbFieldTo_1.findText('value'))

dlg.buttonBox.button(QDialogButtonBox.Ok).clicked.emit(True)
app.processEvents()

# copy from polygon layer 
dlg = CopyFromVector(iface=None)
dlg.check_selected.setChecked(True)
dlg.cmbLayerFrom.setCurrentIndex(dlg.cmbLayerFrom.findText('source_polygon'))
dlg.cmbLayerTo.setCurrentIndex(dlg.cmbLayerTo.findText('dest'))

app.processEvents()

dlg.cmbFieldFrom_1.setCurrentIndex(dlg.cmbFieldFrom_1.findText('value'))
dlg.cmbFieldTo_1.setCurrentIndex(dlg.cmbFieldTo_1.findText('value'))

dlg.buttonBox.button(QDialogButtonBox.Ok).clicked.emit(True)
app.processEvents()


assert(layerTo.getFeatures(QgsFeatureRequest(77)).next()['value']==6.0)
assert(layerTo.getFeatures(QgsFeatureRequest(86)).next()['value']==7.0)
assert(layerTo.getFeatures(QgsFeatureRequest(11)).next()['value']!=8.0)
assert(layerTo.getFeatures(QgsFeatureRequest(91)).next()['value']==9.0)
assert(layerTo.getFeatures(QgsFeatureRequest(46)).next()['value']==3.0)
assert(layerTo.getFeatures(QgsFeatureRequest(55)).next()['value']==5.0)
assert(layerTo.getFeatures(QgsFeatureRequest(1)).next()['value'].isNull())
