# Purpose: Setup and initialize the core gui interfaces
#
# $Id: menupane.rb,v 1.3 2003/06/24 05:23:33 richkilmer Exp $
#
# Authors:  Curt Hibbs <curt@hibbs.com>
# Contributors:
#
# This file is part of the FreeRIDE project
#
# This application is free software; you can redistribute it and/or
# modify it under the terms of the Ruby license defined in the
# COPYING file.
#
# Copyright (c) 2001 Curt Hibbs. All rights reserved.
#

module FreeRIDE
  module FoxRenderer
  
    ##
    # This is the module that renders menupanes using
    # FOX.
    #
    class MenuPane
      include Fox
      
      extend FreeBASE::StandardPlugin
      
      def MenuPane.start(plugin)
        component_slot = plugin["/system/ui/components/MenuPane"]
        
        component_slot.subscribe do |event, slot|
          if (event == :notify_slot_add && slot.parent == component_slot)
            Renderer.new(plugin, slot)
          end
        end
        
        component_slot.each_slot { |slot| slot.notify(:notify_slot_add) }
      
=begin      
        plugin["/system/ui/components/MenuPane"].subscribe do |event, slot|
          Renderer.new(plugin, slot) if event == :notify_data_set
        end
        
        # Force notification events for any slots that existed before we subscribed
        plugin["/system/ui/components/MenuPane"].each_slot { |slot| slot.notify(:notify_data_set) } 
=end        
        # Now only is this plugin running
        plugin.transition(FreeBASE::RUNNING)
      end
      
      ##
      # Each instance of this class is responsible for rendering an menupane component
      #
      class Renderer
        include Fox
        attr_reader :plugin
        
        def initialize(plugin, slot)
          @plugin = plugin
          @slot = slot
          @menu = nil
          @main_window = nil
          
          @command_map = Hash.new(nil)
          slot.attr_FXMenuPane = @menu
          @slot.subscribe do |event, slot|
            update(event) if (event == :refresh)
          end
          # Fake a notification event to create the menu pane
          update(:refresh)
        end
        
        ##
        # Called whenever the menupane may need to be updated.
        #
        def update(event)
          # rebuild the menu pane
          @main_window = @plugin["/system/ui/fox/FXMainWindow"].data if (@main_window == nil)
          @menu.detach() unless @menu == nil
          @menu = FXMenuPane.new(@main_window)
          @slot.attr_FXMenuPane = @menu
          @slot.manager.each_command do | cmd_slot, text, description, available, accelerator |
            begin
              if text == "SEPARATOR"
                FXMenuSeparator.new(@menu)
              else
                menu_text = text
                menu_text += "\t"
                menu_text += accelerator
                menu_text += "\t"
                menu_text += description if description
                menu_text = menu_text.strip
                FXMenuCommand.new(@menu, menu_text) do |menuitem|
                  menuitem.disable unless available
                  menuitem.check if cmd_slot.attr_check
                  menuitem.connect(SEL_COMMAND) { cmd_slot['actions/select'].invoke }
                  cmd_slot.subscribe do |event, slot|
                    if slot==cmd_slot && event==:notify_attribute_set
                      enabled = cmd_slot.attr_enable
                      unless enabled.nil?
                        if cmd_slot.attr_enable
                          menuitem.enable 
                        else
                          menuitem.disable
                        end
                      end
                      checked = cmd_slot.attr_check
                      unless checked.nil?
                        if checked
                          menuitem.check
                        else
                          menuitem.uncheck
                        end
                      end
                    end
                  end
                end
              end
            rescue => e
              puts "\nInternal error creating a menu pane: "  + e + "\n" + e.backtrace.join("\n")
            end
          end
          #create the freshly built menu (FOX needs this)
          @menu.create
          
          # Associate the new menu pane with its menu title if there is one
          if @slot.attr_FXMenuTitle 
            @slot.attr_FXMenuTitle.menu = @menu
          end
        end
      end  # class Renderer
      
    end
    
  end
end  # module FreeRIDE
