# GNU Enterprise Forms - HTML UI Driver - base class for UI widgets
#
# Copyright 2001-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: _base.py 8810 2006-10-17 10:11:19Z reinhard $

import types
from gnue.common import events
from gnue.common.apps import i18n
from gnue.forms.GFForm import *
from gnue.forms.uidrivers._base.widgets._base import UIWidget
from gnue.forms.uidrivers.html.common import *
from gnue.forms.uidrivers.html.Generator import *

# =============================================================================
# This class implements the common behaviour of HTML widgets
# =============================================================================

class UIHelper (UIWidget):
    """
    Implements the common behaviour of HTML widgets
    """


    def __repr__(self):
        return "UIHelper: %s" % self._type

    # ---------------------------------------------------------------------------
    # Create a new HTML widget
    # ---------------------------------------------------------------------------

    def _create_widget_ (self, event, spacer):
        """
        This function creates a new HTML widget and adds it to the cross reference
        table.
        """
        gfObject           = event.object
        self._eventHandler = event.eventHandler

        if hasattr (gfObject, 'Char__y'):
            posY = gfObject.Char__y
            gap  = gfObject._gap + 1
            self.itemY = (posY + spacer * gap) * event.widgetHeight

        if hasattr (gfObject, 'Char__height'):
            self.itemHeight = gfObject.Char__height * event.widgetHeight

        newWidget = self._create_widget (event, spacer)
        if event.initialize:
            self._addToCrossRef (newWidget, gfObject, self)

        return newWidget


    # ---------------------------------------------------------------------------
    # Add a widget to the cross reference tables
    # ---------------------------------------------------------------------------

    def _addToCrossRef (self, widget, gfobject, uiobject):
        self._uiDriver._WidgetToGFObj [widget._id] = gfobject
        self._uiDriver._WidgetToUIObj [widget._id] = uiobject
        self._uiDriver._IdToWidget [widget._id] = widget


    # ---------------------------------------------------------------------------
    # Remove a widget from the cross reference tables
    # ---------------------------------------------------------------------------

    def _deleteFromCrossRef (self, widget, object):
        try:
            del self._uiDriver._WidgetToGFObj [widget._id]
            del self._uiDriver._WidgetToUIObj [widget._id]
            del self._uiDriver._IdToWidget [widget._id]

        except:
            pass


    # ---------------------------------------------------------------------------
    # Get the index of an widget by its widget ID
    # ---------------------------------------------------------------------------

    def _index_for_id(self, widget_id):
        index=0
        for i in self.widgets:
            if i._id == widget_id:
                return index
            index=index+1

        return 0

    # ---------------------------------------------------------------------------
    # Handle focus signals from widgets
    # ---------------------------------------------------------------------------

    def _on_focus_in (self, widget_id):
        assert gDebug (6, "FOCUS-IN-EVENT: %s" % (widget_id))
        gfObject = self._uiDriver._WidgetToGFObj [widget_id]
        gfObject._event_set_focus(self._index_for_id (widget_id))


    # ---------------------------------------------------------------------------
    # Set the focus to a given widget
    # ---------------------------------------------------------------------------

    def _ui_set_focus_ (self, index):
        """
        This function set's the focus to the HTML-widget specified by index. If the
        widget has a focusHandler it will be blocked and unblocked to prevent a
        recursion. The focused widget will have a highlight color if it is set
        in gnue.conf.
        """
        widget = self.widgets [index]
        assert gDebug (6, "indexed_focus: %s [%s]" % (widget, index))

        widget.grab_focus()

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

    def _ui_focus_in_(self, index):

        # FIXME: Can we remove this method?
        # Change the background of a widget if requested via gnue.conf
        widget = self.widgets [index]


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

    def _ui_focus_out_(self, index):

        # FIXME: Can we remove this method?
        widget = self.widgets[index]
        assert gDebug (6, "Lose focus: %s" % widget)

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

    def _ui_set_current_row_(self, index):
      
        pass


    # ---------------------------------------------------------------------------
    # Set the value of a widget
    # ---------------------------------------------------------------------------

    def _ui_set_value_ (self, index, value):
        """
        This function sets the value of a widget and optionally enables or disables
        the widget.
        """
        widget = self.widgets [index]
        assert gDebug (6, "set_value %s [%s] %s" % (repr (value), index, widget))

        if widget.style!="checkbox" and type (value) != types.UnicodeType:
            assert gDebug (6, "converting %s to unicode using %s" % \
                (repr (value), gConfigForms ('textEncoding')))
            value = unicode (value, gConfigForms ('textEncoding'))

        gfObject = self._uiDriver._WidgetToGFObj [widget._id]

        if hasattr(widget,"set_value"):
            widget.set_value (value)


    # ---------------------------------------------------------------------------
    # Make sure a string will be converted into unicode
    # ---------------------------------------------------------------------------

    def _makeSafe (self, value):
        if isinstance (value, types.StringType):
            value = unicode (value, i18n.encoding)
        return value




class HtmlWidget:

    def __repr__(self):
        return "Html Widget: %s" % self._type

    def __init__(self, parent, uidriver, type, dhtml, id):
        self.dhtml = dhtml
        self.value = None
        self._type = type
        self._parent = parent
        self._children = []

        if parent:
            parent._children.append(self)

        self._uiDriver = uidriver
        self._id = id
        self._disabled = False
        if type=="FORM":
            self.pno=1

    def get_html(self):
        if self._type == "PAGE" or self._type == "BOX":
            dhtml = self.dhtml
            for child in self._children:
                dhtml += child.get_html()
            return dhtml

        elif self._type == "FORM":  # DIALOG
            pno=0
            pages=u""
            header=u""
            footer=u""
            for child in self._children:
                # self.dhtml = self.dhtml % ("CT: %s<BR>%%s" % child._type)

                if child._type == "PAGE":
                    try:
                        gfObj=self._uiDriver._WidgetToGFObj[child._id]
                        pagename=u"%s" % (gfObj.name and gfObj.name or pno)
                    except:
                        pagename = u"%s" % pno
                    pages+=build_page(u"page_%s" % pno, pagename, child.get_html())
                    pno+=1

            if hasattr(self,"MenuBar"):
                header = header + self.MenuBar.get_html()

            if hasattr(self,"ToolBar"):
                header = header + self.ToolBar.get_html()

            if hasattr(self,"StatusBar"):
                footer = footer + self.ToolBar.get_html()

            return build_form("GNUe Forms", header, pages, footer)

        else:
            return self.dhtml

    def GetId(self):
        return self._id

    def set_value(self, value):
        if value != None:
            self.value = value
        else:
            self.value = u""

        self._send_update(["set","%s" % self._id,self.value])

    def set_sensitive(self, enabled):
        self._send_update(["disable","%s" % self._id,not(enabled)])
        self._disabled = not(enabled)

    def set_active(self, active):
        self._send_update(["activate","%s" % self._id, active])
        self._active = active

    def grab_focus(self):
        self._send_update(["grab_focus","%s" % self._id,""])

    def _send_update(self, update):
        try:
            p = self._parent
            while p._type != "FORM" and p._type!="DIALOG":
                p=p._parent
            p.updates.append(update)
        except:
            print "couldn't sent update %s"

