from functools import partial

from core.ui import boolStr, DialogUi

from siege import game, States
from siege.util import PixelRect
from siege.world import World


class OptionUi(DialogUi):
    def __init__(self):
        DialogUi.__init__(self, 'info', PixelRect(400, 40, 300, 400))
        self.load('html/option.html')
        self.view.register('settingsClick', self.onSettingsClick)
        self.view.register('tutorialClick', self.onTutorialClick)
        self.view.register('saveAndExitClick', self.onSaveAndExitClick)

        #Settings handlers
        self.view.register('populate', partial(OptionUi.onPopulate))
        self.view.register('applyClick', OptionUi.onApplyClick)
        self.view.register('okClick', self.onOkClick)
        self.view.register('cancelClick', self.onCancelClick)
        self.view.onHide.listen(self.hide)
        self.isAtMain = True

    def update(self, frameTime):
        pass

    def hide(self):
        super(OptionUi, self).hide()
        if not self.isAtMain:
            self.view.resize(300, 400)
            self.load('html/option.html')
            self.isAtMain = True

    def onSettingsClick(self, view, args):
        self.load('html/settings.html')
        self.isAtMain = False

    def onTutorialClick(self, view, args):
        self.view.resize(800, 700)
        self.load('html/tutorial.html')
        self.isAtMain = False

    def onSaveAndExitClick(self, view, args):
        game.onUpdate.listen(self.saveAndExit)

    def saveAndExit(self, frameTime):
        World.get().save(asynchronous=False)
        #Reset some things...
        World.reset()
        game.gui.reset()
        game.network.reset()
        game.scene.transition(States.MENU)
        return True

    @staticmethod
    def onPopulate(view, args):
        commands = []
        first = ''
        settings = game.settings
        for resolution in settings.commonResolutions:
            resolutionText = settings.getResolutionText(*resolution)
            commands.append("App.resolutions.pushObject('{}');".format(resolutionText))
            if not first:
                first = resolutionText
        windowSize = game.render.getWindowSize()
        if (windowSize.x, windowSize.y) in settings.commonResolutions:
            resolutionText = settings.getCurrentResolutionText()
        else:
            resolutionText = first
        commands.append("App.settings.set('resolution', '{}');".format(resolutionText))
        commands.append("App.settings.set('fullscreen', {});".format(boolStr(settings.fullscreen)))
        commands.append("App.settings.set('master', {});".format(game.audio.masterVolume))
        commands.append("App.settings.set('music', {});".format(game.audio.musicVolume))
        commands.append("App.settings.set('sfx', {});".format(game.audio.sfxVolume))
        commands.append("App.settings.updateVolumeControls();")
        view.execute(commands)

    @staticmethod
    def onApplyClick(view, args):
        settings = args[1].toObject()
        masterVolume = settings.getProperty('master').toInteger()
        musicVolume = settings.getProperty('music').toInteger()
        sfxVolume = settings.getProperty('sfx').toInteger()
        fullscreen = settings.getProperty('fullscreen').toBoolean()
        resolution = settings.getProperty('resolution').toString()
        game.settings.apply(resolution, fullscreen, masterVolume, musicVolume, sfxVolume)
        game.settings.save()

    def onOkClick(self, view, args):
        self.onApplyClick(view, args)
        self.onCancelClick(view, args)

    def onCancelClick(self, view, args):
        self.load('html/option.html')
