require 'ams_WindowSettings.rb'

unless defined?(AMS::WindowSettings)
  msg = "Cannot load 'AMS Window Settings' extension. "
  msg << "Ensure that SketchUp meets all compatibility demands of the plugin!"
  raise(LoadError, msg, caller)
end

module AMS::WindowSettings

  @standard = {
    :version            => VERSION,
    :full_screen        => false,
    :menu_bar           => true,
    :view_border        => true,
    :containers         => true,
    :status_bar         => true,
    :scenes_bar         => true,
    :dialogs            => true,
    :toolbars           => true,
    :retain_on_start    => false,
    :dialog_on_start    => true,
    :snapped            => [2,1] # [col, row]
  }
  @saved = @standard.dup
  @dialog = nil
  @handle = nil
  @initialized = false
  @mouse_enter = false
  @title = 'AMS Window Settings'
  @width = 240
  @height = 200
  @opacity = 255
  @min_opacity = 100
  @wait = 0.0
  @leave_time = Time.now
  @pt1 = nil
  @pt2 = nil
  @ratio = 1
  @max_range = 400
  @rect_offset = 100
  @snap = 25 # snap distance in pixels
  @init_called = false
  @dialog_width = {
    'cs'    => 260,
    'de'    => 300,
    'es'    => 300,
    'fr'    => 280,
    'it'    => 320,
    'ja'    => 240,
    'ko'    => 240,
    'nl'    => 300,
    'pl'    => 300,
    'pt-BR' => 260,
    'ru'    => 330,
    'zh-CN' => 240,
    'zh-TW' => 240
  }

  dir = File.dirname(__FILE__)
  TRANSLATE = AMS::Translate.new('commands', File.join(dir, 'lang'))

  class << self

    def init
      return false if @init_called
      @init_called = true
      load_options
      AMS::Timer.start(1000, false){
        retain if @saved[:retain_on_start]
        show_dialog(true) if @saved[:dialog_on_start]
      }
      true
    end

    def save_options
      Sketchup.write_default('Plugins_ams', 'WindowSettings', @saved.inspect.inspect[1..-2])
    end

    def load_options
      v = Sketchup.read_default('Plugins_ams', 'WindowSettings', '{}')
      begin
        res = eval(v)
        if res.is_a?(Hash) && res.size == @saved.size
          @saved.merge!(res)
        end
      rescue Exception => e
        # Do nothing; use default options.
      end
    end

    def get_settings
      settings = {
        :full_screen    => AMS::Sketchup.is_full_screen?,
        :menu_bar       => AMS::Sketchup.is_menu_bar_set?,
        :view_border    => AMS::Sketchup.is_viewport_border_set?,
        :containers     => AMS::Sketchup.is_toolbar_container_visible?(7),
        :status_bar     => AMS::Sketchup.is_status_bar_visible?,
        :scenes_bar     => AMS::Sketchup.is_scenes_bar_visible? || AMS::Sketchup.is_scenes_bar_empty?,
        :dialogs        => !AMS::Sketchup.get_visible_dialogs.empty? || AMS::Sketchup.get_active_dialogs.empty?,
        :toolbars       => !AMS::Sketchup.get_visible_toolbars.empty? || AMS::Sketchup.get_active_toolbars.empty?
      }
      settings
    end

    def set_settings(settings)
      AMS::Sketchup.show_toolbar_container(5, settings[:containers], false)
      AMS::Sketchup.show_scenes_bar(settings[:scenes_bar], false)
      AMS::Sketchup.show_status_bar(settings[:status_bar], false)
      AMS::Sketchup.set_viewport_border(settings[:view_border])
      r1 = AMS::Sketchup.set_menu_bar(settings[:menu_bar])
      r2 = AMS::Sketchup.switch_full_screen(settings[:full_screen])
      AMS::Sketchup.refresh unless r1 || r2
      AMS::Sketchup.show_dialogs(settings[:dialogs])
      AMS::Sketchup.show_toolbars(settings[:toolbars])
    end

    def save
      @saved.merge!(get_settings())
      save_options
    end

    def retain
      set_settings(@saved)
    end

    def reset
      set_settings(@standard)
    end

    def show_dialog(state)
      state = state ? true : false
      return false if state == is_dialog_visible?
      if state
        offset = [0,0]
        # Create a web dialog.
        @dialog = UI::WebDialog.new(@title, false, 'ams_WindowSettings', @width, @height, 400, 300, true)
        # Attach callbacks
        @dialog.add_action_callback('init'){ |dlg, params|
          update_dialog_options
          # Get dialog size
          cx,cy = eval(params)
          if @initialized
            AMS::Window.set_size(@handle, @width, cy, false)
          else
            @initialized = true
            AMS::Window.set_pos(@handle, 0, 0, 0, @width, cy, 0x0266)
          end
          dialog_update_snapped
        }
        @dialog.set_on_close(){
          AMS::Sketchup.include_dialog(@handle)
          AMS::Sketchup.remove_observer(self)
          @dialog = nil
          @handle = nil
          @initialized = false
          @mouse_enter = false
        }
        @dialog.add_action_callback('timer'){ |dlg, params|
            temp = @opacity
            if @mouse_enter
              @opacity += 5 if @opacity < 255
            elsif @leave_time && Time.now - @leave_time > @wait
              @opacity -= 1 if @opacity > @min_opacity
              if @ratio < 1
                @ratio += 0.02
                @ratio = 1 if @ratio > 1 || ((@pt2[0] - @pt1[0]).abs < 5 && (@pt2[1] - @pt1[1]).abs < 5)
                r = 0.5 * Math.sin(Math::PI*(@ratio-0.5)) + 0.5
                x = @pt1[0] + r * (@pt2[0] - @pt1[0])
                y = @pt1[1] + @ratio * (@pt2[1] - @pt1[1])
                AMS::Window.set_origin(@handle, x, y, false)
                if @ratio == 1
                  snap = dialog_get_snap
                  if snap
                    @pt1 = AMS::Window.get_origin(@handle)
                    @pt2 = snap
                    @ratio = 0
                  end
                end
              end
            end
            @opacity = AMS.clamp(@opacity, @min_opacity, 255)
            #rect = AMS::Window.get_rect(@handle)
            #rect[0] -= @rect_offset
            #rect[1] -= @rect_offset
            #rect[2] += @rect_offset
            #rect[3] += @rect_offset
            #pt = AMS::Cursor.get_pos
            #dist = get_closest_distance_to_rect(rect, pt)
            #@opacity = dist < @max_range ? ((@max_range - dist)*255.0 / @max_range).to_i : 0
            #@opacity = @min_opacity if @opacity < @min_opacity
            set_dialog_opacity(@opacity) if @opacity != temp
        }
        @dialog.add_action_callback('window_focus'){ |dlg, params|
        }
        @dialog.add_action_callback('window_blur'){ |dlg, params|
        }
        @dialog.add_action_callback('window_mouse_enter'){ |dlg, params|
          @mouse_enter = true
        }
        @dialog.add_action_callback('window_mouse_leave'){ |dlg, params|
          @mouse_enter = false
          @leave_time = Time.now
          snap = dialog_get_snap
          if snap
            @pt1 = AMS::Window.get_origin(@handle)
            @pt2 = snap
            @ratio = 0
          else
            @ratio = 1
          end
        }
        @dialog.add_action_callback('adjust_size'){ |dlg, params|
          cx,cy = eval(params)
          AMS::Window.set_size(@handle, @width, cy, false)
        }
        @dialog.add_action_callback('input_changed'){ |dlg, params|
          data = eval(params)
          case data[0]
            when :rad1
              AMS::Sketchup.switch_full_screen(true)
            when :rad2
              AMS::Sketchup.maximize
            when :rad3
              AMS::Sketchup.restore
            when :cb1
              AMS::Sketchup.set_menu_bar(data[1])
            when :cb2
              AMS::Sketchup.set_viewport_border(data[1])
            when :cb3
              AMS::Sketchup.show_toolbar_container(5, data[1])
            when :cb4
              AMS::Sketchup.show_scenes_bar(data[1])
            when :cb5
              AMS::Sketchup.show_status_bar(data[1])
            when :cb6
              @saved[:retain_on_start] = data[1]
              save_options
            when :cb7
              @saved[:dialog_on_start] = data[1]
              save_options
          end
        }
        @dialog.add_action_callback('button_clicked'){ |dlg, params|
          case params.to_sym
            when :quit
              dlg.close
            when :btn1
              AMS::Sketchup.show_toolbars(true)
            when :btn2
              AMS::Sketchup.show_toolbars(false)
            when :btn3
              AMS::Sketchup.close_toolbars
            when :btn4
              AMS::Sketchup.show_dialogs(true)
            when :btn5
              AMS::Sketchup.show_dialogs(false)
            when :btn6
              AMS::Sketchup.close_dialogs
            when :btn7
              save
            when :btn8
              retain
            when :btn9
              reset
          end
        }
        @dialog.add_action_callback('drag_start'){ |dlg, params|
          c = AMS::Cursor.get_pos
          d = AMS::Window.get_origin(@handle)
          offset = [c.x - d.x, c.y - d.y]
        }
        @dialog.add_action_callback('drag'){ |dlg, params|
          c = AMS::Cursor.get_pos
          x,y = [c.x - offset.x, c.y - offset.y]
          w,h = AMS::Window.get_size(@handle)
          wr = [x, y, x+w, y+h]
          x,y = panel_snap_to_view(wr)
          wr = [x, y, x+w, y+h]
          x,y = panel_clip_to_screen(wr)
          AMS::Window.set_origin(@handle, x, y, false)
        }
        @dialog.add_action_callback('drag_end'){ |dlg, params|
          offset = [0,0]
        }
        # Set content
        dir = File.dirname(__FILE__)
        loc = Sketchup.get_locale
        path = File.join(dir, "lang/window_settings_#{loc}.html")
        if File.exists?(path)
          @width = @dialog_width[loc] if @dialog_width[loc]
        else
          path = File.join(dir, 'window_settings.html')
        end
        @dialog.set_file(path)
        # Show dialog
        RUBY_PLATFORM =~ /mswin|mingw/i ? @dialog.show : @dialog.show_modal
        # Find dialog handle
        @handle = AMS::Sketchup.find_window_by_caption(@title)
        if @handle
          # Add dialog to ignore list
          AMS::Sketchup.ignore_dialog(@handle)
          # Add observer
          AMS::Sketchup.add_observer(self)
          # Remove dialog caption and borders
          layered = AMS::System.get_windows_version < 6.0 ? 0 : 0x00080000
          style_ex = 0x00010000 | layered # WS_EX_CONTROLPARENT | WS_EX_LAYERED
          style = 0x94000000 # WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS
          AMS::Window.lock_update(@handle)
          AMS::Window.set_long(@handle, -20, style_ex)
          AMS::Window.set_long(@handle, -16, style)
          AMS::Window.lock_update(nil)
          AMS::Window.set_pos(@handle, 0, 0, 0, 0, 0, 0x0267)
        end
      else
        @dialog.close
      end
      true
    end

    def is_dialog_visible?
      @dialog ? true : false
    end

    def update_dialog_options
      return false unless @dialog
      cmd = ""
      if AMS::Sketchup.is_full_screen?
        cmd << "$('#rad1').prop('checked', true);"
      elsif AMS::Sketchup.is_maximized?
        cmd << "$('#rad2').prop('checked', true);"
      else
        cmd << "$('#rad3').prop('checked', true);"
      end
      cmd << "$('#cb1').prop('checked', #{AMS::Sketchup.is_menu_bar_set?});"
      cmd << "$('#cb2').prop('checked', #{AMS::Sketchup.is_viewport_border_set?});"
      cmd << "$('#cb3').prop('checked', #{AMS::Sketchup.is_toolbar_container_visible?(7)});"
      cmd << "$('#cb4').prop('checked', #{AMS::Sketchup.is_scenes_bar_visible?});"
      cmd << "$('#cb5').prop('checked', #{AMS::Sketchup.is_status_bar_visible?});"
      cmd << "$('#cb6').prop('checked', #{@saved[:retain_on_start]});"
      cmd << "$('#cb7').prop('checked', #{@saved[:dialog_on_start]});"
      cmd << "$('#cb3').checkboxradio('option', 'disabled', #{AMS::Sketchup.is_toolbar_container_empty?(6)});"
      cmd << "$('#cb4').checkboxradio('option', 'disabled', #{AMS::Sketchup.is_scenes_bar_empty?});"
      cmd << "$('input[type=radio], input[type=checkbox]').checkboxradio('refresh');"
      @dialog.execute_script(cmd)
      true
    end

    def adjust_dialog_position
      return false if @dialog.nil? || @mouse_enter || @ratio != 1
      rect = AMS::Sketchup.get_viewport_rect
      AMS::Window.set_origin(@handle, rect[2]-@width, rect[1], false)
    end

    def set_dialog_opacity(opacity = 255)
      return false unless @dialog
      return false if AMS::System.get_windows_version < 6.0
      if opacity.is_a?(Float)
        opacity *= 255 if opacity.between?(0,1)
        opacity = opacity.round
      end
      opacity = 0 if opacity < 0
      opacity = 255 if opacity > 255
      AMS::Window.set_layered_attributes(@handle, 0, opacity, 2)
      true
    end

    def get_closest_distance_to_rect(rect, pt)
      return 0 if pt[0].between?(rect[0], rect[2]) && pt[1].between?(rect[1], rect[3])
      if pt[1].between?(rect[1], rect[3])
        pt[0] < rect[0] ? rect[0] - pt[0] : pt[0] - rect[2]
      elsif pt[0].between?(rect[0], rect[2])
        pt[1] < rect[1] ? rect[1] - pt[1] : pt[1] - rect[3]
      elsif pt[0] < rect[0] && pt[1] < rect[1]
        Math.sqrt( (rect[0]-pt[0])**2 + (rect[1]-pt[1])**2 )
      elsif pt[0] > rect[2] && pt[1] < rect[1]
        Math.sqrt( (pt[0]-rect[2])**2 + (rect[1]-pt[1])**2 )
      elsif pt[0] < rect[0] && pt[1] > rect[3]
        Math.sqrt( (rect[0]-pt[0])**2 + (pt[1]-rect[3])**2 )
      else
        Math.sqrt( (pt[0]-rect[2])**2 + (pt[1]-rect[3])**2 )
      end
    end

    def panel_snap_to_view(wr)
      x = wr[0]
      y = wr[1]
      w = wr[2]-wr[0]
      h = wr[3]-wr[1]
      vr = AMS::Sketchup.get_viewport_rect
      temp = @saved[:snapped].dup
      @saved[:snapped] = [0,0]
      if y.between?(vr[1]-h,vr[3])
        if (x-vr[0]).abs <= @snap
          x = vr[0]
          @saved[:snapped][0] = 1
        elsif (x+w-vr[2]).abs <= @snap
          x = vr[2]-w
          @saved[:snapped][0] = 2
        end
      end
      if x.between?(vr[0]-w,vr[2])
        if ((y-vr[1]).abs <= @snap)
          y = vr[1]
          @saved[:snapped][1] = 1
        elsif ((y+h-vr[3]).abs <= @snap)
          y = vr[3]-h
          @saved[:snapped][1] = 2
        end
      end
      save_options if @saved[:snapped] != temp
      return [x,y]
    end

    def panel_clip_to_screen(wr)
      res = AMS::Screen.virtual_resolution
      x = wr[0]
      y = wr[1]
      w = wr[2]-wr[0]
      h = wr[3]-wr[1]
      x = res[0]-w if (x+w > res[0])
      x = 0 if (x < 0)
      y = res[1]-h if (y+h > res[1])
      y = 0 if (y < 0)
      return [x,y]
    end

    def dialog_snap_to_view
      return false unless @handle
      wr = AMS::Window.get_rect(@handle)
      x,y = panel_snap_to_view(wr)
      return false if ([x,y] == wr[0..1])
      AMS::Window.set_origin(@handle, x, y, false)
      true
    end

    def dialog_clip_to_screen
      return false unless @handle
      wr = AMS::Window.get_rect(@handle)
      x,y = panel_clip_to_screen(wr)
      return false if ([x,y] == wr[0..1])
      AMS::Window.set_origin(@handle, x, y, false)
      true
    end

    def dialog_get_snap
      return unless @dialog
      wr = AMS::Window.get_rect(@handle)
      vr = AMS::Sketchup.get_viewport_rect
      x = wr[0]
      y = wr[1]
      w = wr[2]-wr[0]
      h = wr[3]-wr[1]
      # Check whether the dialog must be snapped if not already snapped.
      s = @saved[:snapped]
      if s.include?(0)
        if (s[0] != 0 and y.between?(vr[1]-h,vr[3]))
          x = (s[0] == 1 ? vr[0] : vr[2]-w)
        end
        if (s[1] != 0 and x.between?(vr[0]-w,vr[2]))
          y = (s[1] == 1 ? vr[1] : vr[3]-h)
        end
      else
        x = (s[0] == 1 ? vr[0] : vr[2]-w)
        y = (s[1] == 1 ? vr[1] : vr[3]-h)
      end
      x,y = panel_clip_to_screen([x, y, x+w, y+h])
      return if ([x,y] == wr[0..1])
      [x,y]
    end

    def dialog_update_snapped
      return false if @dialog.nil? || @mouse_enter || @ratio != 1
      snap = dialog_get_snap
      AMS::Window.set_origin(@handle, snap.x, snap.y, false) if snap
      true
    end


    # AMS SketchUp Observers

    def swo_on_enter_size_move(x, y, w, h)
      dialog_update_snapped
    end

    def swo_on_exit_size_move(x, y, w, h)
      dialog_update_snapped
    end

    def swo_on_size_move(x, y, w, h)
      dialog_update_snapped
    end

    def swo_on_viewport_size(w, h)
      dialog_update_snapped
    end

    def swo_on_switch_full_screen(state)
      if @dialog && state
        cmd = "$('#rad1').prop('checked', true);"
        cmd << "$('input[type=radio]').checkboxradio('refresh');"
        @dialog.execute_script(cmd)
      end
    end

    def swo_on_maximize
      cmd = "$('#rad2').prop('checked', true);"
      cmd << "$('input[type=radio]').checkboxradio('refresh');"
      @dialog.execute_script(cmd) if @dialog
    end

    def swo_on_restore
      cmd = "$('#rad3').prop('checked', true);"
      cmd << "$('input[type=radio]').checkboxradio('refresh');"
      @dialog.execute_script(cmd) if @dialog
    end

    def swo_on_menu_bar_changed(state)
      cmd = "$('#cb1').prop('checked', #{state}).checkboxradio('refresh');"
      @dialog.execute_script(cmd) if @dialog
    end

    def swo_on_viewport_border_changed(state)
      cmd = "$('#cb2').prop('checked', #{state}).checkboxradio('refresh');"
      @dialog.execute_script(cmd) if @dialog
    end

    def swo_on_toolbar_container_visibility_changed(bar, state)
      AMS::Timer.start(100, false){
        cmd = "$('#cb3').prop('checked', #{AMS::Sketchup.is_toolbar_container_visible?(7)}).checkboxradio('refresh');"
        @dialog.execute_script(cmd) if @dialog
      }
    end

    def swo_on_toolbar_container_filled(bar)
      cmd = "$('#cb3').checkboxradio('option', 'disabled', false);"
      @dialog.execute_script(cmd) if @dialog
    end

    def swo_on_toolbar_container_emptied(bar)
      AMS::Timer.start(100, false){
        cmd = "$('#cb3').checkboxradio('option', 'disabled', #{AMS::Sketchup.is_toolbar_container_empty?(6)});"
        @dialog.execute_script(cmd) if @dialog
      }
    end

    def swo_on_scenes_bar_visibility_changed(state)
      cmd = "$('#cb4').prop('checked', #{state}).checkboxradio('refresh');"
      @dialog.execute_script(cmd) if @dialog
    end

    def swo_on_scenes_bar_filled
      cmd = "$('#cb4').checkboxradio('option', 'disabled', false);"
      @dialog.execute_script(cmd) if @dialog
    end

    def swo_on_scenes_bar_emptied
      cmd = "$('#cb4').checkboxradio('option', 'disabled', true);"
      @dialog.execute_script(cmd) if @dialog
    end

    def swo_on_status_bar_visibility_changed(state)
      cmd = "$('#cb5').prop('checked', #{state}).checkboxradio('refresh');"
      @dialog.execute_script(cmd) if @dialog
    end

  end # class << self
end # module AMS::WindowSettings


unless file_loaded?(__FILE__)
  AMS::WindowSettings.init
  toolbar = UI::Toolbar.new('WS')
  language = AMS::WindowSettings::TRANSLATE
  submenu = UI.menu('Window').add_submenu(language["Settings"])

  cmd = UI::Command.new('Full Screen'){
    state = !AMS::Sketchup.is_full_screen?
    AMS::Sketchup.switch_full_screen(state)
  }
  cmd.menu_text = cmd.tooltip = language["Full Screen"]
  cmd.status_bar_text = language["Toggle main window full screen."]
  cmd.set_validation_proc {
    AMS::Sketchup.is_full_screen? ? MF_CHECKED : MF_UNCHECKED
  }
  cmd.small_icon = 'images/fullscreen16.png'
  cmd.large_icon = 'images/fullscreen24.png'
  toolbar.add_item(cmd)
  submenu.add_item(cmd)

  cmd = UI::Command.new('Menu Bar'){
    state = !AMS::Sketchup.is_menu_bar_set?
    AMS::Sketchup.set_menu_bar(state)
  }
  cmd.menu_text = cmd.tooltip = language["Menu Bar"]
  cmd.status_bar_text = language["Set/remove menu bar."]
  cmd.set_validation_proc {
    AMS::Sketchup.is_menu_bar_set? ? MF_CHECKED : MF_UNCHECKED
  }
  cmd.small_icon = 'images/menubar16.png'
  cmd.large_icon = 'images/menubar24.png'
  toolbar.add_item(cmd)
  submenu.add_item(cmd)

  cmd = UI::Command.new('View Border'){
    state = !AMS::Sketchup.is_viewport_border_set?
    AMS::Sketchup.set_viewport_border(state)
  }
  cmd.menu_text = language["View Border"]
  cmd.status_bar_text = language["Set/remove view client edge."]
  cmd.set_validation_proc {
    AMS::Sketchup.is_viewport_border_set? ? MF_CHECKED : MF_UNCHECKED
  }
  submenu.add_item(cmd)

  cmd = UI::Command.new('Toolbar Containers'){
    state = !AMS::Sketchup.is_toolbar_container_visible?(7)
    AMS::Sketchup.show_toolbar_container(5, state)
  }
  cmd.menu_text = language["Toolbar Containers"]
  cmd.status_bar_text = language["Show/hide toolbar containers."]
  cmd.set_validation_proc {
    next MF_GRAYED if AMS::Sketchup.is_toolbar_container_empty?(6)
    AMS::Sketchup.is_toolbar_container_visible?(7) ? MF_CHECKED : MF_UNCHECKED
  }
  submenu.add_item(cmd)

  cmd = UI::Command.new('Scenes Bar'){
    state = !AMS::Sketchup.is_scenes_bar_visible?
    AMS::Sketchup.show_scenes_bar(state)
  }
  cmd.menu_text = language["Scenes Bar"]
  cmd.status_bar_text = language["Show/hide scenes bar."]
  cmd.set_validation_proc {
    next MF_GRAYED if AMS::Sketchup.is_scenes_bar_empty?
    AMS::Sketchup.is_scenes_bar_visible? ? MF_CHECKED : MF_UNCHECKED
  }
  submenu.add_item(cmd)

  cmd = UI::Command.new('Status Bar'){
    state = !AMS::Sketchup.is_status_bar_visible?
    AMS::Sketchup.show_status_bar(state)
  }
  cmd.menu_text = language["Status Bar"]
  cmd.status_bar_text = language["Show/hide status bar."]
  cmd.set_validation_proc {
    AMS::Sketchup.is_status_bar_visible? ? MF_CHECKED : MF_UNCHECKED
  }
  submenu.add_item(cmd)

  submenu.add_separator

  cmd = UI::Command.new('Dialogs'){
    AMS::Sketchup.show_dialogs(AMS::Sketchup.get_visible_dialogs.empty?)
  }
  cmd.menu_text = language["Dialogs"]
  cmd.status_bar_text = language["Show/hide all dialogs, including the Ruby Console."]
  cmd.set_validation_proc {
    next MF_GRAYED if AMS::Sketchup.get_active_dialogs.empty?
    AMS::Sketchup.get_visible_dialogs.empty? ? MF_UNCHECKED : MF_CHECKED
  }
  submenu.add_item(cmd)

  cmd = UI::Command.new('Close Dialogs'){
    AMS::Sketchup.close_dialogs
  }
  cmd.menu_text = language["Close Dialogs"]
  cmd.status_bar_text = language["Close all dialogs, including the Ruby Console."]
  cmd.set_validation_proc {
    next MF_GRAYED if AMS::Sketchup.get_active_dialogs.empty?
  }
  submenu.add_item(cmd)

  cmd = UI::Command.new('Toolbars'){
    AMS::Sketchup.show_toolbars(AMS::Sketchup.get_visible_toolbars.empty?)
  }
  cmd.menu_text = language["Toolbars"]
  cmd.status_bar_text = language["Show/hide all floating toolbars."]
  cmd.set_validation_proc {
    next MF_GRAYED if AMS::Sketchup.get_active_toolbars.empty?
    AMS::Sketchup.get_visible_toolbars.empty? ? MF_UNCHECKED : MF_CHECKED
  }
  submenu.add_item(cmd)

  cmd = UI::Command.new('Close Toolbars'){
    AMS::Sketchup.close_toolbars
  }
  cmd.menu_text = language["Close Toolbars"]
  cmd.status_bar_text = language["Close all floating toolbars."]
  cmd.set_validation_proc {
    next MF_GRAYED if AMS::Sketchup.get_active_toolbars.empty?
  }
  submenu.add_item(cmd)

  submenu.add_separator

  cmd = UI::Command.new('Save Settings'){ AMS::WindowSettings.save }
  cmd.menu_text = language["Save"]
  cmd.status_bar_text = language["Save current settings."]
  submenu.add_item(cmd)

  cmd = UI::Command.new('Retain Settings'){ AMS::WindowSettings.retain }
  cmd.menu_text = language["Retain"]
  cmd.status_bar_text = language["Set saved settings."]
  submenu.add_item(cmd)

  cmd = UI::Command.new('Reset Settings'){ AMS::WindowSettings.reset }
  cmd.menu_text = language["Reset"]
  cmd.status_bar_text = language["Set default layout."]
  submenu.add_item(cmd)

  submenu.add_separator

  cmd = UI::Command.new('Settings Dialog'){
    AMS::WindowSettings.show_dialog(!AMS::WindowSettings.is_dialog_visible?)
  }
  cmd.menu_text = cmd.tooltip = language["Settings Dialog"]
  cmd.status_bar_text = language["Open/close settings dialog."]
  cmd.set_validation_proc {
    AMS::WindowSettings.is_dialog_visible? ? MF_CHECKED : MF_UNCHECKED
  }
  cmd.small_icon = 'images/settings16.png'
  cmd.large_icon = 'images/settings24.png'
  toolbar.add_item(cmd)
  submenu.add_item(cmd)

  cmd = UI::Command.new('Website'){ UI.openURL('http://sketchucation.com/forums/viewtopic.php?f=323&t=42926') }
  cmd.menu_text = language["Website"]
  cmd.status_bar_text = language["Open a web browser to the plugin's homepage."]
  submenu.add_item(cmd)

  toolbar.show
  file_loaded(__FILE__)
end
