#    Jools -- a graphical puzzle game in the Tetris tradition
#    
#    Copyright (C) 2002-2003 Paul Pelzl
#
#    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; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

# jool.py
#
# Handles the display of individual jools.
#

import pygame, random
from globals import *
from joolsutils import *
from initialize import *


SEL_UNSELECTED = 0
SEL_PRIMARY    = 1
SEL_SECONDARY  = 2
SEL_TERTIARY   = 3


# Class that displays and moves individual jools.
# Inherits from pygame Sprite class.
class Jool(pygame.sprite.Sprite):

   # Create a jool of a specific type
   def __init__(self, type):
      pygame.sprite.Sprite.__init__(self)
      if type in range(7):
         self.type = type
      else:
         print "Error: tried to create illegal jool type: ", type
         raise JoolTypeError

      self.image = imageCache[self.type][0]
      self.rect  = pygame.Rect((0, 0, JOOLSIZE, JOOLSIZE))

      self.isFixed    = 0       # Initially, assume this jool is not fixed, i.e.
                                #    is in motion.
      self.isSwapped  = 0       # Initially, assume this jool is not being
                                #    swapped.
      self.isFalseSwapped = 0   # Initially, assume this jool is not being 
                                #    illegally swapped.
      self.accel      = GRAVITY # Downward acceleration
      self.velocity   = 0       # Initially not moving 
      self.rect_below = None    # This needs to be set for collision
                                #    detection to work
      self.swapDir    = 0      
      self.swapFrameCount  = 9       # Number of animation frames for swapping
      self.falseSwapFrameCount = 22  # Number of animation frames for an illegal swap
      self.isOnTop    = 0
      self.isRotating = 0
      self.needsRotateCleanup = 0
      self.imageNum   = 0
      self.imageMax   = len(imageCache[self.type])-1
      self.frameCount = 0
      self.selectionStatus = SEL_UNSELECTED 
      self.backupImage = pygame.Surface((JOOLSIZE,JOOLSIZE)).convert()



   def setPos(self, pos):
      self.rect.left = pos[0]
      self.rect.top  = pos[1]
      

   # Update position, etc. for this jool
   # UPDATEREDRAW   --> this jool will be redrawn without any translation
   #                    or rotation (screen refresh)
   # UPDATEALL      --> do falling jool translation updates
   # UPDATESWAPS    --> do jool swapping translation updates
   # UPDATEROTATION --> do jool rotation updates
   def update(self, updateType):
      if updateType == UPDATEREDRAW:
         return 1

      if (not self.isFixed and (updateType == UPDATEALL or
            updateType == UPDATEFALLING)):
         self.velocity += self.accel
         self.rect.top += int(self.velocity)
         
         # Check to see whether we collide with another jool (or the bottom
         # of the screen)
         if self.rect.colliderect(self.rect_below):
            # If there is a collision, the jool stops moving (at least
            # momentarily) and gets aligned properly with the rect that it
            # ran into.
            self.velocity = 0
            self.rect.top = self.rect_below.top - self.rect.height
            self.isFixed  = 1
            click.play()
         return 1

      if (self.isFixed and self.isSwapped and (updateType == UPDATEALL or
            updateType == UPDATESWAPS)):
         if self.swapFrameCount <= 0:
            self.swapFrameCount = 9
            self.isSwapped = 0
            self.isOnTop   = 0
         else:
            self.swapFrameCount -= 1
            if self.swapDir == 1:
               self.rect.left += 5
            elif self.swapDir == 2:
               self.rect.top += 5
            elif self.swapDir == 3:
               self.rect.left -= 5
            elif self.swapDir == 4:
               self.rect.top -= 5
         # This should erase any selection boxes before swapping
         self.image = imageCache[self.type][self.imageNum]
         return 1


      if (self.isFixed and self.isFalseSwapped and (updateType == UPDATEALL or
            updateType == UPDATESWAPS)):
         if self.falseSwapFrameCount <= 0:
            self.falseSwapFrameCount = 22
            self.isFalseSwapped = 0
            self.isOnTop = 0
         else:
            self.falseSwapFrameCount -= 1

            if (self.falseSwapFrameCount == 13):
               buzz.play()

            if (self.falseSwapFrameCount <= 8 or
                  self.falseSwapFrameCount > 12):
               if self.swapDir == 1:
                  self.rect.left += 5
               elif self.swapDir == 2:
                  self.rect.top += 5
               elif self.swapDir == 3:
                  self.rect.left -= 5
               elif self.swapDir == 4:
                  self.rect.top -= 5

            if self.falseSwapFrameCount == 9:
               self.isOnTop = not self.isOnTop
               if self.swapDir == 1:
                  self.swapDir = 3
               elif self.swapDir == 2:
                  self.swapDir = 4
               elif self.swapDir == 3:
                  self.swapDir = 1
               elif self.swapDir == 4:
                  self.swapDir = 2
         # This should erase any selection boxes before swapping
         self.image = imageCache[self.type][self.imageNum]
         return 1



      # Rotation updates
      if updateType == UPDATEALL or updateType == UPDATEROTATION:
         if self.isRotating:
            self.isRotating = 0
            self.imageNum += 1
            if self.imageNum > self.imageMax:
               self.imageNum = 0
            self.image = imageCache[self.type][self.imageNum]
            if self.selectionStatus != SEL_UNSELECTED: 
               self.drawSelection()
            return 1

         if self.needsRotateCleanup:
            if self.imageNum > 0:
               self.imageNum += 1
               if self.imageNum > self.imageMax:
                  self.imageNum = 0
                  self.needsRotateCleanup = 0
               self.image = imageCache[self.type][self.imageNum]
            else:
               self.needsRotateCleanup = 0
               self.image = imageCache[self.type][self.imageNum]

            if self.selectionStatus != SEL_UNSELECTED:
               self.drawSelection()
            return 1

      return 0


   # highlight this jool with a box
   def drawSelection(self):
      # modifications are made to self.backupImage, so that the
      # original images in imageCache are not corrupted
      self.backupImage.fill((0,0,0))
      self.backupImage.blit(self.image, (0,0))
      self.image = self.backupImage
      if self.selectionStatus == SEL_PRIMARY:
         c = (0,200,0)
      elif self.selectionStatus == SEL_SECONDARY:
         c = (0,115,0)
      else:
         c = (150,0,0)
      pygame.draw.rect(self.image, c, pygame.Rect([0,0,JOOLSIZE-1,JOOLSIZE-1]), 1)



   
# arch-tag: jool class
