#
#  Config.py

import k, levels

from Krank  import *
from Sound  import *
from Level  import *
from Tools  import *

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

class Config (dict):
    
    def __init__(self):
        #log(log='startup')
        self['music_volume'] = 1.0
        self['sound_volume'] = 1.0
        self['scores'] = [[], [], [], []]
        self['stage'] = 1
        self['screen'] = ()
        self['totalTime'] = 0
        self['stageTime'] = [0,0,0,0]
        self['totalSolved'] = [0,0,0,0]
        self.stage = 1
        
        k.config = self
        
        self.load()
        
    #-------------------------------------------------------------------------------------------
    def score (self, level):
        si = k.level.isBonus() and 4 or self.stage-1
        li = k.level.isBonus and self.stage-1 or level-1

        # stats
        self['totalTime']       += k.level.time/1000
        self['stageTime'][si]   += k.level.time/1000
        self['totalSolved'][si] += 1

        # failsafe
        while len(self['scores']) < self.stage:
            self['scores'].append([])
        
        while len(self['scores'][si]) < level:
            self['scores'][si].append({'time': sys.maxint, 'score': sys.maxint})
                    
        if self['scores'][si][li]['time'] == 0: self['scores'][si][li]['time']  = sys.maxint

        # first time level solved 
        if self['scores'][si][level-1]['score'] == sys.maxint:
            self.makeLevelAvailable()

        # update scores
        secs = k.level.time/1000

        self['scores'][si][li]['time']  = min(self['scores'][si][li]['time'], secs)
        self['scores'][si][li]['score'] = min(self['scores'][si][li]['score'], int(k.score))
        
        if level == levels.numLevels:
            self.stage = min(3, self.stage+1)
            if len(self['scores']) < self.stage:
                self['scores'].append([])
            self['stage'] = self.stage
            log('stage', self.stage)
        
        self.save()
        
    #-------------------------------------------------------------------------------------------
    def abort (self):
        si = k.level.isBonus() and 4 or self.stage-1
        self['totalTime']     += k.level.time/1000
        self['stageTime'][si] += k.level.time/1000
        
    #-------------------------------------------------------------------------------------------
    def makeLevelAvailable (self):
        for i in range(2):
            for stage_index in range(3):
                scores = self['scores'][stage_index]
                if len(scores) < levels.numLevels:
                    scores.append({'time': sys.maxint, 'score': sys.maxint})
                    break
            
    #-------------------------------------------------------------------------------------------
    def apply(self):
        k.sound.musicVolume = self['music_volume']
        k.sound.soundVolume = self['sound_volume']
        
    #-------------------------------------------------------------------------------------------
    def getConfigFilePath(self):
        if os.sys.platform == 'darwin':
            return os.path.expanduser('~/Library/Preferences/krank.cfg')
        else:
            return os.path.join(os.environ['APPDATA'], 'krank.cfg')
        
    #-------------------------------------------------------------------------------------------
    def save(self):
        self['music_volume'] = k.sound.musicVolume
        self['sound_volume'] = k.sound.soundVolume
        self['screen']       = k.world.rect.size
        try:
            config_file = self.getConfigFilePath()
            log('writing config to', config_file, log='config')
            log(self, log='config')
            file = open(config_file, 'w+')
            cPickle.dump(self, file)
        except Exception, e:
            log(e)
        
    #-------------------------------------------------------------------------------------------
    def load(self):
        try:            
            config_file = self.getConfigFilePath()
            log('reading config from', config_file, log='config')
            log(self, log='config')
            file = open(config_file, 'r')
            self.update(cPickle.load(file))
            self.stage = self['stage']
            while len(self['scores']) < 4: self['scores'].append([])
            log(self, log='config')
        except Exception, e:
            log(e)
        
    #-------------------------------------------------------------------------------------------
    def bestTimeString (self, level=0, stage=0):
        time = self.bestTime(level, stage)
        if time < sys.maxint/1000:
            return k.level.timeString(time)
        return ""

    #-------------------------------------------------------------------------------------------
    def bestScoreString (self, level=0, stage=0):
        score = self.bestScore(level, stage)
        if score < sys.maxint:
            return "%d" % score
        return ""
        
    #-------------------------------------------------------------------------------------------
    def bestTime (self, level=0, stage=0):
        score = self.getScore(level, stage)
        return score['time']
        
    #-------------------------------------------------------------------------------------------
    def bestScore (self, level=0, stage=0):
        score = self.getScore(level, stage)
        return score['score']
    
    #-------------------------------------------------------------------------------------------
    def getScore (self, level=0, stage=0):
        if not stage:
            stage = self.stage
        if not level:
            level = k.level.number
        return self['scores'][stage-1][level-1]
    
    #-------------------------------------------------------------------------------------------
    def setStage (self, stage):
        if stage <> self.stage:
            k.sound.play('exit')
            self.stage = stage
            self.save()
            Level('menu_levels')
            
    #-------------------------------------------------------------------------------------------
    def lastSolvedLevel (self, stage=0):
        if not stage:
            stage = self.stage
        scores = self['scores'][stage-1]
        for index in range(-1, -len(scores), -1):
            score = scores[index]
            if score['score'] < sys.maxint:
                return len(scores)+index+1
        return 0
    
    #-------------------------------------------------------------------------------------------
    def numAvailableLevels (self, stage=0):
        if not stage:
            stage = self.stage
        return min(levels.numLevels, len(self['scores'][stage-1]))
    
    #-------------------------------------------------------------------------------------------
    def numSolvedLevels (self, stage=0):
        if not stage:
            stage = self.stage
        return len([s for s in self['scores'][stage-1] if s['score'] < sys.maxint])
    
    