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

"""
Copyright (C) 2008,2009,2010 Wolfgang Rohdewald <wolfgang@rohdewald.de>

kajongg is free software you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
"""

import sys

from PyKDE4.kdeui import KMessageBox, KIcon
from PyQt4.QtCore import Qt, QVariant, SIGNAL
from PyQt4.QtGui import QDialog,  \
        QHBoxLayout, QVBoxLayout, QDialogButtonBox
from PyQt4.QtSql import QSqlTableModel

from query import Query

from util import logMessage, m18n, m18nc
from guiutil import MJTableView
from statesaver import StateSaver

class PlayerListModel(QSqlTableModel):
    """adapt the standard model to our needs"""
    def __init__(self, parent, dbhandle):
        QSqlTableModel.__init__(self, parent, dbhandle)

    def data(self, index, role=Qt.DisplayRole):
        """act as a filter: display not Local Game but the translation"""
        result = QSqlTableModel.data(self, index, role)
        if role == Qt.DisplayRole and index.column() == 1:
            stri = result.toString()
            result = QVariant(m18nc('kajongg name for local game server', stri))
        return result

class PlayerList(QDialog):
    """QtSQL Model view of the players"""
    def __init__(self, parent):
        QDialog.__init__(self)
        self.parent = parent
        self.model = PlayerListModel(self, Query.dbhandle)
        self.model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.model.setTable("player")
        self.model.setFilter('host<>"%s" or host is null' % Query.serverName)
        self.model.setSort(1, 0)
        self.model.setHeaderData(1, Qt.Horizontal, QVariant(m18nc("kajongg", "Server")))
        self.model.setHeaderData(2, Qt.Horizontal, QVariant(m18nc("Player", "Name")))
        self.model.setHeaderData(3, Qt.Horizontal, QVariant(m18n("Password")))
        self.view = MJTableView(self)
        self.view.setModel(self.model)
        self.view.hideColumn(0)
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.connect(self.buttonBox, SIGNAL("accepted()"), self.accept)
        self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject)
        self.newButton = self.buttonBox.addButton(m18n("&New"), QDialogButtonBox.ActionRole)
        self.newButton.setIcon(KIcon("document-new"))
        self.connect(self.newButton, SIGNAL('clicked(bool)'), self.slotInsert)
        self.deleteButton = self.buttonBox.addButton(m18n("&Delete"), QDialogButtonBox.ActionRole)
        self.deleteButton.setIcon(KIcon("edit-delete"))
        self.connect(self.deleteButton, SIGNAL('clicked(bool)'), self.delete)

        cmdLayout = QHBoxLayout()
        cmdLayout.addWidget(self.buttonBox)
        layout = QVBoxLayout()
        layout.addWidget(self.view)
        layout.addLayout(cmdLayout)
        self.setLayout(layout)

        self.setWindowTitle(m18n("Players") + ' - Kajongg')
        self.setObjectName('Players')

    def showEvent(self, dummyEvent):
        """adapt view to content"""
        if not self.model.select():
            logMessage("PlayerList: select failed")
            sys.exit(1)
        self.view.initView()
        StateSaver(self, self.view.horizontalHeader())

    def accept(self):
        """commit all modifications"""
        self.view.selectRow(0) # if ALT-O is entered while editing a new row, this is one way
        # to end editing and to pass the new value to the model
        if not self.model.submitAll():
            KMessageBox.sorry(None, m18n('Cannot save this. Possibly the name already exists. <br><br>' \
                    'Message from database:<br><br><message>%1</message>',
                    self.model.lastError().text()))
            return
        QDialog.accept(self)

    def slotCancel(self):
        """cancel all modifications"""
        self.model.revertAll()
        self.close()

    def slotInsert(self):
        """insert a record"""
        self.model.insertRow(self.model.rowCount())
        self.view.selectRow(self.model.rowCount()-1)

    def delete(self):
        """delete selected entries"""
        sel = self.view.selectionModel()
        maxDel = self.view.currentIndex().row() - 1
        for idx in sel.selectedIndexes():
            if idx.column() != 2:
                continue
            # sqlite3 does not enforce referential integrity.
            # we could add a trigger to sqlite3 but if it raises an exception
            # it will be thrown away silently.
            # if anybody knows how to propagate sqlite3 exceptions via QtSql
            # into python please tell me (wrohdewald)
            player = self.model.createIndex(idx.row(), 0).data().toInt()[0]
            # no query preparation, we don't expect lots of data
            if Query("select 1 from game where p0==%d or p1==%d or p2==%d or p3==%d" % \
                (player, player, player, player)).records:
                KMessageBox.sorry(self,
                    m18n('This player cannot be deleted. There are games associated with %1.',
                        idx.data().toString()))
            else:
                self.model.removeRow(idx.row())
                maxDel = max(maxDel, idx.row())
        self.view.selectRow(maxDel+1)

    def keyPressEvent(self, event):
        """use insert/delete keys for insert/delete"""
        key = event.key()
        if key == Qt.Key_Insert:
            self.slotInsert()
            return
        QDialog.keyPressEvent(self, event)
