# Purpose: Setup and initialize the Dock Panes gui interfaces
#
# $Id: dockpane.rb,v 1.7 2004/10/06 07:16:49 ljulliar Exp $
#
# Authors:  Laurent Julliard <laurent AT moldus DOT org>
# 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) 2002 Laurent Julliard. All rights reserved.
#

module FreeRIDE
  module FoxRenderer
    
    ##
    # This is the module that renders dockpanes using
    # FOX.
    #
    class DockPane
      extend FreeBASE::StandardPlugin
      
      def DockPane.start(plugin)
        component_slot = plugin["/system/ui/components/DockPane"]
        
        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) }
        
        # Now only is the plugin ready
        plugin.transition(FreeBASE::RUNNING)
      end
      
      ##
      # Each instance of this class is responsible for rendering a dockpane component
      #
      class Renderer
        include Fox
        
        FOCUS_COLOR = Fox::FXRGB(0,84,227)
        FOCUS_TEXT_COLOR = FXColor::GhostWhite
        DEFAULT_COLOR = 4292405740
        DEFAULT_TEXT_COLOR = FXColor::Black
        
        attr_reader :plugin
        
        def initialize(plugin, slot)
          @plugin = plugin
          @slot = slot
          
          @main_window = @plugin["/system/ui/fox/FXMainWindow"].data
          
          @frame = FXVerticalFrame.new(@main_window, FRAME_THICK|LAYOUT_FILL_Y|LAYOUT_FILL_X)
          @frame.padLeft = 0
          @frame.padRight = 0
          @frame.padBottom= 0
          @frame.padTop = 0
          @frame.hide
          @title = FXLabel.new(@frame, @slot.name, nil, JUSTIFY_LEFT|LAYOUT_FILL_X)
          @title.setFont(FXFont.new(@plugin["/system/ui/fox/FXApp"].data, "helvetica", 8, FONTWEIGHT_NORMAL))
          @title.setTextColor(FOCUS_TEXT_COLOR)
          @title.frameStyle = FRAME_LINE
          @title.setBorderColor(FXColor::LightGray)
          @title.setBackColor(FOCUS_COLOR)
          @title.connect(SEL_LEFTBUTTONPRESS) {@slot.data.setFocus}
          @frame.create
          
          @frame.connect(SEL_FOCUSIN) {
            @title.setTextColor(FOCUS_TEXT_COLOR)
            @title.setBackColor(FOCUS_COLOR)
          }
          @frame.connect(SEL_FOCUSOUT) {
            @title.setTextColor(DEFAULT_TEXT_COLOR)
            @title.setBackColor(DEFAULT_COLOR)
          }
          
          @slot.subscribe do |event, slot|
            update(event) if ((event == :refresh) || (event == :notify_data_set && slot==@slot))
          end
          
          setup_actions
          
          @plugin.log_info << "DockPane Renderer for #{@slot.path} created"
        end
        
        def setup_actions
          bind_action("dock", :dock)
          bind_action("undock", :undock)
          bind_action("show", :show)
          bind_action("hide", :hide)
          bind_action("current?", :current?)
        end
        
        def bind_action(name, meth)
          @slot["actions/#{name}"].set_proc method(meth)
        end
        
        ### Commands ###
        
        def dock(dockbar_path)
          @dockbar_path = dockbar_path
          where = @slot[dockbar_path].name
          @tabbook = @slot["/system/ui/fox/dockbar/#{where}/tabbook"].data
          @tab = FXTabItem.new(@tabbook, @slot.name, nil,FRAME_NONE,0,0,0,0,0,0,0,0)
          # keep track of the dockpane manager in the Widget
          @tab.userData = @slot.manager

          if @tabbook.tabStyle==TABBOOK_BOTTOMTABS
            @tab.tabOrientation = TAB_BOTTOM
          else
            @tab.tabOrientation = TAB_TOP
          end
          @tab.create
          @tabbook.current = @tabbook.indexOfChild(@tab)
          @slot.data.setFocus
          @frame.reparent(@tabbook)
          @frame.show
          @slot.data.setFocus
          @tab.connect(SEL_FOCUSIN) {@slot.data.setFocus}
          @plugin.log_info << "Reparenting #{@slot.path} to #{dockbar_path}"
        end
        
        def undock
          # TODO: MUST FIGURE OUT HOW TO UNDOCK CLEANLY
          @frame.hide
          @frame.reparent(@main_window)
          @tab.destroy
          @tab = nil
        end
        
        def show
          unless @tab.shown
            @tab.show
            @frame.show
            @tabbook.current = @tabbook.indexOfChild(@tab)
            @tab.recalc
            @frame.recalc
            @slot.data.setFocus
          end
        end
        
        def hide
          if @tab.shown
            @tab.hide
            @frame.hide
            @tab.recalc
            @frame.recalc
          end
        end

	##
	# Check whether this is the currently active dockpane
	# 
	def current?
	  # current means it is docked, the tab is not hidden
	  # and it is the current tab
	  @tab && @tab.shown && (@tabbook.current*2 == @tabbook.indexOfChild(@tab))
	end

        ##
        # Called whenever the dockpane may need to be updated
        # in particular when the .data of the slot is
        # modified (meaning that a new graphical object must be
        # inserted in the dockpane
        # 
        def update(event)
          # New visual object to be inserted in the tab frame.
          # slot.data contains the path to the UI component to insert
          # the FOX frame to insert is in the attr_frame attribute
          if event == :notify_data_set and @slot.data
            child_frame = @slot.data
            child_frame.reparent(@frame)
            child_frame.show
          end
        end
        
         
      end
    end
    
  end
end
