#coding=utf-8
#Copyright (C) 2015 IDAEA-CSIC
#
#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 
#ITHOUT 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
'''
:copyright: Copyright (C) 2015 IDAEA-CSIC
:authors: V. Velasco Mansilla, L.M. de Vries, A. Nardi, R. Criollo, E. Vázquez Suñé
:contact: enric.vazquez@idaea.csic.es
:license: GPL General Public License, version 2 or any later version (http://opensource.org/licenses/GPL-2.0)
'''
from PyQt4.QtGui import QAction, QIcon

# Initialize Qt resources from file resources.py
import resources.resources
# Import the code for the dialog

import sys
import os.path

class akvaGIS:
    '''
    The AkvaGIS plugin enhances QGIS with hydrochemical and hydrogeological data processing and analysis.
    All reference and measurement data is stored in a SQLite database.
    
    This entry point for the QGIS plugin is the :py:class:`akvaGIS.akvaGIS` class. It takes care of adding toolbar buttons to QGIS and 
    linking them to their respective functionality. 
    The functionality behind each button is called a 'Feature'. Each Feature, with baseclass :py:class:`feature.AKFeature.AKFeature` can either 
    contain other (sub-)Features or/and a form.
     
    There are 3 groups of features:
    
    - General Features
        These are features that deal with the AkvaGIS SQLite database and 
        the related QGIS layers, like create/open/close AkvaGIS database.
    - Hydrochemical Features
        These features manage the selection of geochemical measurements. Different types of 
        plots and maps can be created using the selected samples and measurements. 
    - Hydrogeological Features
        These features manage the selection of hydrogeological measurements to draw plots and maps.
    
    | All database specific settings are managed by the :py:class:`AKSettings.AKSettings` class
    | All the presented forms are based on the :py:class:`form.AKForm.AKForm` class.
    | All the models used in the (table-)views can be found in the :py:mod:`model` module.
    '''
    def __init__(self, iface):
        """
        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        self.allModulesLoaded = True
        from PyQt4.Qt import QMessageBox
        try:
            from PyQt4.Qt import QSqlDatabase
        except ImportError:
            self.allModulesLoaded = False
            QMessageBox.warning(iface.mainWindow(),
                                "Warning",
                                "Make sure that the python PyQt Sql package is installed.")
        try:
            import xlrd
        except ImportError:
            self.allModulesLoaded = False
            QMessageBox.warning(iface.mainWindow(),
                                "Warning",
                                "Make sure that the python xlrd package is installed.")
        try:
            import xlwt
        except ImportError:
            self.allModulesLoaded = False
            QMessageBox.warning(iface.mainWindow(),
                                "Warning",
                                "Make sure that the python xlwt package is installed.")
        if(self.allModulesLoaded):
            self.initAkvaGIS(iface)

    def initAkvaGIS(self, iface):
        from AKSettings import AKSettings
        
        sys.path.append(os.path.dirname(os.path.realpath(__file__)))
        sys.path.append(os.path.normpath((os.path.dirname(os.path.realpath(__file__)) + "/external")))
        
        from feature.AKFeatureCreateDB import AKFeatureCreateDB
        from feature.AKFeatureCloseDB import AKFeatureCloseDB
        from feature.AKFeatureDBManagement import AKFeatureDBManagement

        from feature.AKFeaturePiper import AKFeaturePiper
        from feature.AKFeatureSAR import AKFeatureSAR
        from feature.AKFeatureSBD import AKFeatureSBD
        from feature.AKFeatureStiffPlot import AKFeatureStiffPlot
        from feature.AKFeatureIonicBalance import AKFeatureIonicBalance

        from feature.AKFeatureChemTimePlot import AKFeatureChemTimePlot 
        from feature.AKFeatureHydroTimePlot import AKFeatureHydroTimePlot
        from feature.AKFeatureMapChem import AKFeatureMapChem
        from feature.AKFeatureMapNormative import AKFeatureMapNormative
       
        from feature.AKFeatureMapStiff import AKFeatureMapStiff
#         from feature import OldAKFeatureParameterQuery.AKFeatureParameterQuery
         
        from feature.AKFeatureStatQuimet import AKFeatureStatQuimet
        from feature.AKFeatureEasyQuim import AKFeatureEasyQuim
        from feature.AKFeatureExcelMix import AKFeatureExcelMix       
        
        from feature.AKFeatureSamplesChemistry import AKFeatureSamplesChemistry
        from feature.AKFeatureSamplesHydrogeology import AKFeatureSamplesHydrogeology
        from feature.AKFeatureMapHydro import AKFeatureMapHydro
        from feature.AKFeatureMapHydroSurface import AKFeatureMapHydroSurface

        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        
        self.actions = []
        self.pluginName = u'&AkvaGIS'
        
        self.m_AKSettings = AKSettings(iface)
        self.pluginMenu = self.iface.pluginMenu()
        self.akvaMenu = self.pluginMenu.addMenu(QIcon(self.m_AKSettings.getIconPath('akvaGIS.png')), self.pluginName)
        self.toolbar = self.iface.addToolBar(self.pluginName)
        self.toolbar.setObjectName(self.pluginName)
        
        # Query and DB management group
        self.m_CreateDB = AKFeatureCreateDB(self.m_AKSettings, iface, "create", self.actions)
        self.m_OpenDB = AKFeatureCreateDB(self.m_AKSettings, iface, "open", self.actions)
        self.m_CloseDB = AKFeatureCloseDB(self.m_AKSettings, iface, "close", self.actions)
        self.m_ManageDB = AKFeatureDBManagement(self.m_AKSettings, iface)
        
        # Query samples
        self.m_QuerySamples = AKFeatureSamplesChemistry(self.m_AKSettings, iface)
         
        # Plots
        self.m_Piper = AKFeaturePiper(self.m_AKSettings, iface)
        self.m_SBD = AKFeatureSBD(self.m_AKSettings, iface)      
        self.m_SAR = AKFeatureSAR(self.m_AKSettings, iface)
        self.m_stiffPlot = AKFeatureStiffPlot(self.m_AKSettings, iface)
        self.m_chemTimePlot = AKFeatureChemTimePlot(self.m_AKSettings, iface)
        self.m_IBalance = AKFeatureIonicBalance(self.m_AKSettings, iface)
         
        # Maps        
        self.m_StiffMap = AKFeatureMapStiff(self.m_AKSettings, iface)
        self.m_Map = AKFeatureMapChem(self.m_AKSettings, iface)
        self.m_MapNormative = AKFeatureMapNormative(self.m_AKSettings, iface)        
         
        # Excel tools
        self.m_EasyQuim = AKFeatureEasyQuim(self.m_AKSettings, iface)
        self.m_ExcelMix = AKFeatureExcelMix(self.m_AKSettings, iface)
        self.m_StatQuimet = AKFeatureStatQuimet(self.m_AKSettings, iface)
                
        # Hydro tools
        self.m_HydroSamples = AKFeatureSamplesHydrogeology(self.m_AKSettings, iface)
        self.m_hydroTimePlot = AKFeatureHydroTimePlot(self.m_AKSettings, iface)
        self.m_HydroMap = AKFeatureMapHydro(self.m_AKSettings, iface)
        self.m_HydroMapSurface = AKFeatureMapHydroSurface(self.m_AKSettings, iface)

    def initGui(self):
        """Add all the menu entries and toolbar icons to QGIS."""
        if(self.allModulesLoaded):
            self.add_feature(
                feature=self.m_CreateDB,
                parent=self.iface.mainWindow(),
                enabled=True)
            self.add_feature(
                feature=self.m_OpenDB,
                parent=self.iface.mainWindow(),
                enabled=True)
            self.add_feature(
                feature=self.m_CloseDB,
                parent=self.iface.mainWindow())      
            self.toolbar.addSeparator()          
            self.add_feature(
                feature=self.m_ManageDB,
                parent=self.iface.mainWindow())
            self.add_feature(
                feature=self.m_QuerySamples,
                parent=self.iface.mainWindow())
            self.toolbar.addSeparator()
            self.add_feature(
                feature=self.m_Piper,
                parent=self.iface.mainWindow())
            self.add_feature(
                feature=self.m_SAR,
                parent=self.iface.mainWindow())
            self.add_feature(
                feature=self.m_SBD,
                parent=self.iface.mainWindow())
            self.add_feature(
                feature=self.m_stiffPlot,
                parent=self.iface.mainWindow())
            self.add_feature(
                feature=self.m_chemTimePlot,
                parent=self.iface.mainWindow())        
            self.add_feature(
                feature=self.m_IBalance,
                parent=self.iface.mainWindow())
            self.toolbar.addSeparator()
            self.add_feature(
                feature=self.m_Map,
                parent=self.iface.mainWindow())    
            self.add_feature(
                feature=self.m_MapNormative,
                parent=self.iface.mainWindow())
            self.add_feature(
                feature=self.m_StiffMap,
                parent=self.iface.mainWindow())
            self.toolbar.addSeparator()     
            self.add_feature(
                feature=self.m_EasyQuim,
                parent=self.iface.mainWindow())
            self.add_feature(
                feature=self.m_ExcelMix,
                parent=self.iface.mainWindow())
            self.add_feature(
                feature=self.m_StatQuimet,
                parent=self.iface.mainWindow())
            self.toolbar.addSeparator()
            self.add_feature(
                feature=self.m_HydroSamples,
                parent=self.iface.mainWindow())
            self.add_feature(
                feature=self.m_hydroTimePlot,
                parent=self.iface.mainWindow())  
            self.add_feature(
                feature=self.m_HydroMap,
                parent=self.iface.mainWindow())
            self.add_feature(
                feature=self.m_HydroMapSurface,
                parent=self.iface.mainWindow())

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        if(self.allModulesLoaded):
            for action in self.actions:
                self.iface.removePluginMenu(
                    self.pluginName,
                    action)
                self.iface.removeToolBarIcon(action)

    def add_feature(
        self,
        feature=None,
        parent=None,
        enabled=False):
        """
        Create a QAction and use it for the menu entry and for the toolbar button.
        
        :param feature: The feature provides text, icon and functionality
        :type feature: AKFeature
        :param parent: The parent used for the creation of QAction
        :type parent: QObject
        :param enabled: Is enabled on startup or not
        :type enabled: bool
        """

        icon = feature.m_icon
        text = feature.m_text
        action = QAction(icon, text, parent)
        action.triggered.connect(feature.run)
        action.setEnabled(enabled)
        
        status_tip = "status_tip"
        action.setStatusTip(status_tip)
        whats_this = "whats_this"
        action.setWhatsThis(whats_this)
          
        self.toolbar.addAction(action)        
        self.akvaMenu.addAction(action)

        self.actions.append(action)

        return action
