import sys
import cmd
import pdb
import io
import settingsManager
import spriteManager
import pygame
import pygcurse

class debugConsole(pdb.Pdb):
    def __init__(self, _surface, _gameEnv, _font="unifont-9.0.02", _size=16, _height=24):
        self.game_env = _gameEnv
        text_dims = pygame.font.Font(settingsManager.createPath(_font+".ttf"),_size).size(" ") #Used to determine how much space is available
        self.text_width = int(_surface.get_width()/text_dims[0])
        self.render_corner = [0, _surface.get_height()-text_dims[1]*_height]
        self.pyg_surface = pygcurse.PygcurseSurface(self.text_width, _height, pygame.font.Font(settingsManager.createPath(_font+".ttf"),_size))
        self.pyg_surface.setscreencolors(fgcolor=None, bgcolor=None, clear=True)
        pdb.Pdb.__init__(self, stdin=self, stdout=self.pyg_surface) #Yay for duck typing
        self.use_rawinput = False
        self.prompt = "> "

    def display(self):
        self.game_env.draw()
        self.pyg_surface.update()
        self.pyg_surface.blitto(self.game_env.screen, self.render_corner)
        pygame.display.update()

    def postcmd(self, _stop, _line):
        self.display()
        return pdb.Pdb.postcmd(self, _stop, _line)

    def interaction(self, frame, traceback):
        self.setup(frame, traceback)
        self.cmdloop("Welcome to the debug console. For help, type '?'. ")
        self.forget()

    #Shamelessly copied and modified from pygcurses. See pygcurse.py for license details. 
    def readline(self):
        clock = pygame.time.Clock()
        inputObj = pygcurse.PygcurseInput(self.pyg_surface)
        self.pyg_surface.inputcursor = inputObj.startx, inputObj.starty

        while True: # the event loop
            self.pyg_surface._inputcursormode = inputObj.insertMode and 'insert' or 'underline'

            for event in pygame.event.get((pygame.KEYDOWN, pygame.KEYUP, pygame.QUIT)): # TODO - handle holding down the keys
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type in (pygame.KEYDOWN, pygame.KEYUP):
                    inputObj.sendkeyevent(event)
                    if inputObj.done:
                        return ''.join(inputObj.buffer)

            inputObj.update()
            self.display()

            clock.tick(60)

    def emptyline(self):
        pass #Don't want to cause problems

    def do_setdamage(self, _args):
        """Sets the damage of a fighter to a value.\nSyntax: setdamage <player_num> <value>\nNote that player_num is zero indexed."""
        split_args = _args.split(' ')
        if len(self.game_env.current_fighters) > int(split_args[0]):
            dmg = max(0,min(999,int(split_args[1]))) #clamp it between 0 and 999
            self.game_env.current_fighters[int(split_args[0])].damage = dmg 
            self.pyg_surface.write('Setting player '+split_args[0]+' damage to '+str(dmg)+'\n')
        else: self.pyg_surface.write('Could not find player '+split_args[0]+'\n')
        return False

    def do_advance(self, _args):
        """Advances the game the given number of frames.\nSyntax: advance <num_frames>"""
        #TODO: Allow stepping without an argument
        if _args == '': _args = '1'
        split_args = _args.split(' ')
        num_frames = int(split_args[0])
        frames_advanced = 0
        if num_frames > 0:
            for frame in range(num_frames):
                self.game_env.debug_mode = False
                self.game_env.gameEventLoop()
                frames_advanced += 1
                if self.game_env.exit_status != 0:
                    break
            self.game_env.debug_mode = True
            self.pyg_surface.write('Advanced '+split_args[0]+' frames\n')
            return self.game_env.exit_status != 0
        elif num_frames == 0:
            self.pyg_surface.write('Advanced 0 frames\n')
            return False
        elif num_frames < 0:
            self.pyg_surface.write('Can\'t advance negative frames\n')
            return False