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

# Copyright (c) 2007 Stas Zykiewicz <stas.zytkiewicz@gmail.com>
#
#           memory.py
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 3 of the GNU General Public License
# as published by the Free Software Foundation.  A copy of this license should
# be included in the file GPL-3.
#
# 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


DEBUG = 0
# do we want to use configfiles?
RCFILE = 0

# standard modules you probably need
import os,sys,random

import pygame
from pygame.constants import *

from utils import *
from CPConstants import *
import SpriteUtils

# containers that can be used globally to store stuff
class Img:
    pass
class Snd:
    pass

class Game:
    """  Memory.py - part of childsplay.py, a suite of educational games for
  young children.
  """

    def __init__(self,screen,backgr,rc_dic,basepath,libdir,cpg):
        self.screen = screen
        self.backgr = backgr
        self.rc_dic = rc_dic
        self.bonus = 0
        self.myimages = []      
        self.basedir  = basepath
        try:
            import pyassetmlSDL
            #assetmlSDL = import_module(os.path.join(self.basedir,'pyassetmlSDL.py'))
        except (ImportError,MyError),info:
            print >> sys.stderr,info,"\nThis version of childsplay depends on pyassetmlSDL"
            text = "Module memory fails to import pyassetmlSDL"
            raise MyError,text
        # create two assetmlSDL instances one for parsing images and one for sounds
        self.Assets_img = pyassetmlSDL.AssetmlSDL()
        self.Assets_img.set_mldir('childsplay/memory-136x136/memory-136x136.assetml')
        self.Assets_snd = pyassetmlSDL.AssetmlSDL()
        self.Assets_snd.set_mldir('childsplay/childsplay-sounds/childsplay-sounds.assetml')
        
        self.libdir = libdir
        # This will also used as a test if we are using other images
        #self.myimages = glob.glob(os.path.join(self.libdir,'MemoryData','my_images','*'))
        try:
            self.myimages = glob.glob(os.path.join(HOMEDIR,'memory','my_images','*'))
        except Exception,info:
            print info
            self.myimages = []
        if DEBUG: print "Contents of my_images", self.myimages
        if len(self.myimages) < 12:
            self.myimages = None
        self.selection = []
        self.selected = []
        self.score = 0
        self.gamelevels = [(2,3,167,100),(2,4,90,200),(3,4,90,300),(4,6,40,400)]
        #self.gamelevels =[(2,2,40)]
        self.gameitems = [None]
        self.setup()
    
        
    def setup(self):
        
        files = ('dealcard1.wav','wahoo.wav')
        self.Sound = Snd()
        self.Image = Img()
        # Sound becomes self.Sound.dealcard1, self.Sound.wahoo 
        self.Assets_snd.get_assets(files,self.Sound)
        
        file = os.path.join(self.libdir,'MemoryData','cardback.png')
        Img.cback = load_image(file)
        file = os.path.join(self.libdir,'MemoryData','cardfront.png')
        Img.cfront = load_image(file)
        
    def load_cards(self,num):
        """  Load cards and shuffle them. Images are stored in a list as pygame
        image objects.
        """
        if self.myimages:
            objects = []
            for file in self.myimages:
                objects.append(load_image(file))
        else:
            d = self.Assets_img.get_assets(('*.png',))
            objects = d.values()
            if DEBUG: print "dictionary from pyassetmlSDL",d
        if len(objects) < num:
            return
        else:
            random.shuffle(objects)
            objects = objects[:num]
        if num > 6:# more then 12 cards -> 3x4
            size = 112
            self.card_offset = 4
            
        else:
            size = 136
            self.card_offset = 16
            
        scaled = ScaleImages((Img.cback,), (size,size))
        Img.cback = scaled.get_images()[0]    
        scaled = ScaleImages(objects, (size,size), Img.cfront)
        img_obj_list = scaled.get_images()
        img_obj_list = img_obj_list * 2 # every picture must be double
        random.shuffle(img_obj_list)
        return img_obj_list
    
    def helptitle(self):
        return _("Memory")
    
    def __str__(self):
        """Must return the original, not translated, title of this game.
        It's needed by the high score class of childsplay."""        
        return "Memory"
    
    def help(self):
        text = [_("The aim of the game:"),
        _("Classic memory game where you have to find pairs of cards."),
        " ",
        _("Difficulty : 2-5 years"),
        " ",
        _("Number of levels : 3")]

        return text 
    
    def start(self,l,spam):
        """Turn the cards and find pairs"""
        self.stop,self.score = 0,0
        r, c ,offset, self.bonus = l
        self.deal_cards(r,c,offset)
    
    def deal_cards(self,rows,cols,offset):
        """ Deal the cards and store them in a reference matrix. Display
        the closed cards. The matrix is a dictionary with tuples as keys
         key = tuple(rect), value = image object."""
        
        obj_items = self.load_cards((rows*cols)/2)
        self.matrix = {}
        x_size = Img.cback.get_width()+self.card_offset
        y_size = Img.cback.get_height()+self.card_offset
        for y in range(rows):
            for x in range(cols):
                obj = obj_items.pop()
                r = self.screen.blit(Img.cback,(offset + (x*x_size)+self.card_offset,(y*y_size)+self.card_offset))
                self.matrix[tuple(r)] = obj
                pygame.display.update(r)
                self.Sound.dealcard1.play()
                pygame.time.wait(300)
        pyrect = pygame.Rect
        self.matrixrects = map(pyrect,self.matrix.keys())

    def loop(self,events):
        self.score = 0
        for event in events:
            if event.type is MOUSEBUTTONDOWN:
                self.on_select_activate()
        return self.stop,self.score
        
    def on_select_activate(self):
        pos = pygame.Rect(pygame.mouse.get_pos() + (4,4))
        selitem = None
        self.score = 0
        for rec in self.matrixrects:
            if rec.contains(pos):
                selitem = tuple(rec)
                break
        
        if not selitem: # Mouse outside any card
            return
        if not self.selection: # First card select
            self.selection = selitem
            self.turn_card(selitem)
            return
        if self.selection is selitem: # card is already selected
            return
        else:
            self.turn_card(selitem)
            if self.matrix[selitem] is self.matrix[self.selection]\
                and selitem != self.selection:
                
                #print 'objects are equal'
                self.Sound.wahoo.play()
                self.score = 10
                pygame.time.wait(1000)
                
                del self.matrix[selitem]
                self.matrixrects.remove(pygame.Rect(selitem))
                r = self.screen.blit(self.backgr,selitem,selitem)
                del self.matrix[self.selection]
                self.matrixrects.remove(pygame.Rect(self.selection))
                rr = self.screen.blit(self.backgr,self.selection,self.selection)
                pygame.display.update((r,rr))
                self.selection = None
                if not self.matrixrects: # no more cards left
                    self.score = self.bonus
                    self.stop = -1 # level is over
                                        
            else:
                #print 'objects not equal'
                if self.bonus > 0:
                    self.bonus = self.bonus - 1
                pygame.time.wait(1000)
                
                self.turn_card(selitem,Img.cback)
                self.turn_card(self.selection,Img.cback)
                self.selection = None
        
        return
    
    def turn_card(self,rect,obj=None):
        if not obj:
            obj = self.matrix[rect]
        self.screen.blit(obj,rect)
        pygame.display.update(rect)
        return

