#-*- coding: utf-8 -*-

# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import os

from .. import qt

from .more import LabelWordWrap, FileOpenWgt, show_msg, show_question, \
                 client_list_methods, get_icon, dpivalue

class ToolsWidget (qt.QWidget):
    def __init__(self, parent, ClientObj, window):
        super().__init__()
        self.vlayout = qt.QVBoxLayout(self)
        self.vlayout.setAlignment(qt.Qt.AlignTop)
        self.vlayout.setAlignment(qt.Qt.AlignRight)

#        self.move(100+parent.frameGeometry().x(), \
#                          100+parent.frameGeometry().y())

        self.setFixedSize(dpivalue(450), 100 + dpivalue(120))
        self.setWindowTitle(_('Preferences'))

        self.setWindowIcon(get_icon("preferences-other"))
        # for clear memory after closed this window
        self.setWindowModality(qt.Qt.WindowModal)
        self.setAttribute(qt.Qt.WA_DeleteOnClose)

        self.create(parent, ClientObj)

        self.move(window.geometry().x() + window.geometry().width() / 2 \
                  - self.size().width() / 2, \
                  window.geometry().y() + window.geometry().height() / 2 \
                  - self.size().height() / 2)
    gui_signal = qt.Signal()
    other_signal = qt.Signal()

    def create(self, parent, ClientObj):
        if self.layout():
            for i in range(self.layout().count()):
                child = self.layout().takeAt(0)
                child.widget().hide()
                child.widget().destroy()
                del (child)            

        # Add clear config button
        clear_button = qt.QPushButton(get_icon("edit-delete-page"),
                                      _('Clear the configuration file'),self)
        clear_button.clicked.connect(self.clear_config(parent, ClientObj))

        self.vlayout.addWidget(clear_button)

        tab = ToolTabWidget(self, ClientObj)
        tab.resize(tab.sizeHint())
        self.vlayout.addWidget(tab)

        # add ok, apply and cancel button
        botton_wgt = qt.QWidget(self)
        self.botton_layout = qt.QHBoxLayout(botton_wgt)
        self.botton_layout.setContentsMargins(0,0,0,0)
        self.botton_layout.setAlignment(qt.Qt.AlignRight)

        toolOk = qt.QPushButton(_('Ok'), self)
        toolOk.setShortcut(qt.QKeySequence(qt.Qt.Key_Return))
        toolOk.clicked.connect(self.save_changes(ClientObj, tab))
        toolOk.clicked.connect(self.close)
        self.botton_layout.addWidget(toolOk)

        toolApply = qt.QPushButton(_('Apply'), self)
        toolApply.clicked.connect(self.save_changes(ClientObj, tab))
        self.botton_layout.addWidget(toolApply)

        toolQuit = qt.QPushButton(_('Cancel'), self)
        toolQuit.clicked.connect(self.close)
        toolQuit.setShortcut(qt.QKeySequence(qt.Qt.Key_Escape))
        self.botton_layout.addWidget(toolQuit)

        self.gui_signal.connect(tab.GuiWidget.save_changes(ClientObj))
        self.other_signal.connect(tab.OtherWidget.save_changes(ClientObj))
#        self.grid.addWidget(botton_wgt, 6, 1)

        self.vlayout.addWidget(botton_wgt)

#        clear_button.setMaximumWidth(self.sizeHint().width() / 2)
        clear_button.setMaximumWidth(dpivalue(220))

    def save_changes(self, ClientObj, tab):
        def wrapper():
            if type (tab.currentWidget()) == ToolGui:
                self.gui_signal.emit()
            else:
                self.other_signal.emit()
        return wrapper

    def clear_config(self, parent, ClientObj):
        def wrapper():
            try:
#            fc = open (ClientObj.user_config, 'w')
#            fc.close()
                os.remove(ClientObj.user_config)
                ClientObj.create_user_config()
                ClientObj.read_user_config(ClientObj.user_config)
            except Exception as e:
                show_msg (e, 'Clear Config Error')
            finally:
                self.create(parent, ClientObj)
        return wrapper

class ToolTabWidget(qt.QTabWidget):
    def __init__(self, parent, ClientObj):
        super().__init__(parent)
        self.ClientObj = ClientObj

        self.GuiWidget = ToolGui(self, ClientObj)

        self.OtherWidget = ToolOther(self, ClientObj)

        self.gui_icon = get_icon("video-display")

        self.other_icon = get_icon("preferences-other", "preferences-desktop")

        self.addTab(self.GuiWidget, self.gui_icon ,_('GUI'))
        self.addTab(self.OtherWidget, self.other_icon, _('Other'))

        # message about save
        self.cur_tab_num = 0
        self.changed_flag = False
        self.currentChanged.connect(self.save_mess)

        self.setAttribute(qt.Qt.WA_DeleteOnClose)

    gui_signal = qt.Signal()
    other_signal = qt.Signal()

    def save_mess(self, tab_num):
        # change tab with unsaved changes
        tab_list = [_('GUI'),_('Other')]

        if self.changed_flag:
            text = _('There are unsaved changes in tab %s') \
                                    %tab_list[self.cur_tab_num]
            informative_text = _('<center>Apply them?</center>')

            reply = show_question(self.parent(), text, informative_text,
                                  title = _('Saving changes'))

            if reply == qt.QMessageBox.Yes:
                if self.cur_tab_num == 0:
                    self.gui_signal.connect \
                                  (self.GuiWidget.save_changes(self.ClientObj))
                    self.gui_signal.emit()
                elif self.cur_tab_num == 1:
                    self.other_signal.connect \
                                (self.OtherWidget.save_changes(self.ClientObj))
                    self.other_signal.emit()

            self.changed_flag = False
            self.removeTab(self.cur_tab_num)

            if self.cur_tab_num == 0:
                self.GuiWidget = ToolGui(self, self.ClientObj)
                self.insertTab(self.cur_tab_num, self.GuiWidget, \
                                            self.gui_icon, _('GUI'))
            elif self.cur_tab_num == 1:
                self.OtherWidget = ToolOther(self, self.ClientObj)
                self.insertTab(self.cur_tab_num, self.OtherWidget, \
                                        self.other_icon, _('Other'))

        self.cur_tab_num = tab_num
        self.changed_flag = False

# Gui tools in ToolTabWidget
class ToolGui(qt.QWidget):
    def __init__(self, parent, ClientObj):
        super().__init__(parent)
        self.user_config = ClientObj.user_config
        self._parent = parent

        self.grid = qt.QGridLayout(self)

        self.grid.setContentsMargins(2,2,2,2)
        self.grid.setSpacing(2)
        self.grid.setColumnStretch(0,3)
        self.grid.setColumnStretch(1,5)
#        self.grid.setAlignment(qt.Qt.AlignLeft)

        # add height image in grid
        self.h_image_lbl = LabelWordWrap(_('Image height'), self)
        self.h_image_lbl.setMaximumWidth(self.h_image_lbl.sizeHint().width())

        self.h_image_lineedit = qt.QLineEdit(self)
        self.h_image_lineedit.setToolTip(_('Set a fixed height image for '
                                         'actions')+' '+_('0: hide images'))

        self.h_image_lineedit.setText(str(ClientObj.height_image))

        self.grid.addWidget(self.h_image_lbl, 0, 0)
        self.grid.addWidget(self.h_image_lineedit, 0, 1)

        # add count item in result table in grid
        self.count_row_lbl = LabelWordWrap(_('Rows in Table'),self)
        self.count_row_lbl.setMaximumWidth \
                                    (self.count_row_lbl.sizeHint().width())

        self.count_row_lineedit = qt.QLineEdit(self)

        self.count_row_lineedit.setText(str(ClientObj.count_row_res_table))

        self.grid.addWidget(self.count_row_lbl, 2, 0)
        self.grid.addWidget(self.count_row_lineedit, 2, 1)

        # add spacer
        self.grid.addItem(qt.QSpacerItem(0,0, qt.QSizePolicy.Expanding, \
                          qt.QSizePolicy.Expanding ), 3, 0, 1, 2)

        # connect all with change value slot
        self.h_image_lineedit.textChanged.connect(self.changed_val)
        self.count_row_lineedit.textChanged.connect(self.changed_val)

    def changed_val(self):
        self._parent.changed_flag = True

    def set_opacity_lbl(self, val):
        self.opacity_lbl.setText(self.opacity_lbl_text + str(val))

    def check_cfg (self, flag, config, part, param, value):
        # if param not exists in config
        if not flag:
            part_flag = False
            temp_cfg = []
            for line in config:                    
                temp_cfg.append(line)
                #add new line in config
                if line.startswith(part):
                    temp_cfg.append('%s = %s\n' %(param, value))
                    part_flag = True

            config = temp_cfg
            # if part not exists
            if not part_flag:
                config.append('\n')
                config.append('%s\n' %part)
                config.append('%s = %s\n' %(param, value))
        return config

    def save_changes(self, ClientObj):
        def wrapper():
            if not os.path.isfile (self.user_config):
                f = open (self.user_config, 'w')
                f.close()

            fc = open (self.user_config, 'r')
            config = fc.readlines()
            fc.close()
            new_config = []

#            bg_color_flag = False
            count_row_flag = False
            count_row_flag = False
            h_image_flag = False

            for line in config:
                if line.startswith('height_image '):
                    h_image_flag = True
                    try:
                        height_image = int(self.h_image_lineedit.text())
                    except ValueError:
                        height_image = ClientObj.height_image
                    if height_image < 0 or height_image > 512:
                        height_image = ClientObj.height_image
                    new_config.append('height_image = %d\n' %height_image)
                elif line.startswith('count_row '):
                    count_row_flag = True
                    try:
                        count_row = int(self.count_row_lineedit.text())
                        if count_row < 2:
                            count_row = 2
                    except ValueError:
                        count_row = ClientObj.count_row_res_table
                    new_config.append('count_row = %d\n' %count_row)
                else:
                    new_config.append(line)

            try:
                count_row = int(self.count_row_lineedit.text())
                if count_row < 2:
                    count_row = 2
            except ValueError:
                count_row = ClientObj.count_row_res_table
            new_config = self.check_cfg (count_row_flag, new_config, \
                                '[gui]', 'count_row', count_row)

            try:
                height_image = int(self.h_image_lineedit.text())
            except ValueError:
                height_image = ClientObj.height_image
            if height_image < 0 or height_image > 512:
                height_image = ClientObj.height_image
            new_config = self.check_cfg (h_image_flag, new_config, \
                                '[gui]', 'height_image', height_image)

            fnc = open(self.user_config, 'w')
            for line in new_config:
                fnc.write(line)
            fnc.close()

            # read config for changed parameters
            ClientObj.create_user_config()
            ClientObj.read_user_config(ClientObj.user_config)
            
            # reset unsaved changes flag
            self._parent.changed_flag = False
        return wrapper

# Other tools in ToolTabWidget
class ToolOther(qt.QWidget):
    def __init__(self, parent, ClientObj):
        super().__init__(parent)
        self.user_config = ClientObj.user_config
        self._parent = parent

        self.grid = qt.QGridLayout(self)

        self.grid.setContentsMargins(2,2,2,2)
        self.grid.setSpacing(2)
        self.grid.setColumnStretch(0,3)
        self.grid.setColumnStretch(1,5)

        # lang settings
        self.lang_lbl = LabelWordWrap(_('Select Language'), self)
        self.lang_lbl.setMaximumWidth(self.lang_lbl.sizeHint().width())

        self.lang_ComboBox = qt.QComboBox(self)
        lang_dict = {'en': _('English'),'ru': _('Russian'),'fr':_('French'),
            'uk':_('Ukrainian')}

        for lang in lang_dict:
            self.lang_ComboBox.addItem(lang_dict[lang])
            self.lang_ComboBox.setItemData(self.lang_ComboBox.count()-1,lang)
            if ClientObj.lang == lang:
                self.lang_ComboBox.setCurrentIndex \
                                               (self.lang_ComboBox.count()-1)

        #add lang settings in grid
        self.grid.addWidget(self.lang_lbl,0,0)
        self.grid.addWidget(self.lang_ComboBox,0,1)

        # add open file in grid
        self.cert_path_lbl = LabelWordWrap(_('Path to Certificates'), self)
        self.cert_path_lbl.setMaximumWidth \
                                      (self.cert_path_lbl.sizeHint().width())

        self.fd_cert = FileOpenWgt(self, 'dir', _('Certificate Directory'), \
                                   '~/.calculate')

        self.fd_cert.setToolTip(_('Empty to default path'))
        self.fd_cert.setText(ClientObj.path_to_cert)

        self.grid.addWidget(self.cert_path_lbl, 1, 0)
        self.grid.addWidget(self.fd_cert, 1, 1)

#        # add timeout in grid
#        self.timeout_lbl = LabelWordWrap(_('Timeout'), self)
#        self.timeout_lbl.setMaximumWidth(self.timeout_lbl.sizeHint().width())
#
#        self.timeout_lineedit = qt.QLineEdit(self)
#
#        self.timeout_lineedit.setText(str(ClientObj.timeout))
#
#        self.grid.addWidget(self.timeout_lbl, 2, 0)
#        self.grid.addWidget(self.timeout_lineedit, 2, 1)

        # add spacer
        self.grid.addItem(qt.QSpacerItem(0,0, qt.QSizePolicy.Expanding, \
                                qt.QSizePolicy.Expanding ), 5, 0, 1, 2)

        # connect all with change value slot
        self.lang_ComboBox.currentIndexChanged.connect(self.changed_val)
        self.fd_cert.textChanged.connect(self.changed_val)
#        self.timeout_lineedit.editTextChanged.connect(self.changed_val)

        self.setAttribute(qt.Qt.WA_DeleteOnClose)

    def changed_val(self):
        self._parent.changed_flag = True

    def check_cfg (self, flag, config, part, param, value):
        # if param not exists in config
        if not flag:
            part_flag = False
            temp_cfg = []
            for line in config:                    
                temp_cfg.append(line)
                #add new line in config
                if line.startswith(part):
                    temp_cfg.append('%s = %s\n' %(param, value))
                    part_flag = True

            config = temp_cfg
            # if part not exists
            if not part_flag:
                config.append('\n')
                config.append('%s\n' %part)
                config.append('%s = %s\n' %(param, value))
        return config

    def save_changes(self, ClientObj):
        def wrapper():
            if not os.path.isfile (self.user_config):
                f = open (self.user_config, 'w')
                f.close()

            fc = open (self.user_config, 'r')
            config = fc.readlines()
            fc.close()
            new_config = []

            lang_flag = False
            cert_flag = False
#            timeout_flag = False
            for line in config:
                if line.startswith('lang '):
                    lang_flag = True
                    new_config.append('lang = %s\n' \
                                %self.lang_ComboBox.itemData \
                                (self.lang_ComboBox.currentIndex()))
                elif line.startswith('path_to_cert '):
                    cert_flag = True
                    if os.path.isdir(self.fd_cert.text()):
                                    new_config.append('path_to_cert = %s\n' \
                                    %self.fd_cert.text())
                    elif not self.fd_cert.text():
                                    new_config.append('path_to_cert = no\n')
                    else:
                        new_config.append(line)
#                elif line.startswith('timeout '):
#                    timeout_flag = True
#                    try:
#                        timeout = int(self.timeout_lineedit.text())
#                    except ValueError:
#                        timeout = ClientObj.timeout
#                    new_config.append('timeout = %d\n' %timeout)
                else:
                    new_config.append(line)

            new_config = self.check_cfg (lang_flag, new_config, \
                              '[other]', 'lang', self.lang_ComboBox.itemData \
                              (self.lang_ComboBox.currentIndex()))

            if not self.fd_cert.text().lower():
                new_config = self.check_cfg (cert_flag, new_config, \
                                '[other]', 'path_to_cert', 'no')
            elif os.path.isdir(self.fd_cert.text()):
                new_config = self.check_cfg (cert_flag, new_config, \
                              '[other]', 'path_to_cert', self.fd_cert.text())

#            try:
#                timeout = int(self.timeout_lineedit.text())
#            except ValueError:
#                timeout = ClientObj.timeout
#            new_config = self.check_cfg (timeout_flag, new_config, \
#                                '[other]', 'timeout', timeout)

            fnc = open(self.user_config, 'w')
            for line in new_config:
                fnc.write(line)
            fnc.close()

            # read config for changed parameters
            ClientObj.create_user_config()
            ClientObj.read_user_config(ClientObj.user_config)

            # reset unsaved changes flag
            self._parent.changed_flag = False
            if ClientObj.client:
                from .session_function import client_post_cert
                ClientObj.lang = self.lang_ComboBox.itemData \
                                           (self.lang_ComboBox.currentIndex())
                if ClientObj.client:
                    try:
                        client_post_cert(ClientObj.client, ClientObj.lang)
                    except:
                        return
                    ClientObj.methods_list = client_list_methods \
                                            (ClientObj.sid, ClientObj.client)
                    from .DisplayMethod import DisplayMethod
                    if type (ClientObj.MainWidget.MainFrameWgt) \
                                                            == DisplayMethod:
                        ClientObj.MainWidget.display_methods()
        return wrapper
