## vim:ts=4:et:nowrap
##
##---------------------------------------------------------------------------##
##
## PySol -- a Python Solitaire game
##
## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
##
## 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 sys

# PySol imports
if sys.modules.has_key("pysoltk"):
    from gamedb import registerGame, GameInfo, GI
    from util import *
    from stack import *
    from game import Game
    from layout import Layout
    from hint import AbstractHint, DefaultHint, CautiousDefaultHint
    from hint import FreeCellType_Hint


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

class DerKatzenschwanz(Game):
    RowStack_Class = StackWrapper(AC_RowStack, base_rank=NO_RANK)

    #
    # game layout
    #

    def createGame(self, rows=9, reserves=8):
        # create layout
        l, s = Layout(self, XOFFSET=10), self.s

        # set size
        maxrows = max(rows, reserves)
        self.setSize(l.XM + (maxrows+2)*l.XS, l.YM + 6*l.YS)

        #
        playcards = 4*l.YS / l.YOFFSET
        xoffset, yoffset = [], []
        for i in range(playcards):
            xoffset.append(0)
            yoffset.append(l.YOFFSET)
        for i in range(104-playcards):
            xoffset.append(l.XOFFSET)
            yoffset.append(0)

        # create stacks
        x, y = l.XM + (maxrows-reserves)*l.XS/2, l.YM
        for i in range(reserves):
            s.reserves.append(ReserveStack(x, y, self))
            x = x + l.XS
        x, y = l.XM + (maxrows-rows)*l.XS/2, l.YM + l.YS
        self.setRegion(s.reserves, (-999, -999, 999999, y - l.XM / 2))
        for i in range(rows):
            stack = self.RowStack_Class(x, y, self)
            stack.CARD_XOFFSET = xoffset
            stack.CARD_YOFFSET = yoffset
            s.rows.append(stack)
            x = x + l.XS
        x, y = l.XM + maxrows*l.XS, l.YM
        for suit in range(4):
            for i in range(2):
                s.foundations.append(SS_FoundationStack(x+i*l.XS, y, self, suit=suit))
            y = y + l.YS
        self.setRegion(self.s.foundations, (x - l.CW / 2, -999, 999999, y), priority=1)
        s.talon = InitialDealTalonStack(self.width-3*l.XS/2, self.height-l.YS, self)

        # define stack-groups
        l.defaultStackGroups()

    #
    # game overrides
    #

    def startGame(self):
        self.startDealSample()
        i = 0
        while self.s.talon.cards:
            if self.s.talon.cards[-1].rank == KING:
                if self.s.rows[i].cards:
                    i = i + 1
            self.s.talon.dealRow(rows=[self.s.rows[i]], frames=4)

    def shallHighlightMatch(self, stack1, card1, stack2, card2):
        return (card1.color != card2.color and
                (card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))

    # must look at cards
    def _getClosestStack(self, cx, cy, stacks, dragstack):
        closest, cdist = None, 999999999
        for stack in stacks:
            if stack.cards and stack is not dragstack:
                dist = (stack.cards[-1].x - cx)**2 + (stack.cards[-1].y - cy)**2
            else:
                dist = (stack.x - cx)**2 + (stack.y - cy)**2
            if dist < cdist:
                closest, cdist = stack, dist
        return closest


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

class DieSchlange(DerKatzenschwanz):
    RowStack_Class = StackWrapper(FreeCell_AC_RowStack, base_rank=NO_RANK)
    Hint_Class = FreeCellType_Hint

    def createGame(self):
        DerKatzenschwanz.createGame(self, rows=9, reserves=7)

    def startGame(self):
        self.startDealSample()
        i = 0
        while self.s.talon.cards:
            c = self.s.talon.cards[-1]
            if c.rank == ACE:
                to_stack = self.s.foundations[c.suit*2]
                if to_stack.cards:
                    to_stack = self.s.foundations[c.suit*2+1]
            else:
                if c.rank == KING and self.s.rows[i].cards:
                    i = i + 1
                to_stack = self.s.rows[i]
            self.s.talon.dealRow(rows=(to_stack,), frames=4)


# register the game
registerGame(GameInfo(141, DerKatzenschwanz, "Der Katzenschwanz",
                      GI.GT_FREECELL | GI.GT_OPEN, 2, 0))
registerGame(GameInfo(142, DieSchlange, "Die Schlange",
                      GI.GT_FREECELL | GI.GT_OPEN, 2, 0))

