"""
Copyright 2001-2002 Andrew Jones

This file is part of Pyzzle.

    Pyzzle 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.

    Pyzzle 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 Pyzzle; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


"""

import os, os.path, sys
import pygame,  pygame.constants, pygame.movie, pygame.time
from pygame.locals import *
import constants, snd
import cursors, gfx, menuevents, img, nodedata, mov, transition
import gameobjects, textfn, tripwire, cursors, paths, Image, Movie, AmbientSound, Sound
import Slide, Text, Object
from Text import *
from Object import *
from Slide import *
from nodedata import *
from Image import *
from Movie import *
from AmbientSound import *
from Sound import *
from constants import *
from menuevents import *
from textfn import *
from gameobjects import *


#see if we can get some font lovin'
try: import pygame.font as font
except ImportError: font = None

#this function accepts the view file string and blits that view to screen
def change_slide(newnode):
    nodedata.newNode = newnode 
    
def showview(currentView,setprev=0):
    nodedata.oldCursorZone = nodedata.cursorZone
    movPlay = 0
    if setprev == 1:
        nodedata.previousslide = nodedata.currentslide
    nodedata.currentslide = currentView
    gfx.updateslide(currentView.slidefile)
    if nodedata.hastype('onEntrance') and not gameobjects.outobjects: #onEntrance call
        nodedata.currentslide.onEntranceFn()
    gameobjects.outobjects = 0
    if nodedata.prehastype('transover') or nodedata.prehastype('transition_override'):
        transition.override()
    elif nodedata.prehastype('notrans'):
        transition.notrans()
    for i in currentView.contains:
        if i == 'image':
            gfx.imagerectstore = []
            gfx.imagesurfacestore = []
            img.showimage(currentView)
        elif i == 'movieloop':
            movPlay = 1                
        elif i == 'text': textfn.display(currentView)
    transition.call()
    if movPlay:
        mov.play(0,1,1)
        movPlay = 0
        gameobjects.playmovie = 0
    elif gameobjects.playmovie:
        mov.play(0,1,1)
        gameobjects.playmovie = 0
    if nodedata.hastype('delay'):
        nodedata.previousslide = currentView
        nodedata.cursorZone = 0
        pygame.display.update(gfx.slideRect) 
        pygame.time.delay(currentView.delay)
        nodedata.nextslide = currentView.navdata[0]
        if nodedata.hastype('onExitSlide'):
            nodedata.currentslide.doOnExitSlide()
        if nodedata.hastype('onExit'):
            nodedata.currentslide.onExitFn()
        return showview(currentView.navdata[0],1)

    return currentView
        
def next_view_fn(cursorZone, currentView):
    global tmpnavtype
    if not cursorZone < 0:
        nodedata.cursorZone = cursorZone
        if currentView.contains[0] == 'zip':
             
            currentView.contains[0] = tmpnavtype
            return currentView.zip_navdata[cursorZone]
        return currentView.navdata[cursorZone]
    elif cursorZone == -2:
        
        ret =  menuevents.event('showmain')
       
        return ret
    elif cursorZone == -3:
        nodedata.objectreturnslide = currentView
        i = 0
        for x in gameobjects.objectArrayRect:
            if x.collidepoint(pygame.mouse.get_pos()):
                nodedata.cursorZone = 0
                if mov.mov != None:
                    gameobjects.ismovie = 1
                #print gameobjects.objectArray[i].smallimagefile
                gameobjects.inobjects = 1
                gameobjects.rolloutArray()
                return gameobjects.objectArray[i].node
            i = i + 1
                
        
        return None
    else:
        return None
#this function returns hotspot map info for each view
# std, std180, LandR, LandR180, LandRup, LandRaction, stdup also: custom, stddown,LandRdown
def gethotspotmap(currentView):
	global no_of_constant_rects, cursor_array, sliderect, tmpnavtype

        tmpfile =  os.path.join(paths.current_slide_path, currentView.slidefile )
        tmpSurface = gfx.load(tmpfile)
        sliderect = tmpSurface.get_rect()
        tmpRect = Rect(0,0,parameters.SCREENSIZE[0], parameters.SCREENSIZE[1])
        sliderect.center = tmpRect.center

        if not parameters.DISABLE_ZIPMODE and parameters.ZIPMODE: 
            if nodedata.hastype('zip'):
                returnRect = []
                cursor_array = []
                for i in range(len(currentView.zip_custmaps)):
                        returnRect.append(Rect(0,0,0,0))
                        
                        tempRect = Rect(currentView.zip_custmaps[i])
                        returnRect[i] = Rect(sliderect.left + tempRect.left,
                                                        sliderect.top + tempRect.top, tempRect.width,tempRect.height)
                tmpnavtype = currentView.contains[0] 
                #currentView.contains[0] = 'zip'
                tmprectarray = getMap(currentView)
                
                for i in range(len(tmprectarray)):
                    returnRect.append(tmprectarray[i])
                
                #for i in range(len(currentView.zip_which_cursor)):
                #    cursor_array.append(currentView.zip_which_cursor[i])
                cursor_array = currentView.zip_which_cursor
                no_of_constant_rects = len(currentView.zip_custmaps)
                
                currentView.contains[0] = 'zip' 
                return returnRect
            else: return getMap(currentView)
        else: return getMap(currentView)
        
def getMap(currentView):
    global no_of_constant_rects, cursor_array, sliderect, tmpnavtype

    tmpfile =  os.path.join(paths.current_slide_path, currentView.slidefile )
    tmpSurface = gfx.load(tmpfile)
    sliderect = tmpSurface.get_rect()
    tmpRect = Rect(0,0,parameters.SCREENSIZE[0], parameters.SCREENSIZE[1])
    sliderect.center = tmpRect.center

    if currentView.contains[0] == 'std' or currentView.contains[0] == 'std180':
        return [ Rect(sliderect.left, sliderect.top , TURNDEPTH, sliderect.height),
                 Rect(sliderect.left+TURNDEPTH, sliderect.top, sliderect.width-2*TURNDEPTH, sliderect.height) ,
                 Rect(sliderect.right-TURNDEPTH, sliderect.top , TURNDEPTH , sliderect.height)]
    elif currentView.contains[0] == 'LandRup':
        return [ Rect(sliderect.left, sliderect.top , TURNDEPTH, sliderect.height),
                 Rect(sliderect.left+TURNDEPTH, sliderect.top, sliderect.width-2*TURNDEPTH, VERTICALDEPTH),
                 Rect(sliderect.right-TURNDEPTH, sliderect.top , TURNDEPTH , sliderect.height) ]
    elif currentView.contains[0] == 'LandRdown':
        return [ Rect(sliderect.left, sliderect.top , TURNDEPTH, sliderect.height),
                 Rect(sliderect.left+TURNDEPTH, sliderect.top + sliderect.height-VERTICALDEPTHBOTTOM,
                      sliderect.width-2*TURNDEPTH, sliderect.height - VERTICALDEPTHBOTTOM),
                 Rect(sliderect.right-TURNDEPTH, sliderect.top , TURNDEPTH , sliderect.height) ]
    elif currentView.contains[0] == 'LandR':
        return [ Rect(sliderect.left, sliderect.top , TURNDEPTH, sliderect.height),
                 Rect(sliderect.right-TURNDEPTH, sliderect.top , TURNDEPTH , sliderect.height)]

    elif currentView.contains[0] == 'updown':
        return [ Rect(sliderect.left, sliderect.top, sliderect.width, VERTICALDEPTH),
                 Rect(sliderect.left, sliderect.top + VERTICALDEPTH, sliderect.width,
                      sliderect.height-VERTICALDEPTH)]
        
    elif currentView.contains[0] == 'custom':
        returnRect = []
        cursor_array = []
        for i in range(len(currentView.custmaps)):
            returnRect.append(Rect(0,0,0,0))
            cursor_array.append(currentView.which_cursor[i])
            tempRect = Rect(currentView.custmaps[i])
            returnRect[i] = Rect(sliderect.left + tempRect.left,
                                 sliderect.top + tempRect.top, tempRect.width,tempRect.height)

        no_of_constant_rects = len(currentView.custmaps)
        return returnRect
        
                
	
def keypressed(key):
    if key == K_ESCAPE:
        menuevents.event('showquit')
    elif key == K_F2:
        menuevents.event('showoptions')
    elif key == K_F3:
        menuevents.event('showsave')
    elif key == K_q and parameters.TESTINGFULL:
        gfx.quittest = 1
    
#--------------------------------------------------------------------

def get_map_pos(map_rect, mousepos):
     global is_menu_displayed
     if sliderect.collidepoint(mousepos):
         if map_rect != None:
             map_rect_length  = len(map_rect)
             i = 0
             while (i <= map_rect_length - 1):
             
                 if map_rect[i].collidepoint(mousepos):
                     return i
                 else: i = i + 1
             return -1
     else:
         
         if MENU_DISPLAY_RECT.collidepoint(mousepos):
             return -2#'overmenu'
         elif OBJECT_MOUSEOVER_RECT.collidepoint(mousepos) and not gameobjects.inobjects:
             gameobjects.cursor(mousepos)
             return -3# over object array
                
     return -666

def gamemain():
    global viewport, surface,  next_nodeView, array_pos
    global current_view
    global no_of_constant_rects, cursor_array
    
    parameters.screenRect = Rect(0,0,parameters.SCREENSIZE[0],parameters.SCREENSIZE[1])
    parameters.viewRect = Rect(0, 0, parameters.SLIDESIZE[0], parameters.SLIDESIZE[1])
    parameters.viewRect.center = parameters.screenRect.center
    parameters.OBJECT_RECT = Rect(parameters.viewRect.left,parameters.viewRect.bottom+10,parameters.viewRect.width,parameters.OBJECTMAXSIZE)
    parameters.OBJECT_MOUSEOVER_RECT = Rect(0,parameters.viewRect.bottom,parameters.screenRect.width ,parameters.screenRect.height-parameters.viewRect.height )
    parameters.resolution = parameters.RESOLUTION
    
    # Initialize SDL components
    pygame.init()
    gfx.initialize()
    gfx.initializeBackground()
    snd.initialize()
    cursors.initializecusors()
    mov.initialize()
    
    #first view of the game
    current_view = nodedata.FIRST_SLIDE
    nodedata.currentslide = current_view
    #initialize some vars
    nomovloop = parameters.MOVIEMAINLOOPS
    new_cursor_zone = -888
    cursor_zone = new_cursor_zone
    cursor_array = 'left'
    cursordisable = 0
    isMoviePlaying = 0
    
    #display the first view
    nodedata.cursorZone = 0
    nodedata.previousslide = current_view
    showview(current_view)
    currentView = current_view
    current_hotspotmap = gethotspotmap(current_view)
    cursors.iscursoron = 1
    istopmenu = 0
    istopObjects = 0
    cursors.cursordisabled = 0

    if snd.STARTUP_AMBIENT != None:
        snd.playambient(snd.STARTUP_AMBIENT, snd.STARTUP_VOLUME)

    if parameters.OBJECT_ARRAY_HIDE_ALPHA > 0:
        gameobjects.rolloutArray()
    
        
        
    no_of_constant_rects = 0
    
    cursors.cursor = cursors.fwdcursor
    cursors.cursor.enable()
    dirtyrects = []
    dirtyrects.extend([cursors.cursor.hide()])
    dirtyrects.extend([cursors.cursor.show()])
    pygame.display.update(dirtyrects)
    i=0
    
    while not gfx.quittest:
        dirtyrects = []
        if mov.movcursor:
            dirtyrects.extend([cursors.cursor.hide()])
        if mov.mov == None:
            event = pygame.event.wait()
        else:
            if not mov.mov.get_busy():
                mov.mov.stop()
                mov.mov = None
                mov.movcursor = 1
                gfx.surface.blit(mov.tmpmovsurface, mov.movrect.topleft)
                dirtyrects.append(mov.movrect)
                mov.triggerfn()
            else:
                pygame.event.pump()
                event = pygame.event.poll()
                if i >= nomovloop:
                    gfx.surface.blit(mov.movsurface, mov.movrect)
                    dirtyrects.append(mov.movrect)
                    i = 0
                else:
                    i = i+1
            
        if not pygame.mouse.get_focused():
            dummyVar = 1    
        elif event.type == pygame.MOUSEMOTION:
            new_cursor_zone = get_map_pos(current_hotspotmap, event.pos)
            cursors.cursor.update(event)
        elif (event.type == pygame.MOUSEBUTTONUP and mov.movcursor) or nodedata.newNode != None:
            if nodedata.newNode == None:
                nodedata.nextslide = next_view_fn(new_cursor_zone, nodedata.currentslide)
                
            else: nodedata.nextslide = nodedata.newNode
            nodedata.newNode = None
            if nodedata.nextslide != None:
                
                if nodedata.action == nodedata.nextslide:
                    nodedata.nextslide = None
                    if nodedata.hastype('action'):
                        nodedata.navData = new_cursor_zone
                        
                        nodedata.currentslide.action()

                    current_hotspotmap = gethotspotmap(nodedata.currentslide)
                    new_cursor_zone = get_map_pos(current_hotspotmap, event.pos)
                elif nodedata.nextslide == object_return:
                    gameobjects.outobjects = 1
                    gameobjects.inobjects = 0
                    
                    nodedata.nextslide = nodedata.objectreturnslide
                    
                    if gameobjects.ismovie:
                       gameobjects.playmovie = 1
                       gameobjects.ismovie = 0

            if not nodedata.nextslide == None:
                if mov.mov != None and mov.load != 1:
                    mov.mov.stop()
                    mov.mov = None
                    mov.movcursor = 1
                mov.load = 0
                
                if nodedata.hastype('onExitSlide'):
                    nodedata.currentslide.doOnExitSlide()
                if nodedata.hastype('onExit'):
                    nodedata.currentslide.onExitFn()
                
                nodedata.previousslide = nodedata.currentslide
                nodedata.currentslide = nodedata.nextslide
                
                nodedata.currentslide = showview(nodedata.currentslide)
                
                
                current_hotspotmap = gethotspotmap(nodedata.currentslide)
                if event.type != 0:
                    new_cursor_zone = get_map_pos(current_hotspotmap, event.pos)
                cursors.change_cursor(new_cursor_zone, nodedata.currentslide.contains[0], cursor_array)
                cursors.cursor.update(event)
                cursor_zone = new_cursor_zone
                     
        elif event.type == pygame.KEYUP:
            keypressed(event.key)
        
        if cursor_zone != new_cursor_zone:
            cursors.change_cursor(new_cursor_zone, nodedata.currentslide.contains[0], cursor_array)
            cursors.cursor.update(event)
            cursor_zone = new_cursor_zone
            if cursor_zone == -2 and mov.movcursor:
                gfx.menuButton(1)
                istopmenu  = 1
            elif istopmenu and cursor_zone != -2:
                gfx.menuButton(0)
                istopmenu = 0
            elif cursor_zone == -3:
                istopObjects = 1
                gameobjects.rolloverArray()
                
            elif cursor_zone != -3 and istopObjects :
                
                istopObjects = 0
                gameobjects.rolloutArray()
                
        if mov.movcursor:
            dirtyrects.extend([cursors.cursor.show()])
        pygame.display.update(dirtyrects)      
    #Game exits here uninitialize pygame                        
    pygame.quit()
