#---------------------------------------------------------------------
# 
# mac_noise - A QGIS plugin set to work with flight noise data
# for the Metropolitan Airports Commission of Minneapolis, MN.
#
# Copyright (C) 2008  Aaron Racicot, Z-Pulley Inc.
# Copyright (C) 2008  Metropolitan Airports Commission of Minneapolis
#
# EMAIL: aaronr (at) z-pulley.com
# WEB  : www.z-pulley.com
#        www.reprojected.com
#
#---------------------------------------------------------------------
# 
# licensed under the terms of GNU GPL 2
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# 
#---------------------------------------------------------------------

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *

# for grabbing the elevation
# TODO wrap this with check for errors on import and notify the user gracefully if
# they need to add psycopg2
import psycopg2
import psycopg2.extras

import math
try:
    import PyQt4.Qwt5 as Qwt
except ImportError:
    try:
        import Qwt5 as Qwt
    except:
        pass

import pdb

from mac_elevation_ui import Ui_ElevationWindow

class ElevationData(Qwt.QwtData):
    def __init__(self, data, size):
        Qwt.QwtData.__init__(self)
        self.__data = data
        self.__size = size

    def copy(self):
        return self

    def size(self):
        return self.__size

    def x(self, i):
        return i

    def y(self, i):
        return self.__data[i]

# class SimpleData


class SimplePlot(Qwt.QwtPlot):

    def __init__(self, plotdata):
        Qwt.QwtPlot.__init__(self)

        self.plotdata = plotdata

        # make a QwtPlot widget
        self.setTitle('MAC Elevation Profile')
        self.insertLegend(Qwt.QwtLegend(), Qwt.QwtPlot.RightLegend)

        # a variation on the C++ example
        self.plotLayout().setAlignCanvasToScales(True)
        grid = Qwt.QwtPlotGrid()
        grid.attach(self)
        grid.setPen(QPen(Qt.black, 0, Qt.DotLine))

        # set axis titles
        self.setAxisTitle(Qwt.QwtPlot.xBottom, 'Time -->')
        self.setAxisTitle(Qwt.QwtPlot.yLeft, 'Elevation -->')

        # insert a few curves
        cSin = Qwt.QwtPlotCurve('Elevation for Flight Track1')
        cSin.setPen(QPen(Qt.red))
        cSin.attach(self)

        #cCos = Qwt.QwtPlotCurve('Elevation for Flight Track1')
        #cCos.setPen(QPen(Qt.blue))
        #cCos.attach(self)

        # initialize the data
        cSin.setData(ElevationData(plotdata, len(plotdata)))
        #cCos.setData(SimpleData(math.cos, 100))

        ## insert a horizontal marker at y = 0
        #mY = Qwt.QwtPlotMarker()
        #mY.setLabel(Qwt.QwtText('y = 0'))
        #mY.setLabelAlignment(Qt.AlignRight | Qt.AlignTop)
        #mY.setLineStyle(Qwt.QwtPlotMarker.HLine)
        #mY.setYValue(0.0)
        #mY.attach(self)

        ## insert a vertical marker at x = 2 pi
        #mX = Qwt.QwtPlotMarker()
        #mX.setLabel(Qwt.QwtText('x = 2 hours'))
        #mX.setLabelAlignment(Qt.AlignRight | Qt.AlignTop)
        #mX.setLineStyle(Qwt.QwtPlotMarker.VLine)
        #mX.setXValue(2*math.pi)
        #mX.attach(self)

        # replot
        self.replot()

class ElevationWindow(QDialog, Ui_ElevationWindow):
    def __init__(self, iface, fl, plugin):
        QDialog.__init__(self, iface.mainWindow(), fl)
        self.setupUi(self)
        self.iface = iface
        self.plugin = plugin
        self.connect(self.buttonBox.button(QDialogButtonBox.Close), SIGNAL("clicked()"), self.close)
        self.demo = None

    def setupMyUI(self):
        #activeLayer = self.iface.activeLayer()
        returnVal = False
        activeLayer = self.plugin.macLayer
        self.activeLayer = activeLayer
        if activeLayer and (activeLayer.type() == activeLayer.VectorLayer):
            returnVal = True
            vprovider = activeLayer.dataProvider()
            dataUri = vprovider.dataSourceUri()
            # print dataUri
            # dbname='test_db' host=localhost port=5432 user='aaronr' table="mac_flights2" (the_geom) sql=
            dataUriList = dataUri.split(QString(" "))
            validDB = False
            dbname = None
            host = None
            port = None
            user = None
            table = None
            sql = None
            for uri in dataUriList:
                if uri.contains(QString("dbname=")):
                    validDB = True
                    # We have a database... so lets build the psycopg2 URI
                    splitUri = uri.split(QString("="))
                    # print "uri=" + uri
                    if len(splitUri)>1:
                        # print "splitUri=" + splitUri[1]
                        dbname = splitUri[1]
                if uri.contains(QString("host=")):
                    splitUri = uri.split(QString("="))
                    if len(splitUri)>1:
                        host = splitUri[1]
                if uri.contains(QString("port=")) and not uri.contains(QString("air")):
                    splitUri = uri.split(QString("="))
                    if len(splitUri)>1:
                        port = splitUri[1]
                if uri.contains(QString("user=")):
                    splitUri = uri.split(QString("="))
                    if len(splitUri)>1:
                        user = splitUri[1]
                if uri.contains(QString("table=")):
                    splitUri = uri.split(QString("="))
                    if len(splitUri)>1:
                        if splitUri[1].contains(QString(".")):                    
                            splitTable = splitUri[1].split(QString("."))
                            if len(splitTable)>1:
                                schema = splitTable[0].remove(QChar("\""))
                                table = splitTable[1].remove(QChar("\""))
                        else:
                            table = splitUri[1].remove(QChar("\""))
                if uri.contains(QString("sql=")):
                    splitUri = uri.split(QString("="))
                    if len(splitUri)>1:
                        sql = splitUri[1]
            psyUri = ""
            if dbname is not None:
                psyUri = psyUri + "dbname=" + str(dbname) + " "
            if host:
                psyUri = psyUri + "host='" + str(host) + "' "
            if port:
                psyUri = psyUri + "port='" + str(port) + "' "
            if user:
                psyUri = psyUri + "user=" + str(user) + " "
            # connection = psycopg2.connect("dbname='tisec_dss' user='aaronr'")
            # print "psyUri=" + psyUri
            # print "table=" + table
            # print "sql=" + sql
            connection = psycopg2.connect(psyUri)
            mark = connection.cursor(cursor_factory=psycopg2.extras.DictCursor)
            
            if schema != None and schema != "public":
                # print "Setting schema to " + str(schema)
                mark.execute("SET search_path TO %s,public;" % (schema))
            elif schema != None and schema == "public":
                # print "Setting schema to " + str(schema)
                mark.execute("SET search_path TO %s;" % (schema))
            
            # Find the first selected geom...
            allAttrs = vprovider.attributeIndexes()
            vprovider.select(allAttrs)
            lineList = activeLayer.selectedFeatures()
            gid = 0
            if len(lineList) > 0:
                for line in lineList:
                    #tempGeom = line.geometry()
                    # Grab the gid of the line we are interested in
                    index = vprovider.fieldNameIndex(QString("gid"))
                    # DEBUG
                    #pyqtRemoveInputHook()
                    #pdb.set_trace()
                    # DEBUG
                    gid = line.id()
                    #gid = line.attributeMap()[index].toString()
                    # print "Found GID=" + str(gid)
            numPoints = 0
            mark.execute("select numpoints(the_geom) from mac_flights2 where gid="+str(gid))
            numPointsRes = mark.fetchone()
            if numPointsRes and len(numPointsRes)>0:
                numPoints = numPointsRes[0]
            # print "Number of Points = " + str(numPoints)
            elevations = []
            if numPoints>0:
                for i in range(1,numPoints+1):
                    sql = "select z(pointn(the_geom,%s)) from mac_flights2 where gid=%s" % (str(i),str(gid))
                    # print sql
                    mark.execute(sql)                
                    # mark.execute("select z(pointn(the_geom,%s)) from mac_flights2 where gid=%s"%(str(gid),str(i)))
                    elevations.append(mark.fetchone()[0])
                # print elevations
            if self.demo != None:
                self.demo.hide()
                self.gridlayout.removeWidget(self.demo)                
            self.demo = SimplePlot(elevations)
            # demo.resize(500, 300)
            # demo.show()
            self.gridlayout.addWidget(self.demo)

        return returnVal
