# Copyright (c) 2001 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# 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; either version 2 of the License, or (at your option) any later
# version.
#
# 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.,
# 59 Temple Place - Suite 330, Boston, MA  02111-1307
# USA.

"""
Recipe Window which contains graphical, tree and text view
Can be editable (edition of recipe) or not (plan monitoring)
"""

__revision__ = "$Id: RecipeWindow.py,v 1.52 2002/01/04 14:13:05 syt Exp $"

from gtk import *
from logilab.xmltools.XmlEditor import *
from logilab.xmltools.XmlTree import *
from xml.dom.ext import PrettyPrint
from narval.lib import NO_NS
from os.path import normpath,join
from RecipeCodes import *
from MemoryModel import MemoryModel
from narval.gui import unicode_to_gtk

class RecipeWindow(GtkWindow):
    def __init__(self,recipe,editable):

        # main window
        if editable:
            name = unicode_to_gtk(_("Recipe [%s]"))%recipe.getAttributeNS(NO_NS,'name')
        else:
            name = unicode_to_gtk(_("Plan [%s]"))%recipe.getAttributeNS(NO_NS,'name')
            
        GtkWindow.__init__(self,WINDOW_TOPLEVEL,name)

        self.connect('delete-event',self._exit_from_delete)
        
        vbox = GtkVBox()
        self.add(vbox)

        self.editable = editable
        self.current_page = 0

        # recipe model
        from RecipeModel import RecipeModel
        self.model = RecipeModel()

        # recipe controller
        from RecipeController import RecipeController
        self.controller = RecipeController(self.model,self)
        self.controller.get_count(recipe)

        # menu
        ag = GtkAccelGroup()
        self.factory = GtkItemFactory(GtkMenuBar, "<main>", ag)
        self.add_accel_group(ag)
        _scc = self.controller.callbacks
        menu_struct =[
            (unicode_to_gtk(_('/_File')),                         None,  None, 0,      '<Branch>'),
            (unicode_to_gtk(_('/_File/_Save recipe')),            None,  _scc, SV_RECIPE,      ''),
            (unicode_to_gtk(_('/_File/sep2')),                    None,  None, 0,   '<Separator>'),
            (unicode_to_gtk(_('/_File/_Close')),          '<control>C',  self.exit, 0,         ''),
            (unicode_to_gtk(_('/_Actions')),                      None,  None, ACT,    '<Branch>'),
            (unicode_to_gtk(_('/_Actions/_Undo')),                None,  _scc, UNDO,           ''),
            (unicode_to_gtk(_('/_Actions/_Redo')),                None,  _scc, REDO,           ''),
            (unicode_to_gtk(_('/_Actions/sep2')),                 None,  _scc, 0,   '<Separator>'),
            (unicode_to_gtk(_('/_Actions/Add step...')),          None,  _scc, ACT_ADD_STEP,   ''),
            (unicode_to_gtk(_('/_Actions/Remove step...')),       None,  _scc, ACT_REM_STEP,   ''),
            (unicode_to_gtk(_('/_Actions/sep2')),                 None,  _scc, 0,   '<Separator>'),
            (unicode_to_gtk(_('/_Actions/Add transition')),       None,  _scc, ACT_ADD_TRANS,  ''),
            (unicode_to_gtk(_('/_Actions/Remove transition...')), None,  _scc, ACT_REM_TRANS,  ''),
            (unicode_to_gtk(_('/_Actions/sep2')),                 None,  _scc, 0,   '<Separator>'),
            (unicode_to_gtk(_('/_Actions/Add connection')),       None,  _scc, ACT_ADD_CONNECT,''),
            (unicode_to_gtk(_('/_Actions/Remove connection')),    None,  _scc, ACT_REM_CONNECT,''),
            (unicode_to_gtk(_('/_Actions/sep2')),                 None,  _scc, 0,   '<Separator>'),
            (unicode_to_gtk(_('/_Actions/Edit properties')),      None,  _scc, ACT_EDIT_PROP,  ''),
            (unicode_to_gtk(_('/_Layout/_Simple Layout')),        None,  _scc, LAY_DEFAULT,    ''),
            (unicode_to_gtk(_('/_Layout/Layout _1 (default)')),   None,  _scc, LAY_ONE,        ''),
            (unicode_to_gtk(_('/_Layout/Layout _2')),             None,  _scc, LAY_TWO,        ''),
            (unicode_to_gtk(_('/_Help')),                         None,  None, 0,  '<LastBranch>'),
            (unicode_to_gtk(_('/_Help/_Help')),                   None,  _scc, HELP,           ''),
            (unicode_to_gtk(_('/_Help/_About')),                  None,  _scc, ABOUT,          ''),
            ]
        
        self.factory.create_items(menu_struct)
        self._menubar = self.factory.get_widget('<main>')
        self._menubar.set_shadow_type(SHADOW_NONE)
        if editable:
            self.factory.get_widget_by_action(UNDO).set_sensitive(FALSE)
            self.factory.get_widget_by_action(REDO).set_sensitive(FALSE)
            self.factory.get_widget_by_action(ACT_ADD_CONNECT).set_sensitive(FALSE)
            self.factory.get_widget_by_action(ACT_REM_CONNECT).set_sensitive(FALSE)
        else:
            self.factory.get_widget_by_action(SV_RECIPE).set_sensitive(FALSE)
            self.factory.get_widget_by_action(ACT).set_sensitive(FALSE)
        vbox.pack_start(self._menubar,expand=FALSE)

        # notebook

        self._notebook = GtkNotebook()
        self._notebook.set_tab_pos(POS_BOTTOM)
        self._notebook.connect('switch-page',self._notebook_switch)
        vbox.pack_start(self._notebook)

        # recipe graphic view
        from RecipeGraphicView import *
        self._layout = RecipeGraphicView(self.controller)
        self._layout.editable = editable
        self.model.attach_observer(self._layout)
        MemoryModel().attach_observer(self._layout)
    
        scrollwin = GtkScrolledWindow(self._layout.get_hadjustment(),self._layout.get_vadjustment())
        scrollwin.get_hadjustment().set_all(0,\
                                            scrollwin.get_hadjustment().__getattr__("lower"),\
                                            scrollwin.get_hadjustment().__getattr__("upper"),\
                                            4,0.5,0.5)
        scrollwin.get_vadjustment().set_all(0,\
                                            scrollwin.get_vadjustment().__getattr__("lower"),\
                                            scrollwin.get_vadjustment().__getattr__("upper"),\
                                            4,0.5,0.5)
        scrollwin.set_policy(POLICY_AUTOMATIC,POLICY_AUTOMATIC)
        scrollwin.add(self._layout)
    
        self._notebook.append_page(scrollwin,GtkLabel(unicode_to_gtk(_("Graphic"))))
        self.set_default_size(400,400)
        self.set_position(WIN_POS_CENTER)

        # recipe tree view
        from RecipeTreeView import *
        ig = InfoGenerator([('@id','string(@id)'),('@name','string(@name)')])
        self._tree = RecipeTreeView(editable,self.controller)
        self._tree.set_info_generator(ig)
        self.model.attach_observer(self._tree)
        self._notebook.append_page(self._tree,GtkLabel(unicode_to_gtk(_("Tree"))))

        # recipe text view
        from RecipeTextView import *
        self._text = RecipeTextView(editable,self.controller)
        self.model.attach_observer(self._text)
        self._notebook.append_page(self._text,GtkLabel(unicode_to_gtk(_("XML code"))))

        # import a recipe
        self.model.set_recipe(recipe)
        self.controller.set_document(self.model._recipe.ownerDocument)
        self.show_all()

    def adj(self,*args):
        print args[0].__getattr__("value")

    def exit(self,*args):
        # destroy dialog window before
        self.controller.callbacks(EXIT)

    def destroy_all(self,*args):
        # clean each view
        self.model.detach_observer(self._layout)
        self.model.detach_observer(self._tree)
        self.model.detach_observer(self._text)
        MemoryModel().detach_observer(self._layout)
        MemoryModel().detach_observer(self._tree)
        MemoryModel().detach_observer(self._text)
        self._tree.destroy()
        self._text.destroy()
        self._layout.destroy()
        self._notebook.destroy()
        self.model = None
        self.controller = None
        self.destroy()

    # update model
    def update_model(self):
        if self.editable:
            if self.current_page == 1:
                recipe = self._tree.tree_to_recipe()
                if recipe:
                    self.controller.update_recipe(recipe)
                    print '0', dir(recipe), id(recipe)
                else:
                    print unicode_to_gtk(_('recipe is not well formed, please correct on tree'))
            elif self.current_page == 2:
                recipe = self._text.text_to_recipe()
                if recipe:
                    print '1', dir(recipe), id(recipe)
                    self.controller.update_recipe(recipe)
                else:
                    print unicode_to_gtk(_('recipe is not well formed, please correct on text'))


    def expand_node_in_tree(self,node):
        self._notebook.set_page(1)
        self._tree.expand_node(node)

    ## Private ################################################################
    def _notebook_switch(self,*args):
        self.update_model()
        self.current_page = args[-1]

    def _exit_from_delete(self,*args):
        self.controller.has_changed = FALSE
        self.exit()
