import os
import traceback
#import logging
from pathlib import Path

import axipy
from PySide2.QtCore import QObject, Signal
from PySide2.QtWidgets import QFileDialog
from axipy.app import Notifications
from loguru import logger

from LoadMiWor.ui.processTool.parserWor.clsLayout import miWorLayout, miWorLayoutDesigner
from LoadMiWor.ui.processTool.parserWor.clsLegend import MiLegend
from LoadMiWor.ui.processTool.parserWor.clsLegendView import LegendeView
from LoadMiWor.ui.processTool.parserWor.clsMiMap import MiMap
from LoadMiWor.ui.processTool.parserWor.clsTableView import BrowseTable
from LoadMiWor.ui.processTool.parserWor.clsTables import MiTable
from LoadMiWor.ui.processTool.utils import removeLn, prepareWor, normWorLine, buildTree
import time

class ProcessLoadWor(QObject):
    updateProcess = Signal(float)
    updateFormatProgressBar=Signal(str)
    finished = Signal(int)
    def __init__(self,name_prosess,parent_class):
        self.__last_folder=None
        self.__name_process=name_prosess

        super(ProcessLoadWor, self).__init__()
        self.__parent=parent_class
        self.__erorr_message=None
    def setParams(self,params):
        self.__params=params
    def __isCancel(self):
        self.__cancelProcess=True
    def setCancel(self):
        self.__cancelProcess=True
    def __process_callback(self,complete, message=None, user_data=None):
        #print('progress: {}, message: "{}", unknown {}'.format(complete, message,user_data))
        if self.__cancelProcess:
            return 0
        self.updateProcess.emit(complete*100)
        time.sleep(0.001)
        #logging.debug(" update progress bar "+str(complete*100))
        #self.__parent.window.pr_bar.setValue(complete*100)
        #print(complete*100)
        return 1
    def __parseTreeWor(self):
        folder_wor=Path(self.__path_wor).parent
        cls_tables=MiTable(folder_wor)
        list_miMap=[]
        list_layout=[]
        curent_miMap=None
        size_tree=len(self.__level_tree)
        curent_layout=None
        for index_record,item_tree in enumerate(self.__level_tree):
            is_cancel=self. __process_callback(index_record/size_tree)
            if is_cancel==0:
                #logging.debug(("send send cancel"))
                break
            if item_tree['key'].lower()=='open' and item_tree['words'][1].lower()=='table':
                ''' Open Table '''

                isOk,path_tab,alias_tab=cls_tables.add(item_tree,self.__lines_new)
                if not isOk and path_tab is not None:
                    ''' Пытаемся открыть из последнего folder'''


                    if self.__last_folder is not None:
                        #print("Last Folder:" + str(self.__last_folder))
                        new_path=self.__last_folder.joinpath(Path(path_tab).name)
                        #print(str(new_path))
                        if new_path.exists():
                            cls_tables.add(item_tree, self.__lines_new, str(new_path))
                            continue
                        lin_path=str(new_path).replace(".tab",".TAB")
                        if Path(lin_path).exists():
                            cls_tables.add(item_tree, self.__lines_new, str(lin_path))
                            continue
                    file_name = QFileDialog.getOpenFileName(axipy.app.mainwindow.qt_object(), "Таблица не найдена: "+path_tab, path_tab, "MapInfo Tab (*.tab *.TAB)")[0]
                    if not file_name:
                        Notifications.push('Загрузка wor', 'Не найдена таблица '+path_tab, Notifications.Critical)
                        return
                    self.__last_folder=Path(file_name).parent
                    isOk=True
                    path_tab=file_name
                    cls_tables.add(item_tree,self.__lines_new,file_name)
                continue
            if item_tree['key'].lower() == 'select':
                ''' Таблица select '''
                isOk,_=cls_tables.addSelect(item_tree,self.__lines_new)
            if item_tree['key'].lower()=='map':
                if curent_miMap is not None and isinstance(curent_miMap,MiMap):
                    if curent_miMap is not None:
                        list_miMap.append(curent_miMap)
                curent_miMap=MiMap(item_tree,self.__lines_new,cls_tables)
                if curent_layout is not None:
                    curent_layout.add(curent_miMap)
            if item_tree['key'].lower()=='set':
                second_key=item_tree['words'][1].lower()
                if second_key=='window' and curent_miMap is not None:
                    if item_tree['words'][2].lower()=='uniquelayoutwin':
                        ''' Устаналивается активным окно отчета'''
                        if curent_miMap is not None and isinstance(curent_miMap, MiMap):
                            list_miMap.append(curent_miMap)
                            curent_miMap=None
                            continue
                    curent_miMap.setMapWinProperty(item_tree)
                    continue
                if second_key=='map':
                    if curent_miMap is not None:
                        logger.debug("Parset Set Map")
                        curent_miMap.setMap(item_tree)
                    continue
                if second_key=='coordsys':
                    ''' Устанавливается текущая координатная система'''
                    if curent_miMap is not None:

                        curent_miMap.setCurentCoordSystem(self.__lines_new[item_tree['index']])
                    continue
                if second_key=='legend':
                    ''' Легенда '''
                    mi_legende=MiLegend()
                    mi_legende.create(item_tree,self.__lines_new)
                    curent_miMap.addLegend(mi_legende)
                    continue
            if  item_tree['key'].lower()=='create':
                '''
                if len(item_tree['words'])>4 and item_tree['words'][2].lower()=='into' and item_tree['words'][3].lower()=='window' :
                    # Возможно добавление обекста в отчет
                    if curent_layout is not None:
                        curent_layout.addGeometry(item_tree)
                else:
                    if curent_miMap is not None:
                        #Создание объектов на слое 
                        curent_miMap.createObj(item_tree)
                '''
                if curent_miMap is not None:
                    # Создание объектов на слое
                    curent_miMap.createObj(item_tree)
                else:
                    if curent_layout is not None:
                        curent_layout.addGeometry(item_tree)
                try:
                    if (item_tree['words'][1].lower()=='designer' and item_tree['words'][2].lower()=='legend') or (item_tree['words'][1].lower()=='cartographic' and item_tree['words'][2].lower()=='legend'):
                        ''' Окно легенды '''
                        if len(curent_miMap.Legends)==0:
                            logger.info("Error Create Legen Windows not find legends in Map")
                            continue
                        LegendeView().create(item_tree,self.__lines_new,curent_miMap)
                except Exception as ex:
                    pass
            if item_tree['key'].lower()=='shade':
                ''' Тематика '''
                curent_miMap.addTheme(item_tree)
            if item_tree['key'].lower()=='layout':
                ''' отчет '''
                if curent_miMap is not None and isinstance(curent_miMap,MiMap):
                    list_miMap.append(curent_miMap)
                #if curent_miMap is not None and isinstance(curent_miMap,miWorLayout):
                #    list_layout.append(curent_miMap)
                curent_miMap=None
                isDesiner=False
                try:
                    isDesiner=item_tree['words'][1].lower()=='designer'
                except:
                    pass
                if isDesiner:
                    curent_layout=miWorLayoutDesigner(item_tree,self.__lines_new)
                else:
                    curent_layout=miWorLayout(item_tree,self.__lines_new)
                list_layout.append(curent_layout)
            if item_tree['key'].lower()=='browse':
                ''' Таблица списком'''
                #tableView=BrowseTable.openBroseTable(self.__level_tree,index_record,self.__lines_new)
                tableView=BrowseTable(self.__level_tree,index_record,self.__lines_new)
                if curent_layout is not None:
                    curent_layout.add(tableView)
        if curent_miMap is not None and isinstance(curent_miMap,MiMap):
            list_miMap.append(curent_miMap)
        '''
        if curent_miMap is not None and isinstance(curent_miMap,miWorLayout):
            list_layout.append(curent_miMap)
        '''
        for layout in list_layout:

            layout.fillLayout()
        path_obj_path_out_mws=Path(self.__path_wor)
        name=path_obj_path_out_mws.stem
        path_obj_out_mws=path_obj_path_out_mws.parent.joinpath(name+".mws")
        out_path_mws = str(path_obj_out_mws)
        if path_obj_out_mws.exists():
            os.remove(out_path_mws)


        axipy.Workspace().save_file(out_path_mws)
        logger.info("End parser wor")
        self.updateProcess.emit(100)
    def run(self):
        try:
            self.__parent.disconnect(self.__isCancel)
        except:
            pass
        self.__parent.cancelProcess.connect(self.__isCancel)
        self.__cancelProcess=False
        self.__path_wor=self.__params['source']
        lines_source=None
        self.updateFormatProgressBar.emit("Чтение рабочего набора .. %p%")
        self.updateProcess.emit(0)
        with open(self.__path_wor, encoding='cp1251') as file:
            lines = file.readlines()
        self.updateFormatProgressBar.emit("Подготовка wor (step 1) .. %p%")
        self.__lines_new=removeLn(lines)
        self.updateFormatProgressBar.emit("Подготовка wor (step 2) .. %p%")
        prepar_tree=prepareWor(self.__lines_new)
        self.updateFormatProgressBar.emit("Подготовка wor (step 3) .. %p%")
        normWorLine(self.__lines_new,prepar_tree)
        self.updateFormatProgressBar.emit("Создание иерархического дерева .. %p%")
        self.__level_tree=buildTree(prepar_tree)
        self.updateFormatProgressBar.emit("Импорт wor .. %p%")
        self.updateProcess.emit(0)
        try:

            self.__parseTreeWor()
        except Exception as ex:
            self.__cancelProcess=True
            logger.exception("Ошибка загрузки Wor")
            print(str(traceback.format_exc()))
            Notifications.push("Ошибка",str(ex),Notifications.Critical)
        if self.__cancelProcess:
            self.finished.emit(0)
            return
        self.finished.emit(100)
        return

