#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------##
#
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co.
# Copyright (C) 2005-2009 Skomoroh
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
#
# ---------------------------------------------------------------------------##

from pysollib.gamedb import GI, GameInfo, registerGame
from pysollib.games.larasgame import LarasGame, LarasGame_Reserve
from pysollib.games.larasgame import LarasGame_Talon
from pysollib.games.special.dashavatara import AbstractDashavataraGame
from pysollib.games.special.hanafuda_common import AbstractFlowerGame
from pysollib.games.special.hexadeck import AbstractHexADeckGame
from pysollib.games.special.mughal import AbstractMughalGame
from pysollib.games.special.tarock import AbstractTarockGame
from pysollib.stack import OpenStack


class DojoujisGame_Talon(LarasGame_Talon):
    def getActiveRow(self):
        card = self.getCard()
        return card.rank + card.deck * 4


class DoubleKalisGame_Talon(LarasGame_Talon):
    def getActiveRow(self):
        card = self.getCard()
        return card.rank + card.deck * 12


class BridgetsGame_Reserve(OpenStack):

    def acceptsCards(self, from_stack, cards):
        if not OpenStack.acceptsCards(self, from_stack, cards):
            return 0
        if not self.cards:
            return from_stack in self.game.s.foundations and cards[0].suit == 4
        return from_stack in self.game.s.rows

    def getBottomImage(self):
        return self.game.app.images.getReserveBottom()


# ************************************************************************
# * Katrina's Game
# ************************************************************************

class KatrinasGame(AbstractTarockGame, LarasGame):
    DEAL_TO_TALON = 3
    MAX_ROUNDS = 2
    ROW_LENGTH = 5
    MAX_ROW = 22

    #
    # Game extras
    #

    def Max_Cards(self, i):
        return 14 + 8 * (i == 4)

    def Mod(self, i):
        return 14 + 8 * (i == 4)

    def Base_Rank(self, i, j):
        return (13 + 8 * (i == 4)) * (not j)

    def Deal_Rows(self, i):
        return 14 + 8 * (i % 2)

    def Base_Suit(self, i, j):
        return i

    #
    # Game overrides
    #

    def getCardFaceImage(self, deck, suit, rank):
        return self.app.images.getFace(deck, suit, rank)


# ************************************************************************
# * Relaxed Katrina's Game
# ************************************************************************

class RelaxedKatrinasGame(KatrinasGame):
    Reserve_Class = LarasGame_Reserve
    Reserve_Cards = 2


# ************************************************************************
# * Double Katrina's Game
# ************************************************************************

class DoubleKatrinasGame(RelaxedKatrinasGame):
    Reserve_Cards = 3
    MAX_ROUNDS = 3

    def Max_Cards(self, i):
        return 28 + 16 * (i == 4)


# ************************************************************************
# * Bridget's Game
# * In memory of Bridget Bishop
# * Hanged as a witch on June 10, 1692
# * Salem Massachusetts, U. S. A.
# * and the nineteen other women
# * and men who followed her
# ************************************************************************

class BridgetsGame(AbstractHexADeckGame, LarasGame):
    Reserve_Class = BridgetsGame_Reserve
    Reserve_Cards = 2
    MAX_ROUNDS = 2
    ROW_LENGTH = 5
    MAX_ROW = 16

    def Max_Cards(self, i):
        return 16 - 12 * (i == 4)

    def Mod(self, i):
        return 16 - 12 * (i == 4)

    def Base_Rank(self, i, j):
        return (15 - 12 * (i == 4)) * (not j)

    def Deal_Rows(self, i):
        return 16

    def Base_Suit(self, i, j):
        return i


# ************************************************************************
# * Double Bridget's Game
# ************************************************************************

class DoubleBridgetsGame(BridgetsGame):
    Reserve_Cards = 3
    MAX_ROUNDS = 3

    def Max_Cards(self, i):
        return 32 - 24 * (i == 4)


# ************************************************************************
# * Fatimeh's Game
# ************************************************************************

class FatimehsGame(AbstractMughalGame, LarasGame):
    DEAL_TO_TALON = 5
    MAX_ROUNDS = 3
    MAX_ROW = 12
    DIR = (1, 1)

    def Max_Cards(self, i):
        return 12

    def Mod(self, i):
        return 12

    def Base_Rank(self, i, j):
        return 0

    def Deal_Rows(self, i):
        return 12

    def Base_Suit(self, i, j):
        return i + j * 4


# ************************************************************************
# * Relaxed Fatimeh's Game
# ************************************************************************

class RelaxedFatimehsGame(FatimehsGame):
    Reserve_Class = LarasGame_Reserve
    Reserve_Cards = 2


# ************************************************************************
# * Kali's Game
# ************************************************************************

class KalisGame(AbstractDashavataraGame, FatimehsGame):
    DEAL_TO_TALON = 6
    ROW_LENGTH = 5

    def Base_Suit(self, i, j):
        return i + j * 5


# ************************************************************************
# * Relaxed Kali's Game
# ************************************************************************

class RelaxedKalisGame(KalisGame):
    Reserve_Class = LarasGame_Reserve
    Reserve_Cards = 2


# ************************************************************************
# * Double Kali's Game
# ************************************************************************

class DoubleKalisGame(RelaxedKalisGame):
    Talon_Class = DoubleKalisGame_Talon
    Reserve_Cards = 4
    MAX_ROUNDS = 4
    MAX_ROW = 24

    def Max_Cards(self, i):
        return 24

    def Deal_Rows(self, i):
        return 24


# ************************************************************************
# * Dojouji's Game
# ************************************************************************

class DojoujisGame(AbstractFlowerGame, LarasGame):
    Talon_Class = DojoujisGame_Talon
    ROW_LENGTH = 6
    MAX_ROW = 8
    DIR = (-1, -1)

    def Max_Cards(self, i):
        return 8

    def Mod(self, i):
        return 4

    def Base_Rank(self, i, j):
        return 3

    def Deal_Rows(self, i):
        return 8

    def Base_Suit(self, i, j):
        return i + j * 6


# ************************************************************************
# * Double Dojouji's Game
# ************************************************************************

class DoubleDojoujisGame(DojoujisGame):
    MAX_ROW = 16

    def Max_Cards(self, i):
        return 16

    def Deal_Rows(self, i):
        return 16


# register the game
registerGame(GameInfo(13001, KatrinasGame, "Katrina's Game",
                      GI.GT_TAROCK, 2, 1, GI.SL_BALANCED,
                      ranks=list(range(14)), trumps=list(range(22))))
registerGame(GameInfo(13002, BridgetsGame, "Bridget's Game",
                      GI.GT_HEXADECK, 2, 1, GI.SL_BALANCED,
                      ranks=list(range(16)), trumps=list(range(4))))
registerGame(GameInfo(13003, FatimehsGame, "Fatimeh's Game",
                      GI.GT_MUGHAL_GANJIFA, 1, 2, GI.SL_BALANCED,
                      suits=list(range(8)), ranks=list(range(12))))
registerGame(GameInfo(13004, KalisGame, "Kali's Game",
                      GI.GT_DASHAVATARA_GANJIFA, 1, 2, GI.SL_BALANCED,
                      suits=list(range(10)), ranks=list(range(12))))
registerGame(GameInfo(13005, DojoujisGame, "Dojouji's Game",
                      GI.GT_HANAFUDA, 2, 0, GI.SL_BALANCED,
                      suits=list(range(12)), ranks=list(range(4))))
registerGame(GameInfo(13008, RelaxedKatrinasGame, "Katrina's Game Relaxed",
                      GI.GT_TAROCK, 2, 1, GI.SL_BALANCED,
                      ranks=list(range(14)), trumps=list(range(22))))
registerGame(GameInfo(13009, DoubleKatrinasGame, "Katrina's Game Doubled",
                      GI.GT_TAROCK, 4, 2, GI.SL_BALANCED,
                      ranks=list(range(14)), trumps=list(range(22))))
registerGame(GameInfo(13010, DoubleBridgetsGame, "Bridget's Game Doubled",
                      GI.GT_HEXADECK, 4, 2, GI.SL_BALANCED,
                      ranks=list(range(16)), trumps=list(range(4))))
registerGame(GameInfo(13011, RelaxedKalisGame, "Kali's Game Relaxed",
                      GI.GT_DASHAVATARA_GANJIFA, 1, 2, GI.SL_BALANCED,
                      suits=list(range(10)), ranks=list(range(12))))
registerGame(GameInfo(13012, DoubleKalisGame, "Kali's Game Doubled",
                      GI.GT_DASHAVATARA_GANJIFA, 2, 3, GI.SL_BALANCED,
                      suits=list(range(10)), ranks=list(range(12))))
registerGame(GameInfo(13013, RelaxedFatimehsGame, "Fatimeh's Game Relaxed",
                      GI.GT_MUGHAL_GANJIFA, 1, 2, GI.SL_BALANCED,
                      suits=list(range(8)), ranks=list(range(12))))
registerGame(GameInfo(13014, DoubleDojoujisGame, "Dojouji's Game Doubled",
                      GI.GT_HANAFUDA, 4, 0, GI.SL_BALANCED,
                      suits=list(range(12)), ranks=list(range(4))))
