# GNU Enterprise Forms - Curses UI Driver - Grid 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: grid.py 9956 2009-10-11 18:54:57Z reinhard $

import curses

from gnue.forms.uidrivers.curses.widgets import _base

__all__ = ['UIGrid']

# =============================================================================
# Grid widget class
# =============================================================================

class UIGrid(_base.UIHelper):
    """
    Interface implementation for <grid> widgets.
    """

    # -------------------------------------------------------------------------
    # Constructor
    # -------------------------------------------------------------------------

    def __init__(self, event):

        _base.UIHelper.__init__(self, event)

        self._column_header_ = {}               # Labels per column header
        self.__max = 0
        self.__visible = 0


    # -------------------------------------------------------------------------
    # Widget creation
    # -------------------------------------------------------------------------

    def _create_widget_(self, event, spacer):

        _base.UIHelper._create_widget_(self, event, spacer)
        self._parent = event.container
        self._container = self._parent

        self.__max = self._gfObject.rows
        self.__visible = self.__max

        return None


    # -------------------------------------------------------------------------
    # UI event handler
    # -------------------------------------------------------------------------

    def _ui_adjust_scrollbar_(self, *args):
        pass


    # -------------------------------------------------------------------------
    # Set the size for the grid and it's children
    # -------------------------------------------------------------------------

    def set_size_and_fit(self, width, height):

        self.width = width
        self.height = height

        # The header rows are not available to the grid's children
        i_height = num_recs = height - len(self._children)

        if num_recs > self.__visible:
            self.__add_new_records(num_recs - self.__visible)
            self._gfObject._event_rows_changed(self.__visible)

        elif num_recs < self.__visible:
            self.__hide_records(self.__visible - num_recs)
            self._gfObject._event_rows_changed(self.__visible)

        self._repaint_()

        for (row, child) in enumerate(self._children):
            child.left = self.left
            child.top = self.top + row

            child.set_size_and_fit(width, i_height)


    # -------------------------------------------------------------------------
    # Get the size hints for an entry
    # -------------------------------------------------------------------------

    def get_size_hints(self, vertical=None):

        hints = []
        for child in self._children:
            hints.append(child.get_size_hints())

        minw = max([i[0] for i in hints])
        minh = len(self._children) + self._gfObject.rows + 1

        return (minw, minh, 0, self.stretch)


    # -------------------------------------------------------------------------
    # Repaint the widget
    # -------------------------------------------------------------------------

    def _repaint_(self):

        for row in range(self.height):
            self._parent.write(self.left, self.top + row, ' ' * self.width,
                    self._uiDriver.attr['background'])


    # -------------------------------------------------------------------------
    # Add new rows to the grid
    # -------------------------------------------------------------------------

    def __add_new_records(self, num_recs):

        for index in range(num_recs):
            record = self.__visible + index
            if record >= self.__max:
                self.walk(self.__child_add_walker, record)
                self.__max += 1
            else:
                self.__change_visibility(record, True)

        self.__visible += num_recs


    # -------------------------------------------------------------------------
    # Create all child widgets for a new row
    # -------------------------------------------------------------------------

    def __child_add_walker(self, item, spacer):

        if item != self:
            widget = item.create_widget(item._creationEvent, spacer)
            item.widgets.append(widget)


    # -------------------------------------------------------------------------
    # Show or hide grid lines
    # -------------------------------------------------------------------------

    def __change_visibility(self, record, state):
        pass


    # -------------------------------------------------------------------------
    # Hide a given number of rows
    # -------------------------------------------------------------------------

    def __hide_records(self, num_recs):

        for index in range(num_recs):
            self.__change_visibility(self.__visible-1, False)
            self.__visible -= 1


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

configuration = {
  'baseClass'  : UIGrid,
  'provides'   : 'GFGrid',
  'container'  : 1,
}
