#
#  $Id$
#
#  (C) Copyright 2016 Kai Sterker <kaisterker@linuxgames.com>
#  Part of the Adonthell Project http://adonthell.linuxgames.com
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License.
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY.
#
#  See the COPYING file for more details
#

import adonthell
import codecs

# -- properly encode unicode strings across python versions
def u(x): 
    result = codecs.unicode_escape_decode(x)[0]
    if not isinstance(result, str):
    	result = codecs.utf_8_encode(result)[0]
    return result

# -- pygettext support
def _(message): return adonthell.nls_translate (message)

if not "reversed" in dir(__builtins__):
    def reversed(list):
        result = []
        for x in list:
            result.insert(0, x)
        return result

# -- GUI for changing the most important game settings
class option_screen (adonthell.win_container):
    
    # -- Constructor
    def __init__(self):    
        adonthell.win_container.__init__(self)
        
        # -- list of supprted languages
        #    Default will try to use the system language
        #    English is the builtin language, so uses the C locale
        #    Others are the actual translations that are included
        
        #    note that for the language we always try to display
        #    the native form, which requires escaping any unicode
        #    characters and also fooling xgettext by splitting the
        #    actual unicode literals in 2 halves
        self.languages = [ \
            ("", _("Default")), \
            ("C", "English"), \
            ("da_DA", "Dansk"), \
            ("es_ES", u("Espa\\"+"xf1ol")), \
            ("fr_FR", u("Fran\\"+"xe7ais")), \
            ("it_IT", "Italiano"), \
            ("nl_NL", "Nederlands")]
        
        self.current_values = []
        self.config = adonthell.config()
        if not self.config.read_adonthellrc():
            return

        self.initial_language = self.config.language

        # -- get font and theme
        self.font = adonthell.win_manager_get_font ("original")
        self.theme = adonthell.win_manager_get_theme ("original")
        
        self.move (50, 55)
        self.resize (220, 120)
        self.set_border (self.theme)
        self.set_background (self.theme)
        self.set_trans_background (True)
        
        # -- list of options
        self.option_list = adonthell.win_select()
        self.option_list.move (10, 5)
        self.option_list.resize (200, 110)
        self.option_list.set_layout (adonthell.win_container_LIST_LAYOUT)
        self.option_list.thisown = 0

        # -- activate the list
        self.option_list.set_activate (True)
    
        # -- give focus to the list
        self.add(self.option_list)
        self.set_focus_object (self.option_list)
    
        self.option_list.py_signal_connect (self.save_settings, adonthell.win_event_ACTIVATE_KEY)

        if self.config.screen_mode == 0:
            screen_mode = _("Windowed")
        elif self.config.screen_mode == 1:
            screen_mode = _("Letterbox")
        else:
            screen_mode = _("Fullscreen")
            
        language = _("Default")
        for x in self.languages:
            if self.config.language == x[0]:
                language = x[1]
                break
        
        # -- add options
        self.option_list.add(self.make_option(_("Screen Mode"), screen_mode))
        self.option_list.add(self.make_option(_("Music Volume"), str(self.config.audio_volume)))
        self.option_list.add(self.make_option(_("Language"), language))
        self.option_list.add(self.make_option(None, _("Save")))

        # -- set everything visible
        self.set_visible_background (True)
        self.set_visible_border (True)
        self.set_visible_all (True)
        self.set_activate (True)

        self.py_signal_connect (self.on_update, adonthell.win_event_UPDATE)

    def language_changed(self):
        return self.initial_language != self.config.language

    def make_option(self, name, value):
        container = adonthell.win_container()
        container.thisown = 0

        if name != None:
            label1 = adonthell.win_label()
            label1.resize (0, 20)
            label1.move (4, 0)
            label1.set_font (self.font)
            label1.set_form (adonthell.label_AUTO_SIZE)
            label1.set_text (name)
            label1.pack ()
            label1.thisown = 0

            label2 = adonthell.win_label()
            label2.resize (10, 20)
            label2.move (85, 0)
            label2.set_font (self.font)
            label2.set_text ("<")
            label2.pack ()
            label2.thisown = 0

            label3 = adonthell.win_label()
            label3.resize (10, 20)
            label3.move (185, 0)
            label3.set_font (self.font)
            label3.set_text (">")
            label3.pack ()
            label3.thisown = 0

            container.add(label1)
            container.add(label2)
            container.add(label3)

        label4 = adonthell.win_label()
        label4.resize (0, 20)
        label4.set_font (self.font)
        label4.set_form (adonthell.label_AUTO_SIZE)
        label4.set_text (value)
        label4.pack ()
        label4.move (95 + (90 - label4.length())//2, 0)
        label4.thisown = 0

        self.current_values.append(label4)

        container.add(label4)        
        container.move(0, 0)
        container.resize (200, 15)
        container.set_visible_all (True)
        
        return container

    # -- save and close settings
    def save_settings(self):
        if self.option_list.get_selected_position() == 4:
            self.config.write_adonthellrc()
            adonthell.gamedata_engine ().main_quit ()
    
    # -- callback for custom updating
    def on_update (self):
        # -- pressing ESC will close settings without saving
        if adonthell.input_has_been_pushed (adonthell.SDLK_ESCAPE):
            adonthell.gamedata_engine ().main_quit ()
        elif adonthell.input_has_been_pushed (adonthell.SDLK_LEFT):
            self.change_value(-1)
        elif adonthell.input_has_been_pushed (adonthell.SDLK_RIGHT):
            self.change_value(1)

    def change_value (self, increment):
        label = None
        option = self.option_list.get_selected_position()
        
        if option == 1:
            label = self.current_values[option-1]
            # -- Screen Mode
            mode = adonthell.screen.mode() + increment
            if mode < 0: mode = 2
            if mode > 2: mode = 0
            self.config.screen_mode = mode

            if adonthell.screen.set_fullscreen(mode):
                if mode == 0: label.set_text(_("Windowed"))
                elif mode == 1: label.set_text(_("Letterbox"))
                else: label.set_text(_("Fullscreen"))
        
        elif option == 2:
            # -- Volume
            if self.config.audio_volume == 0 and increment < 0 or \
               self.config.audio_volume == 100 and increment > 0:
                return 
            
            self.config.audio_volume = self.config.audio_volume + increment
            if self.config.audio_volume == 0:
                adonthell.audio.cleanup()
            elif self.config.audio_volume == 1:
                adonthell.audio.init(self.config)
            else:
                adonthell.audio.set_background_volume(self.config.audio_volume)
                
            label = self.current_values[option-1]
            label.set_text(str(self.config.audio_volume))

        elif option == 3:
            # -- Language
            label = self.current_values[option-1]
            language = label.text_char()
            new_language = self.languages[0]
            
            if increment < 0:
                prev = self.languages[-1]
                for x in self.languages:
                    if language == x[1]:
                        new_language = prev
                        break
                    prev = x
            else:
                next = self.languages[0]
                for x in reversed(self.languages):
                    if language == x[1]:
                        new_language = next
                        break
                    next = x

            self.config.language = new_language[0]
            adonthell.nls_set_language(new_language[0])
            label.set_text(new_language[1])

        if label != None:
            label.move (100 + (80 - label.length())//2, 0)
            label.pack()
            