# Copyright 2004, @Last Software, Inc.
# The code related to click 3 points was reused here from an original
# example titled rectangle.rb by Last Software, Inc. 
# To it I added the FilletTool code. cheers! Tim 
# Name:           FilletTool
# Description:    input the radius and create a filleted rectanglular area
# Usage:          click 3 points, to create a filleted rectanglular area 
# Date:           2005/06/06
# Type:           Tool
# Revision:       2005/06/08 error checking for radius added
#------------------------------------------------------------------------------------------------
require 'sketchup.rb'

class FilletTool

def initialize
    @ip = Sketchup::InputPoint.new
    @ip1 = Sketchup::InputPoint.new
    reset
       
    $fr=6.inch if not $fr
    $fh=0.inch if not $fh    
       
    # Dialog box
    prompts=[ "Fillet Radius", "Extruded Height "]
    values=[$fr, $fh]
    results=inputbox prompts, values, "Fillet Parameters"

    return if not results
    $fr, $fh =results
    
    if ($fr <= 0.0.inch)
       then $fr = 0.01.inch
    end
    
end

def reset
    @pts = []
    @state = 0
    @ip1.clear
    @drawn = false
    Sketchup::set_status_text "", SB_VCB_LABEL
    Sketchup::set_status_text "", SB_VCB_VALUE
    Sketchup::set_status_text "Click any TOP LEFT start location"
    @shift_down_time = Time.now
end

def activate
    self.reset
end

def deactivate(view)
    view.invalidate if @drawn
end

def set_current_point(x, y, view)
    if( !@ip.pick(view, x, y, @ip1) )
        return false
    end
    need_draw = true
    
    # Set the tooltip that will be displayed
    view.tooltip = @ip.tooltip
        
    # Compute points
    case @state
    when 0
        @pts[0] = @ip.position
        @pts[4] = @pts[0]
        need_draw = @ip.display? || @drawn
    when 1
        @pts[1] = @ip.position
        @length = @pts[0].distance @pts[1]
        Sketchup::set_status_text @length.to_s, SB_VCB_VALUE
    when 2
        pt1 = @ip.position
        pt2 = pt1.project_to_line @pts
        vec = pt1 - pt2

        @pt1 = @ip.position
        @pt2 = pt1.project_to_line @pts
        @vec = @pt1 - @pt2


        @width = vec.length
        if( @width > 0 )
            # test for a square
            square_point = pt2.offset(vec, @length)
            if( view.pick_helper.test_point(square_point, x, y) )
                @width = @length
                @pts[2] = @pts[1].offset(vec, @width)
                @pts[3] = @pts[0].offset(vec, @width)
                view.tooltip = "Square"
            else
                @pts[2] = @pts[1].offset(vec)
                @pts[3] = @pts[0].offset(vec)
            end
        else
            @pts[2] = @pts[1]
            @pts[3] = @pts[0]
        end
        Sketchup::set_status_text @width.to_s, SB_VCB_VALUE
    end

    view.invalidate if need_draw
end

def onMouseMove(flags, x, y, view)
    self.set_current_point(x, y, view)
end

def create_rectangle
#--------------------------------------------------------------------------
    model=Sketchup.active_model
    model.start_operation "Create Fillet"
    entities=model.active_entities
            
    #------create a new set of points from the original 3 point pick
    $pt0=Geom::Point3d.new(@pts[0].x, @pts[0].y, @pts[0].z)
    $pt1=Geom::Point3d.new(@pts[1].x, @pts[1].y, @pts[1].z)
    $pt2=Geom::Point3d.new(@pts[2].x, @pts[2].y, @pts[2].z)
    $pt3=Geom::Point3d.new(@pts[3].x, @pts[3].y, @pts[3].z)
    #------create vert arc startpoint
    $pt0a=Geom::Point3d.new(@pts[0].x, @pts[0].y-$fr, @pts[0].z)
    $pt1a=Geom::Point3d.new(@pts[1].x, @pts[1].y-$fr, @pts[1].z)
    $pt2a=Geom::Point3d.new(@pts[2].x, @pts[2].y+$fr, @pts[2].z)
    $pt3a=Geom::Point3d.new(@pts[3].x, @pts[3].y+$fr, @pts[3].z)
    #------create horiz arc startpoint
    $pt0b=Geom::Point3d.new(@pts[0].x+$fr, @pts[0].y, @pts[0].z)
    $pt1b=Geom::Point3d.new(@pts[1].x-$fr, @pts[1].y, @pts[1].z)
    $pt2b=Geom::Point3d.new(@pts[2].x-$fr, @pts[2].y, @pts[2].z)
    $pt3b=Geom::Point3d.new(@pts[3].x+$fr, @pts[3].y, @pts[3].z)
    #------center of arc
    $pt0c=Geom::Point3d.new(@pts[0].x+$fr, @pts[0].y-$fr, @pts[0].z)
    $pt1c=Geom::Point3d.new(@pts[1].x-$fr, @pts[1].y-$fr, @pts[1].z)
    $pt2c=Geom::Point3d.new(@pts[2].x-$fr, @pts[2].y+$fr, @pts[2].z)
    $pt3c=Geom::Point3d.new(@pts[3].x+$fr, @pts[3].y+$fr, @pts[3].z)
            
    pi = 3.141592653589793  # 180 degree angle = pi radians
    vecz = Geom::Vector3d.new(0, 0, 1)
    vecy = Geom::Vector3d.new(0, 1, 0)     
    vecx = Geom::Vector3d.new(1, 0, 0) 
    
    vecy = $pt0 - $pt3 
    vert = vecy[1] # extract the vector length y between $pt0 - $pt3
    
    vecx = $pt1 - $pt0 
    horiz = vecx[0] # extract the vector length x between $pt1 - $pt0
    
    if ($fr*2 > horiz)
       UI.messagebox( "you picked a Fillet radius thats GREATER than the lenght of the object! try again!")
    return nil
    end
    
    if ($fr*2 > vert)
       UI.messagebox( "you picked a Fillet radius thats GREATER than the width of the object! try again! ")
    return nil
    end
    
       
    model.entities.add_arc($pt0c, vecx, vecz, $fr, pi, pi/2, 12)     
    model.entities.add_arc($pt1c, vecx, vecz, $fr, pi/2, 0, 12) 
    model.entities.add_arc($pt2c, vecx, vecz, $fr, 0, -pi/2, 12)  
    model.entities.add_arc($pt3c, vecx, vecz, $fr, -pi/2, -pi, 12) 
    model.entities.add_line($pt0b, $pt1b)
    model.entities.add_line($pt1a, $pt2a)
    model.entities.add_line($pt2b, $pt3b)
    e=model.entities.add_line($pt3a, $pt0a)
    e.find_faces 
    e.faces.first.pushpull -$fh
      
    model.commit_operation
end

def increment_state
    @state += 1
    case @state
    when 1
        @ip1.copy! @ip
        Sketchup::set_status_text "Drag Right for second point  "
        Sketchup::set_status_text "Slab Length", SB_VCB_LABEL
        Sketchup::set_status_text "", SB_VCB_VALUE
    when 2
        @ip1.clear
        Sketchup::set_status_text "Drag Down for third point"
        Sketchup::set_status_text "Slab Width", SB_VCB_LABEL
        Sketchup::set_status_text "", SB_VCB_VALUE
    when 3
        self.create_rectangle
    end
end

def onLButtonDown(flags, x, y, view)
    self.set_current_point(x, y, view)
    self.increment_state
    view.lock_inference
end

def onCancel(flag, view)
    view.invalidate if @drawn
    self.reset
end

# This is called when the user types a value into the VCB
def onUserText(text, view)
    # The user may type in something that we can't parse as a length
    # so we set up some exception handling to trap that
    begin
        value = text.to_l
    rescue
        # Error parsing the text
        UI.beep
        value = nil
        Sketchup::set_status_text "", SB_VCB_VALUE
    end
    return if !value
    
    case @state
    when 1
        # update the width
        vec = @pts[1] - @pts[0]
        if( vec.length > 0.0 )
            vec.length = value
            @pts[1] = @pts[0].offset(vec)
            view.invalidate
            self.increment_state
        end
    when 2
        # update the height
        vec = @pts[3] - @pts[0]
        if( vec.length > 0.0 )
            vec.length = value
            @pts[2] = @pts[1].offset(vec)
            @pts[3] = @pts[0].offset(vec)
            self.increment_state
        end
    end
end

def getExtents
    bb = Geom::BoundingBox.new
    case @state
    when 0
        # We are getting the first point
        if( @ip.valid? && @ip.display? )
            bb.add @ip.position
        end
    when 1
        bb.add @pts[0]
        bb.add @pts[1]
    when 2
        bb.add @pts
    end
    bb
end

def draw(view)
    @drawn = false
    
    # Show the current input point
    if( @ip.valid? && @ip.display? )
        @ip.draw(view)
        @drawn = true
    end

    # show the rectangle
    if( @state == 1 )
        # just draw a line from the start to the end point
        view.set_color_from_line(@ip1, @ip)
        inference_locked = view.inference_locked?
        view.line_width = 3 if inference_locked
        view.draw(GL_LINE_STRIP, @pts[0], @pts[1])
        view.line_width = 1 if inference_locked
        @drawn = true
    elsif( @state > 1 )
        # draw the curve
        view.drawing_color = "black"
        view.draw(GL_LINE_STRIP, @pts)
        @drawn = true
    end
end

def onKeyDown(key, rpt, flags, view)
    if( key == CONSTRAIN_MODIFIER_KEY && rpt == 1 )
        @shift_down_time = Time.now
        
        # if we already have an inference lock, then unlock it
        if( view.inference_locked? )
            view.lock_inference
        elsif( @state == 0 )
            view.lock_inference @ip
        elsif( @state == 1 )
            view.lock_inference @ip, @ip1
        end
    end
end

def onKeyUp(key, rpt, flags, view)
    if( key == CONSTRAIN_MODIFIER_KEY &&
        view.inference_locked? &&
        (Time.now - @shift_down_time) > 0.5 )
        view.lock_inference
    end
end

  
end # of class FilletTool
#----------------------------------------------------------------------------
def frametool
    Sketchup.active_model.select_tool FilletTool.new
end

if( not file_loaded?("FilletTool.rb") )
    UI.menu("Plugins").add_item("FilletTool") { Sketchup.active_model.select_tool FilletTool.new }
end
#-----------------------------------------------------------------------------
file_loaded("FilletTool.rb") # load"FilletTool.rb"

