# compress.py - History compression dialog for TortoiseHg
#
# Copyright 2010 Steve Borho <steve@borho.org>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2, incorporated herein by reference.

from PyQt4.QtCore import *
from PyQt4.QtGui import *

from mercurial import revset

from tortoisehg.hgqt.i18n import _
from tortoisehg.hgqt import csinfo, cmdui, commit, wctxcleaner

BB = QDialogButtonBox

class CompressDialog(QDialog):
    showMessage = pyqtSignal(QString)

    def __init__(self, repoagent, revs, parent):
        super(CompressDialog, self).__init__(parent)
        f = self.windowFlags()
        self.setWindowFlags(f & ~Qt.WindowContextHelpButtonHint)
        self._repoagent = repoagent
        self.revs = revs

        box = QVBoxLayout()
        box.setSpacing(8)
        box.setContentsMargins(*(6,)*4)
        self.setLayout(box)

        style = csinfo.panelstyle(selectable=True)

        srcb = QGroupBox( _('Compress changesets up to and including'))
        srcb.setLayout(QVBoxLayout())
        srcb.layout().setContentsMargins(*(2,)*4)
        source = csinfo.create(self.repo, revs[0], style, withupdate=True)
        srcb.layout().addWidget(source)
        self.layout().addWidget(srcb)

        destb = QGroupBox( _('Onto destination'))
        destb.setLayout(QVBoxLayout())
        destb.layout().setContentsMargins(*(2,)*4)
        dest = csinfo.create(self.repo, revs[1], style, withupdate=True)
        destb.layout().addWidget(dest)
        self.destcsinfo = dest
        self.layout().addWidget(destb)

        self.cmd = cmdui.Widget(True, True, self)
        self.cmd.commandFinished.connect(self.commandFinished)
        self.cmd.setShowOutput(True)
        self.showMessage.connect(self.cmd.stbar.showMessage)
        self.layout().addWidget(self.cmd, 2)

        bbox = QDialogButtonBox()
        self.cancelbtn = bbox.addButton(QDialogButtonBox.Cancel)
        self.cancelbtn.clicked.connect(self.reject)
        self.compressbtn = bbox.addButton(_('Compress'),
                                            QDialogButtonBox.ActionRole)
        self.compressbtn.clicked.connect(self.compress)
        self.layout().addWidget(bbox)
        self.bbox = bbox

        self.showMessage.emit(_('Checking...'))
        self._wctxcleaner = wctxcleaner.WctxCleaner(repoagent, self)
        self._wctxcleaner.checkFinished.connect(self._checkCompleted)
        self.cmd.stbar.linkActivated.connect(self._wctxcleaner.runCleaner)
        QTimer.singleShot(0, self._wctxcleaner.check)

        self.setMinimumWidth(480)
        self.setMaximumHeight(800)
        self.resize(0, 340)
        repo = repoagent.rawRepo()
        self.setWindowTitle(_('Compress - %s') % repo.displayname)

        self.restoreSettings()

    @property
    def repo(self):
        return self._repoagent.rawRepo()

    @pyqtSlot(bool)
    def _checkCompleted(self, clean):
        if not clean:
            self.compressbtn.setEnabled(False)
            txt = _('Before compress, you must <a href="commit">'
                    '<b>commit</b></a> or <a href="discard">'
                    '<b>discard</b></a> changes.')
        else:
            self.compressbtn.setEnabled(True)
            txt = _('You may continue the compress')
        self.showMessage.emit(txt)

    def compress(self):
        self.cancelbtn.setShown(False)
        uc = ['update', '--repository', self.repo.root, '--clean', '--rev',
              str(self.revs[1])]
        rc = ['revert', '--repository', self.repo.root, '--all', '--rev',
              str(self.revs[0])]
        self.repo.incrementBusyCount()
        self.cmd.run(uc, rc)

    def commandFinished(self, ret):
        self.repo.decrementBusyCount()
        self.showMessage.emit(_('Changes have been moved, you must now commit'))
        self.compressbtn.setText(_('Commit', 'action button'))
        self.compressbtn.clicked.disconnect(self.compress)
        self.compressbtn.clicked.connect(self.commit)

    def commit(self):
        tip, base = self.revs
        func = revset.match(self.repo.ui, '%s::%s' % (base, tip))
        revcount = len(self.repo)
        revs = [c for c in func(self.repo, range(revcount)) if c != base]
        descs = [self.repo[c].description() for c in revs]
        self.repo.opener('cur-message.txt', 'w').write('\n* * *\n'.join(descs))

        dlg = commit.CommitDialog(self._repoagent, [], {}, self)
        dlg.finished.connect(dlg.deleteLater)
        dlg.exec_()
        self.showMessage.emit(_('Compress is complete, old history untouched'))
        self.compressbtn.setText(_('Close'))
        self.compressbtn.clicked.disconnect(self.commit)
        self.compressbtn.clicked.connect(self.accept)

    def storeSettings(self):
        s = QSettings()
        s.setValue('compress/geometry', self.saveGeometry())

    def restoreSettings(self):
        s = QSettings()
        self.restoreGeometry(s.value('compress/geometry').toByteArray())

    def accept(self):
        self.storeSettings()
        super(CompressDialog, self).accept()

    def reject(self):
        self.storeSettings()
        super(CompressDialog, self).reject()
