## vim:ts=4:et:nowrap
##
##---------------------------------------------------------------------------##
##
## PySol -- a Python Solitaire game
##
## Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
## All Rights Reserved.
##
## This program 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; see the file COPYING.
## If not, write to the Free Software Foundation, Inc.,
## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
##
## Markus F.X.J. Oberhumer
## <markus@oberhumer.com>
## http://www.oberhumer.com/pysol
##
##---------------------------------------------------------------------------##


# imports
import os, sys, string, time, types

# PySol imports
from mfxtools import *
from mfxutil import SubclassResponsibility, Struct, destruct
from util import PACKAGE, VERSION
from gamedb import GI

# Toolkit imports
from pysoltk import MfxDialog


# // FIXME - this a quick hack and needs a rewrite


# /***********************************************************************
# //
# ************************************************************************/

class Status_StatsDialog(MfxDialog):
    def __init__(self, parent, game):
        stats, gstats = game.stats, game.gstats
        w1 = w2 = ""
        n = 0
        for s in game.s.foundations:
            n = n + len(s.cards)
        if PACKAGE == "PyJongg":
            w1 = "Highlight tiles: " + str(stats.highlight_piles) + "\n"
            w2 = w2 + "\nTiles removed: " + str(n)
            w2 = w2 + "\nTiles remaining: " + str(len(game.cards) - n)
        else:
            w1 = ("Highlight piles: " + str(stats.highlight_piles) + "\n" +
                  "Highlight cards: " + str(stats.highlight_cards) + "\n" +
                  "Highlight same rank: " + str(stats.highlight_samerank) + "\n")
            if game.s.talon:
                if game.gameinfo.redeals != 0:
                    w2 = w2 + "\nRedeals: " + str(game.s.talon.round - 1)
                w2 = w2 + "\nCards in Talon: " + str(len(game.s.talon.cards))
            if game.s.waste and game.s.waste not in game.s.foundations:
                w2 = w2 + "\nCards in Waste: " + str(len(game.s.waste.cards))
            if game.s.foundations:
                w2 = w2 + "\nCards in Foundations: " + str(n)
        #
        date = time.strftime("%Y-%m-%d %H:%M", time.localtime(game.gstats.start_time))
        MfxDialog.__init__(self, parent, title="Game status",
                   text=game.getTitleName() + "\n" +
                        game.getGameNumber(format=1) + "\n" +
                        "Playing time: " + game.getTime() + "\n" +
                        "Started at: " + date + "\n\n"+
                        "Moves: " + str(game.moves.index) + "\n" +
                        "Undo moves: " + str(stats.undo_moves) + "\n" +
                        "Bookmark moves: " + str(gstats.goto_bookmark_moves) + "\n" +
                        "Demo moves: " + str(stats.demo_moves) + "\n\n" +
###                        "Total player moves: " + str(stats.player_moves) + "\n" +
###                        "Total moves in this game: " + str(stats.total_moves) + "\n" +
                        "Hints: " + str(stats.hints) + "\n" +
                        w1 + w2,
                   strings=("OK", ("Statistics...", 101)),
                   image=game.app.gimages.logos[3], image_side="left", image_padx=20,
                   padx=20, separatorwidth=2)


# /***********************************************************************
# //
# ************************************************************************/

class PysolStatsFormatter:
    def __init__(self, app):
        self.app = app

    #
    #
    #

    class StringWriter:
        def __init__(self):
            self.text = ""

        def p(self, s):
            self.text = self.text + s

        def nl(self, count=1):
            self.p("\n" * count)

        def pheader(self, s):
            self.p(s)

        def pstats(self, t1, t2, t3, t4, t5, gameid=None):
            s = "%-30s %7s %7s %7s %7s\n" % (t1, t2, t3, t4, t5)
            self.p(s)

        def plog(self, gamename, gamenumber, date, status, gameid=-1, won=-1):
            self.p("%-25s %-20s  %17s  %s\n" % (gamename, gamenumber, date, status))


    class FileWriter(StringWriter):
        def __init__(self, file):
            self.file = file

        def p(self, s):
            self.file.write(s)

    #
    #
    #

    def writeHeader(self, writer, header, pagewidth=72):
        date = time.ctime(time.time())
        date = time.strftime("%Y-%m-%d  %H:%M", time.localtime(time.time()))
        blanks = max(pagewidth - len(header) - len(date), 1)
        writer.pheader(header + " "*blanks + date + "\n")
        writer.pheader("-" * pagewidth + "\n")
        writer.pheader("\n")

    def writeStats(self, writer, player, header):
        app = self.app
        self.writeHeader(writer, header, 62)
        writer.pstats(player or "Demo games", "Played", "Won", "Lost", r"% won")
        writer.nl()
        twon, tlost, tgames = 0, 0, 0
        g = app.getGamesIdSortedByName()
        for id in g:
            name = app.getGameMenuitemName(id)
            won, lost = app.stats.getStats(player, id)
            twon, tlost = twon + won, tlost + lost
            if won + lost > 0: perc = "%.1f" % (100.0 * won / (won + lost))
            else: perc = "0.0"
            if won > 0 or lost > 0 or id == app.game.id:
                writer.pstats(name, won+lost, won, lost, perc, gameid=id)
                tgames = tgames + 1
        writer.nl()
        won, lost = twon, tlost
        if won + lost > 0: perc = "%.1f" % (100.0 * won / (won + lost))
        else: perc = "0.0"
        writer.pstats("Total (%d out of %d games)" % (tgames, len(g)),
                      won+lost, won, lost, perc)
        writer.nl(2)
        return tgames

    def _writeLog(self, writer, player, header, prev_games):
        if not player or not prev_games:
            return 0
        self.writeHeader(writer, header, 71)
        writer.plog("Game", "Game number", "Started at   ", "Status")
        writer.nl()
        twon, tlost = 0, 0
        for pg in prev_games:
            if type(pg) is not types.TupleType:
                continue
            if len(pg) == 5:
                pg = pg + ("", None, None, 1)
            elif len(pg) == 7:
                pg = pg + (None, 1)
            elif len(pg) == 8:
                pg = pg + (1,)
            if len(pg) < 8:
                continue
            gameid = pg[0]
            if type(gameid) is not types.IntType:
                continue
            gi = self.app.getGameInfo(gameid)
            if not gi:
                gi = self.app.getGameInfo(GI.PROTECTED_GAMES.get(gameid))
            if gi:
                name = gi.short_name
            else:
                name = "** UNKNOWN %d **" % gameid
            f = pg[1]
            if len(f) == 16:
                ##gamenumber = "%s-%s-%s-%s" % (f[0:4], f[4:8], f[8:12], f[12:16])
                gamenumber = "%s-%s-%s" % (f[4:8], f[8:12], f[12:16])
            elif len(f) <= 20:
                gamenumber = f
            else:
                gamenumber = "** ERROR **"
            date = time.strftime("%Y-%m-%d  %H:%M", time.localtime(pg[3]))
            if pg[2] >= 0:
                won = pg[2] > 0
                twon, tlost = twon + won, tlost + (1 - won)
            status = "*error*"
            if -2 <= pg[2] <= 2:
                status = ("Loaded", "Not won", "Lost", "Won", "Perfect") [pg[2]+2]
            writer.plog(name, gamenumber, date, status, gameid=gameid, won=pg[2])
        writer.nl(2)
        return 1

    def writeFullLog(self, writer, player, header):
        prev_games = self.app.stats.prev_games.get(player)
        return self._writeLog(writer, player, header, prev_games)

    def writeSessionLog(self, writer, player, header):
        prev_games = self.app.stats.session_games.get(player)
        return self._writeLog(writer, player, header, prev_games)
