# -*- coding: utf-8 -*-
"""
Copyright (c) 2016 Biuro Urządzania Lasu i Geodezji Leśnej

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), 
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
OTHER DEALINGS IN THE SOFTWARE.
"""

import os
import Mapa_PU
from Mapa_PU.widok.zestawienia_dialog import ZestawieniaDialog
from Mapa_PU.model.biblioteka_dll import Biblioteka
from Mapa_PU.kontroler import komunikaty
from PyQt5.QtWidgets import *
from Mapa_PU.model.baza_danych import Baza
from Mapa_PU.kontroler import rejestr
from Mapa_PU.widok.pasek_wiadomosci import PasekWiadomosc


class Raporty(Biblioteka):
    """Obsługa raportów"""
    def __init__(self,mapa,iface,konfiguracja):
        
        self.can_start = False
        self.mapa = mapa
        self.iface = iface
        self.konfiguracja=konfiguracja
        self.pasekWiadomosc = PasekWiadomosc(self.iface)

        
        if self.mapa.warstwaRejestr('POW'):
            
            self.wybrane_featurey = self.slownikWybranychFeatureow( self.mapa.warstwaRejestr('POW') )
        
            if self.wybrane_featurey:
        
                # musi być rzut na str().
                self.katalogZasobow=rejestr.szukaj_taksator() 
                
                
                if self.katalogZasobow != None:
                                  
                    Biblioteka.__init__(self,self.katalogZasobow)
                    self.zaladujZasob('ReportsHelper')
                    import ReportsHelper
        
                    self.raporty = ReportsHelper.ExternalMethods
                    self.listaRaportow=self.raporty.GetReportList()
                    self.dostepne_raporty = self.slownikDostepnychRaportow()
                    self.katalog_zestawien = ''
                
                    self.can_start = True
                    
                else:
                    self.can_start = False
            else:
                self.can_start = False
                komunikaty.informacja(u'Tworzenie zestawień', u'Proszę zaznaczyć pododdziały (POW), dla których mają być utworzone zestawienia!')
        else:
            komunikaty.blad(u'Tworzenie zestawień', u'Brak Warstwy POW !!!')
            self.can_start = False        
        
    def slownikWybranychFeatureow(self,warstwa):
        """ pobiera obiekt warstwy, zwraca slownik zaznaczonych w oknie mapy feature'ow """
        sel_feats = {}
        if warstwa.isValid() and warstwa.selectedFeatureCount()>0:
            sel_feats = { feat.id() : feat for feat in warstwa.selectedFeaturesIterator() }
        return sel_feats
    
    def listaAtrybutu(self,nazwa_atrybutu="",slownik={}):
        """zwraca liste krotek parametrow do zapytania executemany(sql, *params) w ODBC"""
        lista=[]
        if nazwa_atrybutu and slownik:    
            for id,feat in slownik.items():
                attr_idx = feat.fields().indexFromName(nazwa_atrybutu)
                if attr_idx:
                    lista.append((feat.attributes()[attr_idx],))
        return lista
            
    def slownikDostepnychRaportow(self):
        """Na podstawie listy raportów rozbija każdą pozycję listy na numer raportu i jego nazwe. Symbolem rozdzielajacym jest znak:'-' """
        try:
            reports = {}
            if self.listaRaportow:
                for report in self.listaRaportow: 
                    reports.update({ int(report.split('-')[0].rstrip()) : report.split('-')[1].strip().decode("windows-1250") })  

            return reports    
        except Exception as e:
            komunikaty.blad_systemowy(e)
                        
                             
    def uruchomRaport(self, id, community, destPath, dbFilePath, nazwa):
        """ uruchamia tworzenie raportu przy pomocy metody RunReport z modułu ReportsHelper
            argumenty:  id - numer wewnętrzny raportu
                        community - parametr opcjonalny. Przekazujemy ciąg '9999' by pominąc go przy tworzeniu.
                        destPath - sciezka zapisu pliku raportu
                        dbFilePath - sciezka do pliku bazy danych UPUL.mdb
        """
        try:
            if id and community and destPath and dbFilePath:
                retValue = self.raporty.RunReport(int(id), str(community), str(destPath), str(dbFilePath))

        except Exception as e:
            komunikaty.blad_systemowy(e, u'Nie udało się stworzyć zestawienia "'+nazwa+'" !')
            #komunikaty.blad(u'Tworzenie zestawień', u'Nie udało się stworzyć zestawienia "'+nazwa+'" !')

            
    def generujWybraneZestawienia(self):
        """metoda pełniąca rolę slotu dla obsługi klikniecia przycisku na formatce wyboru zestawień
           dla poprawnej pracy wymaga ustawienia atrybutów :self.katalog_zestawien - sciezka do folderu do zapisu wybranych zestawień,
                                                            self.dostepne_raporty - slownik dostepnych raportow,
                                                            self.qdialog wraz z jego zawartoscią,
                                                            self.konfiguracja.plikBazaTaksator- sciezka do bazy UPUL.mdb
        """
        
        if not self.katalog_zestawien:
            self.wskazKatalogZestawien()
        
        if os.path.isdir(self.katalog_zestawien):
            
            self.progressbar = self.pasekWiadomosc.utworzPasekPostepu(opis='Tworzenie Zestawień')
              
            _licznik_pasek = 0
            _liczba_raportow = len(self.dostepne_raporty)
            
            tak_na_wszystkie = False
            for id,nazwa_raportu in self.dostepne_raporty.items():   
                if self.qdialog.findChild(QCheckBox,str(id)).isChecked():
                    
#                     sciezka_pliku_raportu = os.path.normpath(os.path.join(self.katalog_zestawien, nazwa_raportu+'.xls').replace(" ", "_"))
                    sciezka_pliku_raportu = os.path.normpath(os.path.join(self.katalog_zestawien,nazwa_raportu.replace(" ","_")+'.xls')) 
                    
                    if os.path.exists(sciezka_pliku_raportu) and not tak_na_wszystkie:
                        
                        qbox_plik = QMessageBox()
                        qbox_plik.setIcon(QMessageBox.Question)
                        qbox_plik.setWindowIcon(QIcon('%s\\ikony\\Logo_BULiGL.ico' % Mapa_PU.upul_modul.root))
                        qbox_plik.setText( u"Zestawienie \"" + nazwa_raportu + u"\" już istnieje ! \n Czy nadpisać istniejący plik ?" )
                        qbox_plik.setWindowTitle(u"Plik już istnieje !")
                        
                        pbutton_accept = qbox_plik.addButton( u"Tak",QMessageBox.AcceptRole )
                        pbutton_accept.setDefault(True)
                        pbutton_yesall = qbox_plik.addButton( u"Tak na wszystkie", QMessageBox.YesRole )
                        pbutton_no = qbox_plik.addButton( u"Nie",QMessageBox.NoRole )
                        pbutton_reject = qbox_plik.addButton( u"Anuluj",QMessageBox.RejectRole )

                        qbox_plik.exec_()
                        
                        if qbox_plik.clickedButton() == pbutton_accept:
                            self.uruchomRaport(id, "9999", sciezka_pliku_raportu.encode("windows-1250"), self.konfiguracja.plikBazaTaksator, nazwa_raportu )
                            
                        elif qbox_plik.clickedButton() == pbutton_yesall:
                            self.uruchomRaport(id, "9999", sciezka_pliku_raportu.encode("windows-1250"), self.konfiguracja.plikBazaTaksator, nazwa_raportu )
                            tak_na_wszystkie = True
                            
                        elif qbox_plik.clickedButton() == pbutton_no:
                            pass
                            
                        elif qbox_plik.clickedButton() == pbutton_reject:
                            break
                    
                    else:
                        self.uruchomRaport(id, "9999", sciezka_pliku_raportu.encode("windows-1250"), self.konfiguracja.plikBazaTaksator, nazwa_raportu )
                    
                    _licznik_pasek += round(100/_liczba_raportow)
                    self.progressbar.setValue(_licznik_pasek)

            # usuniecie paska Progress Bar
            self.pasekWiadomosc.clear()
                    
            komunikaty.informacja( u'Tworzenie zestawień',u'Tworzenie wybranych zestawień zostało zakończone. Proszę sprawdzić zawartość katalogu : ' +self.katalog_zestawien )
        else:
            komunikaty.blad(u'Tworzenie zestawień', u'Nie wybrano poprawnego katalogu !')
            self.uruchomDialog()
            
    def wskazKatalogZestawien(self):
        """wybór katalogu do zapisu zestawien"""
        self.katalog_zestawien = QFileDialog.getExistingDirectory(self.iface.mainWindow(),u'Wybierz katalog do zapisu zestawień','C:\\')
        if os.path.isdir(self.katalog_zestawien):
            return self.katalog_zestawien
        else:
            return '' 

        
    def uruchomDialog(self):
        
        self.qdialog = ZestawieniaDialog()
        self.qdialog.raporty = self
        self.qdialog.wypelnijQDialog(slownik_raportow = self.dostepne_raporty)
        self.qdialog.exec_()
        
        
    def run(self):
        
        """ punkt wejsciowy dla klasy Raporty.
            Na podstawie listy zaznaczonych obiektów na warstwie POW ustawia znacznik TEMP_RAPORT w tabeli F_ARODES na 0 a następnie znaczy rekordy według listy zaznaczenia.
            Uruchamia wypełnienie okna dialogowego listą dostępnych raportów.  
        """
         
        if self.mapa.warstwaRejestr('POW'):
                
                lista_atrybutow_w_pow = self.listaAtrybutu(nazwa_atrybutu='ADR_BDL', slownik = self.slownikWybranychFeatureow(self.mapa.warstwaRejestr('POW') ) )                
                baza = Baza(self.konfiguracja.plikBazaTaksator)
                baza.polaczOdbc()
                        
                #zeruje znacznik do raportow.
                baza.wykonajZapytanieModyfikacja("UPDATE F_ARODES SET F_ARODES.TEMP_RAPORT=0;")
                
                #znaczymy rekordy w F_ARODES po wartosciach ADR_BDL = ADRESS_FOREST.     
                baza.wykonajWieleZapytan(zapytanie="UPDATE F_ARODES SET F_ARODES.TEMP_RAPORT=1 WHERE ADRESS_FOREST = ?",parametry=lista_atrybutow_w_pow)
                baza.zamknijPolaczenie() 
            
                self.uruchomDialog()

        else:
            komunikaty.blad(u'Tworzenie zestawień', u'Brak Warstwy POW !!!')
    