#
#  World.py

import k

from Math   import *
from Player import *
from Level  import *
from Tools  import *

#-----------------------------------------------------------------------------------------------
#-----------------------------------------------------------------------------------------------

class World: 
    
    #-------------------------------------------------------------------------------------------
    def __init__ (self, size, flags):
        #log(size, log='startup')
        k.world = self

        self.tilesize = 16
        
        self.initScreen(size, flags)
        self.image = None
        self.oldImage = None
        self.fadeTiles = []
        
        self.resetCockpit()
        
    #-------------------------------------------------------------------------------------------
    def resetCockpit (self):
        self.fpsrect   = None
        self.scorerect = None
        self.timerect  = None                
          
    #-------------------------------------------------------------------------------------------
    # coordinates
    #-------------------------------------------------------------------------------------------
    def initScreen (self, size, flags):
        k.screen = pygame.display.set_mode(size, flags)
        pygame.display.set_caption(k.KRANK_TITLE)
        self.rect = pygame.Rect(0, 0, size[0], size[1])
        self.screen_flags = flags
        self.postInit()
        
    #-------------------------------------------------------------------------------------------
    def setScreen (self, size):
        if size != self.rect.size:
            self.image = None
            k.sound.play('exit')
            k.screen = pygame.display.set_mode(size, self.screen_flags)
            self.rect = pygame.Rect(0, 0, size[0], size[1])
            self.postInit()
            Level('menu_screen')
            k.screen.blit(k.world.image, k.screen.get_rect())
            pygame.display.flip()
    
    #-------------------------------------------------------------------------------------------
    def toggleFullscreen(self):
        if k.config.fullscreen:
            sx,sy=k.world.rect.size
            k.config.fullscreen = 0
            k.screen = pygame.display.set_mode((sx, sy), pygame.RESIZABLE);
            self.rect = pygame.Rect(0, 0, sx, sy)
            self.screen_flags = pygame.RESIZABLE
            self.postInit()
            Level('menu_screen')
            k.screen.blit(k.world.image, k.screen.get_rect())
            pygame.display.flip()
        else:
            sx,sy=k.world.rect.size
            k.config.fullscreen = 1
            k.screen = pygame.display.set_mode((sx, sy), pygame.FULLSCREEN);
            self.rect = pygame.Rect(0, 0, sx, sy)
            self.screen_flags = pygame.FULLSCREEN
            self.postInit()
            Level('menu_screen')
            k.screen.blit(k.world.image, k.screen.get_rect())
            pygame.display.flip()

    #-------------------------------------------------------------------------------------------
    # fonts
    #-------------------------------------------------------------------------------------------        
    def postInit (self):
        if os.sys.platform != 'darwin':
            pygame.display.set_gamma(1.4)
            
        self.forceFactor = 1.0-clamp((1024-self.rect.height)/1800.0, -0.15, 0.4)
        
        try:
            height = self.rect.height
            try:
                fontfile = '/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf'
                k.font['large']  = pygame.font.Font(fontfile, height//24)
                k.font['normal'] = pygame.font.Font(fontfile, height//36)
                k.font['small']  = pygame.font.Font(fontfile, 30)
                k.font['tiny']   = pygame.font.Font(fontfile, 20)
            except Exception as e:
                  log(e)
                  k.font['large']  = pygame.font.SysFont(pygame.font.get_default_font(), height//12)
                  k.font['normal'] = pygame.font.SysFont(pygame.font.get_default_font(), height//24)
                  k.font['small']  = pygame.font.SysFont(pygame.font.get_default_font(), 40)
                  k.font['tiny']   = pygame.font.SysFont(pygame.font.get_default_font(), 30)    
        except Exception as e:
          log(e)
          k.font = None
                        
    #-------------------------------------------------------------------------------------------
    # backdrop
    #-------------------------------------------------------------------------------------------
    def setBackground (self, name):
        
        self.resetCockpit()
                
        path = os.path.join('levels/unera-backgrounds', name + '.jpg')
        log(path, log='world')
        if os.path.isdir(path):
            for item in os.listdir(path):
                if os.path.splitext(item)[1].lower() in ['.jpg']:
                    file = os.path.join(path, item)
                    if os.path.isfile(file) and os.path.splitext(file)[1] in ['.jpg', '.tif']:
                        break
        else: file = path
        if not os.path.exists(file): 
            log('[ERROR] image doesn\'t exist', file)
            return
        
        if self.image and k.level.name[:11] != 'menu_levels':
            xtiles, ytiles = self.rect.width//self.tilesize+1, self.rect.height//self.tilesize+1
            self.fadeTiles = list(range(xtiles*ytiles))
            random.shuffle(self.fadeTiles)
        self.image = quadMirrorSurface(pygame.image.load(file), self.rect.size).convert()            

    #-------------------------------------------------------------------------------------------        
    def darken (self, darkness):
        darkenImage(self.image, darkness)
        
    #-------------------------------------------------------------------------------------------
    def inTransition (self):
        return len(self.fadeTiles)

    #-------------------------------------------------------------------------------------------
    def clearCockpit (self):
        updates = []
        if not self.inTransition():
            for rect in [self.timerect, self.scorerect]:
                if rect:
                    k.screen.blit(k.world.image, rect, rect)
                    updates.append(rect)
        return updates
            
    #-------------------------------------------------------------------------------------------
    # on frame
    #-------------------------------------------------------------------------------------------
    def onFrame (self, delta):
        if len(self.fadeTiles):
            rectlist = []
            for i in range(min(len(self.fadeTiles), self.rect.width//self.tilesize)):
                tilesize = self.tilesize
                tile = self.fadeTiles.pop(0)
                xtiles, ytiles = self.rect.width//tilesize+1, self.rect.height//tilesize+1
                rect = pygame.Rect((tile%xtiles)*tilesize, (tile//xtiles)*tilesize, tilesize, tilesize)
                rect = rect.clip(self.image.get_rect())
                image = self.image.subsurface(rect)
                k.screen.blit(image, rect)
                rectlist.append(rect)
            pygame.display.update(rectlist)
