#!/usr/bin/env python
#-*- coding: UTF-8 -*-

__author__ = 'helljump'

from PyQt4 import QtGui
from PyQt4 import QtCore
import logging
import startup
import re
from ui.search_ui import Ui_Dialog as DLG1
from ui.dialog_table_ui import Ui_Dialog as DLG2
import transaction
from utils import MyProgressDialog


log = logging.getLogger(__name__)


class DocumentsModel(QtCore.QAbstractTableModel):

    def __init__(self, found, parent):
        super(DocumentsModel, self).__init__(parent)
        self.labels = [u'Заголовок', u'Текст']
        self._data = found

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self._data)

    def columnCount(self, parent=QtCore.QModelIndex()):
        return len(self.labels)

    def headerData(self, section, orientation, role):
        egg = QtCore.QVariant()
        if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
            egg = QtCore.QVariant(self.labels[section])
        elif orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole:
            egg = QtCore.QVariant(section + 1)
        return egg

    def flags(self, index):
        egg = QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled
        return egg

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if not index.isValid():
            return None
        item = self._data[index.row()]
        ndx = index.column()
        egg = QtCore.QVariant()
        if role == QtCore.Qt.DisplayRole:
            if ndx == 0:
                egg = item.title
            elif ndx == 1:
                egg = item.text[:50]
        elif role == QtCore.Qt.UserRole + 1:
            return item
        return egg


class DialogTable(QtGui.QDialog, DLG2):

    def __init__(self, found, parent=None):
        super(DialogTable, self).__init__(parent)
        self.setupUi(self)
        if startup.CFG.contains('search/geometry'):
            self.restoreGeometry(startup.CFG.value('search/geometry').toByteArray())
        self.tableView.setModel(DocumentsModel(found, parent))

    def closeEvent(self, evt):
        log.debug('close event')
        startup.CFG.setValue('search/geometry', self.saveGeometry())
        evt.accept()

    @QtCore.pyqtSlot(QtCore.QModelIndex)
    def on_tableView_doubleClicked(self, index):
        log.debug('select doc')
        self.doc = self.tableView.model().data(index, QtCore.Qt.UserRole + 1)
        self.setResult(1)
        self.hide()


class Dialog(QtGui.QDialog, DLG1):

    def __init__(self, project, parent=None):
        super(Dialog, self).__init__(parent)
        self.setupUi(self)
        self.prefs = allprefs = project.root()['prefs']
        myprefs = allprefs.get('search', {})
        self.search_te.setPlainText(myprefs.get('search', ''))
        self.replace_te.setPlainText(myprefs.get('replace', ''))
        self.regex_cb.setChecked(myprefs.get('regex', False))

    @QtCore.pyqtSlot()
    def on_replace_pb_clicked(self):
        log.debug('replace')
        self.save()
        self.setResult(2)
        self.hide()

    @QtCore.pyqtSlot()
    def on_search_pb_clicked(self):
        log.debug('search')
        self.save()
        self.setResult(1)
        self.hide()

    def save(self):
        self.prefs['search'] = {
            'search': unicode(self.search_te.toPlainText()),
            'replace': unicode(self.replace_te.toPlainText()),
            'regex': self.regex_cb.isChecked()
        }
        transaction.commit()


def process(prj, parent=None):
    dlg = Dialog(prj, parent)
    mode = dlg.exec_()
    if not mode:
        return
    search = dlg.prefs['search']['search']
    replace = dlg.prefs['search']['replace']
    regex = dlg.prefs['search']['regex']
    if not regex:
        search = re.escape(search)
    comp = re.compile(search, re.I | re.U | re.M | re.S)
    docs = prj.root()['documents']
    found = []
    pdlg = MyProgressDialog(u'Обработка', u'Поиск' if mode == 1 else u'Поиск и замена', u'Отмена', 0, len(docs), parent=parent)
    pdlg.show()
    for i, doc in enumerate(docs):
        pdlg.set_value(i)
        QtGui.qApp.processEvents()
        if pdlg.wasCanceled():
            transaction.abort()
            break
        if comp.search(doc.title) is None and comp.search(doc.text) is None:
            continue
        found.append(doc)
        if mode == 2:
            doc.title = comp.sub(replace, doc.title)
            doc.text = comp.sub(replace, doc.text)
    else:
        transaction.commit()
    pdlg.close()
    if not found:
        QtGui.QMessageBox.information(parent, u'Поиск', u'Документы с заданными критериями не найдены.')
        return
    dlg = DialogTable(found, parent)
    if dlg.exec_():
        return dlg.doc


if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    root = startup.CONN.root()
    prj = root["projects"][0]
    prj.open()
    process(prj)
    prj.close()
