# GNU Enterprise Forms - Curses UI Driver - Page Widget
#
# Copyright 2000-2009 Free Software Foundation
#
# This file is part of GNU Enterprise.
#
# GNU Enterprise 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; either
# version 3, or (at your option) any later version.
#
# GNU Enterprise 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 program; see the file COPYING. If not,
# write to the Free Software Foundation, Inc., 59 Temple Place
# - Suite 330, Boston, MA 02111-1307, USA.
#
# $Id: page.py 9956 2009-10-11 18:54:57Z reinhard $

import curses

from gnue.common.apps import i18n
from _base import ManagedBox

# =============================================================================
# Page class
# =============================================================================

class UIPage(ManagedBox):

    vertical = True
    enough_space = False


    # -------------------------------------------------------------------------
    # Initialize page
    # -------------------------------------------------------------------------

    def _create_widget_(self, event, spacer):

        ManagedBox._create_widget_(self, event, spacer)

        caption = getattr(self._gfObject, 'caption', None) or \
                self._gfObject.name

        self.__window = None
        self.__cursor = (0, 0)
        self._container = self

        event.parent.add_page(self, caption)


    # -------------------------------------------------------------------------
    # Virtual methods
    # -------------------------------------------------------------------------

    def _container_is_ready_(self):

        return self.__window is not None


    # -------------------------------------------------------------------------
    # Get the minimum space required by a page
    # -------------------------------------------------------------------------

    def get_size_hints(self, vertical=True):
        """
        The space requirements of a page in a managed form is made up of the
        space needed by all it's children.  In a positioned layout the space
        available to (or needed by) a page is defined by the <layout> tag.
        """

        if self.managed:
            return ManagedBox.get_size_hints(self, vertical)
        else:
            return (self._gfObject._layout.Char__width,
                    self._gfObject._layout.Char__height, 0, 0)


    # -------------------------------------------------------------------------
    # Set the page sizes and fit their children
    # -------------------------------------------------------------------------

    def set_size_and_fit(self, width, height):

        self.width = width
        self.height = height
        
        (minw, minh, label, prop) = self.get_size_hints(True)

        if minw > width or minh > height:
            self.__not_enough_space()
            self.enough_space = False

        else:
            self.enough_space = True

            if not self.managed:
                self._add_decoration_()

                for child in self._children:
                    child.left = child.chr_x
                    child.top = child._gfObject.Char__y

                    child.set_size_and_fit(child.chr_w, child.chr_h)
            else:
                ManagedBox.set_size_and_fit(self, width, height)


    # -------------------------------------------------------------------------
    # Write a text to a given position
    # -------------------------------------------------------------------------

    def write(self, x, y, text, attribute):

        if self.ready():
            try:
                if isinstance(text, basestring):
                    self.__window.addstr(y, x, o(text), attribute)
            except curses.error:
                pass


    # -------------------------------------------------------------------------
    # Write a special character to a given position
    # -------------------------------------------------------------------------

    def putchar (self, x, y, char, attribute):

        if self.ready():
            try:
                self.__window.addch (y, x, char, attribute)
            except curses.error:
                pass

    # -------------------------------------------------------------------------
    # Move the cursor to a given position
    # -------------------------------------------------------------------------

    def move(self, x, y):

        self.__cursor = (x, y)

    # -------------------------------------------------------------------------
    # Update screen and wait for user input
    # -------------------------------------------------------------------------

    def wait(self):

        try:
            self.__window.move(self.__cursor[1], self.__cursor[0])
            self.__window.refresh(0, 0, self.top, self.left, self.bottom,
                self.right)
        except curses.error:
            pass

        return self._uiDriver.get_key(self.__window)


    # -------------------------------------------------------------------------
    # Repaint this page
    # -------------------------------------------------------------------------

    def repaint(self, immediate=True):

        try:
            if immediate:
                self.__window.refresh(0, 0, self.top, self.left, self.bottom,
                    self.right)
            else:
                self.__window.noutrefresh(0, 0, self.top, self.left,
                        self.bottom, self.right)

        except curses.error:
            pass


    # -------------------------------------------------------------------------
    # Virtual methods
    # -------------------------------------------------------------------------

    def _add_decoration_(self):
        """
        A page has no decoration but a curses window.
        """

        self.__window = curses.newpad(self.height, self.width)
        self.__window.keypad(1)
        self.__window.bkgd(' ', self._uiDriver.attr['background'])

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

    def _get_upper_left_(self):
        """
        The upper left corner of a page is always 0/0 since the page provides
        it's own window.
        """
        return (0, 0)

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

    def _add_child_(self, child, index, last_x, last_y):
        """
        Add a child widget to the page
        """

        cwidth, cheight = self._sizes_[index]
        child.left = self.left + self._horizontal_offset_()
        child.top = last_y + self._vertical_offset_()

        return (0, cheight)


    # -------------------------------------------------------------------------
    # There is not enough space left to show the entire page
    # -------------------------------------------------------------------------

    def __not_enough_space(self):

        text = u_("Not enough space available to display the page.")
        self._add_decoration_()
        self.write(0, 0, text, self._uiDriver.attr['background'])
        


# =============================================================================
# Configuration data
# =============================================================================

configuration = {
  'baseClass'  : UIPage,
  'provides'   : 'GFPage',
  'container'  : 1,
}
