require 'sketchup.rb'
###########################################################
#
#    Copyright (C) 2008 Uli Tessel (utessel@gmx.de)
#
#    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 3 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, see <http://www.gnu.org/licenses/>.
#
###########################################################

class FacePusher

  #--------------------------------------------------------------------------
  def initialize( distance, material, negmaterial)
    @distance = distance
    @material = material
    @negmaterial = negmaterial
    @components = []
  end
  
  #--------------------------------------------------------------------------
  def DoPushFace( face )
     
      if (@material==nil)
	    face.pushpull @distance, false    
	    return
      end
      
      if (@material)
        if (face.material == @material) or (face.back_material == @material)
  	      face.pushpull @distance, false    
  	      return
  	    end
      end
      
      if (@negmaterial)
        if (face.material == @negmaterial) or (face.back_material == @negmaterial)
 	      face.pushpull -@distance, false    
 	      return
        end      
      end
 
  end
  
  #--------------------------------------------------------------------------
  def DoPush( entity )

    #----------- GROUP -----------------
    if entity.is_a? Sketchup::Group then
      entity.entities.each { |sub| DoPush( sub ) }    
    
    #----------- COMPONENT -----------------
    elsif entity.is_a? Sketchup::ComponentInstance then    
      return if @components.include? entity.definition      
      @components << entity.definition
      entity.definition.entities.each { |sub| DoPush( sub ) }    

    #----------- FACE -----------------
    elsif entity.is_a? Sketchup::Face then    
      DoPushFace( entity )
    end

  end

  #--------------------------------------------------------------------------
  def Work(what)
    model = Sketchup.active_model
    model.start_operation("Push Selection")
    begin
      what.each { |entity| DoPush( entity ) }
      model.commit_operation
    rescue => bang
      model.abort_operation
      UI.messagebox "Error: " + bang
    end
  end

end
#--------------------------------------------------------------------------

#-----------------------------------------------------------------------------
def DoPusher( )

  what = Sketchup.active_model.selection
  if (what.count==0) then
    UI.messagebox "Nothing selected"
    return;
  end

  model = Sketchup.active_model
  materials = model.materials
  names = materials.collect {|m| m.name}
  displaynamesA = materials.collect {|m| m.display_name}
  displaynamesB = Array.new displaynamesA
  
  displaynamesA << "all"
  displaynamesB << "none"

  prompts = ["Distance", "Material", "negative Material" ]
  
  if $pusherLastTimeValues
    values = $pusherLastTimeValues
  else
    values = [1.mm, displaynamesA.last, displaynamesB.last ]
  end
  enums = [nil, displaynamesA.join("|"), displaynamesB.join("|") ]
    
  results = UI.inputbox prompts, values, enums, "Push selected faces"
  return if not results
  
  $pusherLastTimeValues = results
  distance = results[0]
     
  if (results[1]=="all")
    material = nil 
  else  
    index = displaynamesA.index(results[1])
    materialname = index ? names[index] : nil
    material = materialname ? materials[materialname] : nil
    
    if (material==nil)      
       UI.messagebox( "Material "+matname+" unknown" )
       return
    end    
  end
  
  if (results[2]=="none")
    negmaterial = nil 
  else  
    index = displaynamesB.index(results[2])
    materialname = index ? names[index] : nil
    negmaterial = materialname ? materials[materialname] : nil
    
    if (negmaterial==nil)      
       UI.messagebox( "Material "+matname+" unknown" )
       return
    end    
  end

  pusher = FacePusher.new(distance, material, negmaterial)
  pusher.Work(what)
end
#--------------------------------------------------------------------------

#--------------------------------------------------------------------------
# Register within Sketchup
if(file_loaded("FacePusher.rb"))
 	menu = UI.menu("Plugins");
	menu.add_item("Push Faces") { DoPusher() }
end

#--------------------------------------------------------------------------
file_loaded("FacePusher.rb")
