# appscreen.py - Copyright (C) 2012 Red Hat, Inc.
# Written by Darryl L. Pierce <dpierce@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA  02110-1301, USA.  A copy of the GNU General Public License is
# also available at http://www.gnu.org/copyleft/gpl.html.

from snack import ButtonBar
from snack import Grid
from snack import GridForm
from snack import Label
from snack import SnackScreen

BACK_BUTTON   = "back"
NEXT_BUTTON   = "next"
CANCEL_BUTTON = "cancel"
FINISH_BUTTON = "finish"

class ApplicationScreen:
    '''
    The ApplicationScreen is the background window displayed by an
    application. Only one instance of this class is presented.

    An application can override this screen by extending this class
    and then overriding the Application.create_app_screen() method.
    '''

    def __init__(self, app):
        self.app = app
        self.screen_width = 0
        self.screen_height = 0

    def show_current_page(self):
        '''
        Shows the current application page.
        '''
        screen = SnackScreen()
        page = self.app.get_current_page()

        gridform = GridForm(screen, page.get_title(), 4, 1)

        button_bar = self.get_button_bar(screen, page)
        content    = self.get_content(screen, button_bar, page)

        # if we're full screen then move to full height
        if self.app.get_fullscreen():
            fullheight = screen.height
            gridform.add(Label(""), 0, 0,
                         padding = (0, (fullheight / 2) - 4,
                                    0, (fullheight / 2) - 4),
                         growy = 1)
            gridform.add(Label("  "), 2, 0, anchorTop = 1)
        gridform.add(content, 3, 0, anchorTop = 1)

        # run the page
        topx = topy = None
        if self.app.get_fullscreen():
            topx = topy = 2
        result = gridform.runOnce(topx, topy)
        pressed = button_bar.buttonPressed(result)

        screen.popWindow()
        screen.finish()

        if pressed == FINISH_BUTTON or pressed == CANCEL_BUTTON:
            self.app.set_finished(True)
            if pressed == CANCEL_BUTTON:
                self.app.set_cancelled(True)
        elif pressed == BACK_BUTTON:
            self.app.previous_page()
        elif pressed == NEXT_BUTTON:
            self.app.next_page()
        else:
            # TODO: in future have applicaton-specific button handling
            raise Exception("Unsupported button: %s" % pressed)

    def get_content(self, screen, button_bar, page):
        '''
        Renders the current page.
        '''
        elements = page.get_elements(screen)
        if elements == None:
            raise AttributeError("No page elements defined.")
        content = Grid(1, len(elements) + 2)
        current_element = 0
        for element in elements:
            content.setField(element, 0, current_element, anchorLeft = 1)
            current_element += 1

        # if we're going to be fullscreen then page it out
        if self.app.get_fullscreen():
            fullwidth = screen.width
            content.setField(Label(""), 0, len(elements),
                             padding = ((fullwidth / 2) - 4, 2,
                                        (fullwidth / 2) - 4, 2),
                             growx = 1)

        # add the button bar
        content.setField(button_bar,
                         0, page.get_element_count() + 1,
                         anchorLeft = 1, growx = 0)

        return content

    def get_button_bar(self, screen, page):
        '''
        Adds the buttons that the page requires to the form.
        '''
        buttons = []
        if page.has_previous_button():
            buttons.append(["Back", BACK_BUTTON, "F11"])
        if page.has_next_button():
            buttons.append(["Next", NEXT_BUTTON, "F12"])
        if page.has_finish_button():
            buttons.append(["Finish", FINISH_BUTTON, "F10"])
        if page.has_cancel_button():
            buttons.append(["Cancel", CANCEL_BUTTON, "ESC"])

        compact = 0
        if self.app.get_compact_buttons():
            compact = 1

        return ButtonBar(screen, buttons, compact = compact)
