"""
# -*- coding: utf-8 -*-
#
# ============
============================================
# 
# Purpose: Create a square or hexagon grid for use with Marxan
# Author: Trevor Wiens
# Copyright: Apropos Information Systems Inc.
# Acknolwedgements: This function was derived from QGIS fTools VectorGrid
#                   function created by Carson Farmer
# Date: 2011-11-11
# License: GPL2 
# 
# 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 import QtCore, QtGui
import qmarxan
from qgis.core import *
from ui_qm_mkgrid import Ui_qm_mkgrid
import math,os
from qm_utils import qmCalculateThread

class qmMkGrid(QtGui.QDialog):

    def __init__(self, iface):
    
        self.iface = iface
        self.mLayer = None
        self.tLayer = None

        # Import required plugins and if missing show the plugin's name
        import sys
        ftPath = os.path.join(str(QtCore.QFileInfo(QgsApplication.qgisUserDbFilePath()).path()), 'python/plugins/fTools')
        if not ftPath in sys.path:
            sys.path.append(ftPath)
        req_plugin = "ftools 0.5.10"
        try:
            import ftools_utils
        except:
            QtGui.QMessageBox.information(self, self.tr("Missing Plugins"), 
                    self.tr("Missing plugin: %s" % req_plugin))
                    
        QtGui.QDialog.__init__(self)
        # Set up the user interface from Designer.
        self.ui = Ui_qm_mkgrid()
        self.ui.setupUi(self)
        self.setFixedSize(460,582)
        QtCore.QObject.connect(self.ui.toolOut, QtCore.SIGNAL("clicked()"), self.outFile)
        QtCore.QObject.connect(self.ui.spnUnitArea, QtCore.SIGNAL("valueChanged(double)"), self.offset)
        QtCore.QObject.connect(self.ui.spnSideLength, QtCore.SIGNAL("valueChanged(double)"), self.offset)
        QtCore.QObject.connect(self.ui.spnXmax, QtCore.SIGNAL("valueChanged(double)"), self.updateCellCount)
        QtCore.QObject.connect(self.ui.spnXmin, QtCore.SIGNAL("valueChanged(double)"), self.updateCellCount)
        QtCore.QObject.connect(self.ui.spnYmax, QtCore.SIGNAL("valueChanged(double)"), self.updateCellCount)
        QtCore.QObject.connect(self.ui.spnYmin, QtCore.SIGNAL("valueChanged(double)"), self.updateCellCount)
        #QObject.connect(self.inShape, SIGNAL("currentIndexChanged(QString)"), self.updateInput)
        QtCore.QObject.connect(self.ui.rdoArea, QtCore.SIGNAL("clicked()"), self.updateCellCount)
        QtCore.QObject.connect(self.ui.rdoSideLength, QtCore.SIGNAL("clicked()"), self.updateCellCount)
        QtCore.QObject.connect(self.ui.rdoHexagon, QtCore.SIGNAL("clicked()"), self.updateCellCount)
        QtCore.QObject.connect(self.ui.rdoSquare, QtCore.SIGNAL("clicked()"), self.updateCellCount)
        QtCore.QObject.connect(self.ui.btnUpdate, QtCore.SIGNAL("clicked()"), self.updateLayer)
        QtCore.QObject.connect(self.ui.btnCanvas, QtCore.SIGNAL("clicked()"), self.updateCanvas)
        self.ui.buttonOk = self.ui.buttonBox_2.button( QtGui.QDialogButtonBox.Ok )
        self.setWindowTitle(self.tr("Create Planning Unit Grid"))
        layermap = QgsMapLayerRegistry.instance().mapLayers()
        for name, layer in layermap.iteritems():
            self.ui.inShape.addItem( unicode( layer.name() ) )
        self.ui.progressBar.setRange( 0, 100 )

    def updateCellCount( self ):
        try:
            xmin = self.ui.spnXmin.value()
            ymin = self.ui.spnYmin.value()
            xmax = self.ui.spnXmax.value()
            ymax = self.ui.spnYmax.value()
            xdiff = xmax - xmin
            ydiff = ymax - ymin
            if self.ui.rdoHexagon.isChecked():
                if self.ui.rdoArea.isChecked():
                    sideLen = self.CalculateHexagonSideLength(self.ui.spnUnitArea.value())
                    tarea = float(self.ui.spnUnitArea.value())
                else:
                    sideLen = float(self.ui.spnSideLength.value())
                    tarea = float(sideLen)**2 * math.sqrt(3)/4
                # basic trig needed to calculate effective length
                angle_a = math.radians(30)
                hyp = sideLen
                side_b = hyp * math.cos(angle_a)
                side_a = hyp * math.sin(angle_a)
                cellcount = ((xdiff + sideLen)/(2 * side_b)) * (((ydiff+side_b)/(sideLen + side_a))+1)
            else:
                if self.ui.rdoArea.isChecked():
                    sideLen = math.sqrt(float(self.ui.spnUnitArea.value()))
                    tarea = float(self.ui.spnUnitArea.value())
                else:
                    sideLen = float(self.ui.spnSideLength.value())
                    tarea = float(self.ui.spnSideLength.value())**2
                cellcount = ((xdiff/sideLen)+1) * ((ydiff/sideLen)+1)
            if cellcount < 100:
                outText = str(int(round(cellcount,-1)))
            elif cellcount < 10000:
                outText = str(int(round(cellcount,-2)))
            elif cellcount < 1000000:
                outText = str(int(round(cellcount,-3)))
            elif cellcount < 100000000:
                outText = str(int(round(cellcount,-4)))
            else:
                outText = str(int(round(cellcount,-5)))
            self.ui.leUnitNumber.setText( QtCore.QString( outText ) )
        except:
            self.ui.leUnitNumber.setText( QtCore.QString( '' ) )
            
    def offset(self, value):
        if self.ui.rdoArea.isChecked():
            self.ui.spnUnitArea.setValue(value)
        self.updateCellCount()

    def updateLayer( self ):
        import ftools_utils
        mLayerName = self.ui.inShape.currentText()
        if not mLayerName == "":
            self.mLayer = ftools_utils.getMapLayerByName( unicode( mLayerName ) )
            boundBox = self.mLayer.extent()
            self.updateExtents( boundBox )
    
    def updateCanvas( self ):
        canvas = self.iface.mapCanvas()
        boundBox = canvas.extent()
        self.updateExtents( boundBox )
    
    def updateExtents( self, boundBox ):
        self.ui.spnXmin.setValue( boundBox.xMinimum() )
        self.ui.spnYmin.setValue( boundBox.yMinimum() )
        self.ui.spnXmax.setValue( boundBox.xMaximum() ) 
        self.ui.spnYmax.setValue( boundBox.yMaximum() )
        self.updateCellCount()

    def accept(self):
        import ftools_utils
        self.ui.buttonOk.setEnabled( False )
        if self.ui.spnXmin.text() == "" or self.ui.spnXmax.text() == "" or self.ui.spnYmin.text() == "" or \
        self.ui.spnYmax.text() == "":
            QtGui.QMessageBox.information(self, self.tr("Planning Grid"), \
            self.tr("Please specify valid extent coordinates"))
        elif self.ui.outShape.text() == "":
            QtGui.QMessageBox.information(self, self.tr("Planning Grid"), \
            self.tr("Please specify output shapefile"))
        else:
            try:
                boundBox = QgsRectangle(
                float( self.ui.spnXmin.value() ),
                float( self.ui.spnYmin.value() ),
                float( self.ui.spnXmax.value() ),
                float( self.ui.spnYmax.value() ) )
            except:
                QtGui.QMessageBox.information(self, self.tr("Planning Grid"), 
                    self.tr("Invalid extent coordinates entered"))
            sideLen = self.ui.spnSideLength.value()
            unitArea = self.ui.spnUnitArea.value()
            if self.ui.rdoHexagon.isChecked