#
# Copyright (c) 2002-2004 Art Haas
#
# This file is part of PythonCAD.
# 
# PythonCAD 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 2 of the License, or
# (at your option) any later version.
# 
# PythonCAD 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 PythonCAD; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# Handles creation of construction lines, circles, etc
#

from math import hypot, pi, atan2
from Foundation import *

from PythonCAD.Interface.Cocoa import CocoaEntities
import PythonCAD.Generic.cline
import PythonCAD.Generic.acline
import PythonCAD.Generic.conobject


#
# Horizontal/Vertical lines - could really be combined
#

def hcline_mode_init(doc, tool):
    doc.setPrompt("Click in the drawing area or enter the first point as 'x, y'")
    tool.setHandler("initialize", hcline_mode_init)
    tool.setHandler("left_button_press", hcline_left_button_press_cb)
    tool.setHandler("entry_event", hcline_entry_event_cb)
    
def hcline_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _viewLoc = _da.convertPoint_fromView_(_loc, None)
    tool.setPoint(_viewLoc.x, _viewLoc.y)
    CocoaEntities.create_entity(doc, tool)
    
def hcline_entry_event_cb(doc, text, tool):
    if len(text):
        _x, _y = CocoaEntities.make_tuple(text)
        tool.setPoint(_x, _y)
        CocoaEntities.create_entity(doc, tool)
    
def vcline_mode_init(doc, tool):
    doc.setPrompt("Click in the drawing area or enter the first point as 'x, y'")
    tool.setHandler("initialize", vcline_mode_init)
    tool.setHandler("left_button_press", vcline_left_button_press_cb)
    tool.setHandler("entry_event", vcline_entry_event_cb)

def vcline_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _viewLoc = _da.convertPoint_fromView_(_loc, None)
    tool.setPoint(_viewLoc.x, _viewLoc.y)
    CocoaEntities.create_entity(doc, tool)
    
def vcline_entry_event_cb(doc, text, tool):
    if len(text):
        _x, _y = CocoaEntities.make_tuple(text)
        tool.setPoint(_x, _y)
        CocoaEntities.create_entity(doc, tool)

#
# Angled Construction line
#

    
def acline_mode_init(doc, tool):
    doc.setPrompt("Click in the drawing area or enter the first point as 'x, y'")
    tool.setHandler("initialize", acline_mode_init)
    tool.setHandler("left_button_press", acline_first_left_button_press_cb)
    tool.setHandler("entry_event", acline_first_entry_event_cb)

def acline_first_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _viewLoc = _da.convertPoint_fromView_(_loc, None)
    _da.setTempPoint(_viewLoc)
    tool.setPoint(_viewLoc.x, _viewLoc.y)
    tool.setHandler("mouse_move", acline_mouse_move_cb)
    tool.setHandler("left_button_press", acline_second_left_button_press_cb)
    tool.setHandler("entry_event", acline_second_entry_event_cb)
    doc.setPrompt("Click in the drawing area or enter the angle")
    
def acline_second_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _sp = _da.convertPoint_fromView_(_loc, None)
    tool.setLocation(_sp.x, _sp.y)
    CocoaEntities.create_entity(doc, tool)

def acline_mouse_move_cb(doc, np, tool):
    tool.setLocation(np.x, np.y)
    _p1 = tool.getPoint()
    _p2 = (np.x, np.y)
    _s = PythonCAD.Generic.conobject.ConstructionObject._ConstructionObject__defstyle
    _seg = PythonCAD.Generic.segment.Segment(_p1, _p2, _s)
    _da = doc.getDA()
    _da.setTempObject(_seg)
    

def acline_first_entry_event_cb(doc, text, tool):
    if len(text):
        _x, _y = CocoaEntities.make_tuple(text)
        tool.setPoint(_x, _y)
        tool.setHandler("mouse_move", acline_mouse_move_cb)
        tool.setHandler("left_button_press", acline_second_left_button_press_cb)
        tool.setHandler("entry_event", acline_second_entry_event_cb)
        doc.setPrompt("Click in the drawing area or enter the angle")
        doc.getDA().setTempPoint(NSMakePoint(_x, _y))

def acline_second_entry_event_cb(doc, text, tool):
    if len(text):
        _angle = CocoaEntities.make_angle(text)
        tool.setAngle(_angle)
        CocoaEntities.create_entity(doc, tool)

#
# two-point construction line
#

def cline_tp_mode_init(doc, tool):
    doc.setPrompt("Click in the drawing area or enter the first point as 'x, y'")
    tool.setHandler("initialize", cline_tp_mode_init)
    tool.setHandler("left_button_press", cline_tp_first_left_button_press_cb)
    tool.setHandler("entry_event", cline_tp_first_entry_event_cb)

def cline_tp_first_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _viewLoc = _da.convertPoint_fromView_(_loc, None)
    _da.setTempPoint(_viewLoc)
    tool.setFirstPoint(_viewLoc.x, _viewLoc.y)
    tool.setHandler("mouse_move", cline_tp_mouse_move_cb)
    tool.setHandler("left_button_press", cline_tp_second_left_button_press_cb)
    tool.setHandler("entry_event", cline_tp_second_entry_event_cb)
    doc.setPrompt("Click in the drawing area or enter the second point as 'x, y'")

def cline_tp_second_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _sp = _da.convertPoint_fromView_(_loc, None)
    tool.setSecondPoint(_sp.x, _sp.y)
    CocoaEntities.create_entity(doc, tool)
        
def cline_tp_mouse_move_cb(doc, np, tool):
    _p1 = tool.getFirstPoint()
    _p2 = (np.x, np.y)
    _s = PythonCAD.Generic.conobject.ConstructionObject._ConstructionObject__defstyle
    _seg = PythonCAD.Generic.segment.Segment(_p1, _p2, _s)
    _da = doc.getDA()
    _da.setTempObject(_seg)

def cline_tp_first_entry_event_cb(doc, text, tool):
    if len(text):
        _x, _y = CocoaEntities.make_tuple(text)
        tool.setFirstPoint(_x, _y)
        tool.setHandler("mouse_move", cline_tp_mouse_move_cb)
        tool.setHandler("left_button_press", cline_tp_second_left_button_press_cb)
        tool.setHandler("entry_event", cline_tp_second_entry_event_cb)
        doc.setPrompt("Click in the drawing area or enter the second point as 'x, y'")
        doc.getDA().setTempPoint(NSMakePoint(_x, _y))

def cline_tp_second_entry_event_cb(doc, text, tool):
    if len(text):
        _x, _y = CocoaEntities.make_tuple(text)
        tool.setSecondPoint(_x, _y)
        CocoaEntities.create_entity(doc, tool)
    
#
# Parallel Construction Line
#
    
def cline_par_mode_init(doc, tool):
    doc.setPrompt("Click on the reference construction line")
    tool.setHandler("initialize", cline_par_mode_init)
    tool.setHandler("left_button_press", cline_par_first_left_button_press_cb)

def cline_par_first_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _viewLoc = _da.convertPoint_fromView_(_loc, None)
    _tol = _da.pointSize().width
    _image = doc.getImage()
    _objdict = _image.mapPoint(_viewLoc.x, _viewLoc.y, _tol, 1)
    if len(_objdict):
        _active_layer = _image.getActiveLayer()
        if _active_layer in _objdict:
            _objs = []
            for _obj, _pt in _objdict[_active_layer]:
                if isinstance(_obj, (PythonCAD.Generic.hcline.HCLine,
                                     PythonCAD.Generic.vcline.VCLine,
                                     PythonCAD.Generic.acline.ACLine,
                                     PythonCAD.Generic.cline.CLine)):
                    tool.setLocation(_viewLoc.x, _viewLoc.y)
                    tool.setConstructionLine(_obj)
                    tool.setHandler("left_button_press", cline_par_second_left_button_press_cb)
                    tool.delHandler("entry_event")
                    doc.setPrompt("Click in the drawing area to place the new construction line")

def cline_par_second_left_button_press_cb(doc, event, tool):
    _x1, _y1 = tool.getLocation()
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _sp = _da.convertPoint_fromView_(_loc, None)
    _x2, _y2 = _sp
    _offset = hypot((_x2 - _x1), (_y2 - _y1))
    tool.setOffset(_offset)
    tool.setReferencePoint(_sp.x, _sp.y)
    CocoaEntities.create_entity(doc, tool)


#
# Perpendicular to object construction line
#
def cline_perp_mode_init(doc, tool):
    doc.setPrompt("Click on the object to which you want a perpendicular")
    tool.setHandler("initialize", cline_perp_mode_init)
    tool.setHandler("left_button_press", cline_perp_left_button_press_cb)

def cline_perp_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _viewLoc = _da.convertPoint_fromView_(_loc, None)
    _tol = _da.pointSize().width
    _image = doc.getImage()
    _layer = _image.getActiveLayer()
    _hits = _layer.mapPoint((_viewLoc.x, _viewLoc.y), _tol, 1)
    if len(_hits):
        _obj, _pt = _hits[0]
        _lp = _layer.findObject(_pt)
        if _lp is None:
            _lp = _pt
            _image.addObject(_lp)
        if isinstance(_obj, PythonCAD.Generic.segment.Segment):
            _p1, _p2 = _obj.getEndpoints()
            _p1x, _p1y = _p1.getCoords()
            _p2x, _p2y = _p2.getCoords()
            if abs(_p1x - _p2x) < 1e-10: # vertical
                _image.addObject(PythonCAD.Generic.hcline.HCLine(_lp))
            elif abs(_p1y - _p2y) < 1e-10: # horizontal
                _image.addObject(PythonCAD.Generic.vcline.VCLine(_lp))
            else:
                _slope = (180.0/pi) * atan2((_p2y - _p1y),
                                            (_p2x - _p1x)) + 90.0
                _image.addObject(PythonCAD.Generic.acline.ACLine(_lp, _slope))
        elif isinstance(_obj, PythonCAD.Generic.circle.Circle):
            _cp = _obj.getCenter()
            _image.addObject(PythonCAD.Generic.cline.CLine(_cp, _lp))
        elif isinstance(_obj, PythonCAD.Generic.hcline.HCLine):
            _image.addObject(PythonCAD.Generic.vcline.VCLine(_lp))
        elif isinstance(_obj, PythonCAD.Generic.vcline.VCLine):
            _image.addObject(PythonCAD.Generic.hcline.HCLine(_lp))
        elif isinstance(_obj, PythonCAD.Generic.acline.ACLine):
            _angle = _obj.getAngle()
            if abs(_angle) < 1e-10: # horizontal
                _image.addObject(PythonCAD.Generic.vcline.VCLine(_lp))
            elif abs(abs(_angle) - 90.0) < 1e-10: # vertical
                _image.addObject(PythonCAD.Generic.hcline.HCLine(_lp))
            else:
                _slope = _angle + 90.0
                _image.addObject(PythonCAD.Generic.acline.ACLine(_lp, _slope))
        elif isinstance(_obj, PythonCAD.Generic.cline.CLine):
            _p1, _p2 = _obj.getKeypoints()
            _p1x, _p1y = _p1.getCoords()
            _p2x, _p2y = _p2.getCoords()
            if abs(_p1x - _p2x) < 1e-10: # vertical
                _image.addObject(PythonCAD.Generic.hcline.HCLine(_lp))
            elif abs(_p1y - _p2y) < 1e-10: # horizontal
                _image.addObject(PythonCAD.Generic.vcline.VCLine(_lp))
            else:
                _slope = (180.0/pi) * atan2((_p2y - _p1y),
                                            (_p2x - _p1x)) + 90.0
                _image.addObject(PythonCAD.Generic.acline.ACLine(_lp, _slope))
        else:
            _image.delObject(_lp)
            return
        # we have to call another function to generate
        # an event to flush out the notification system
        # and draw what we just added.  This one works
        # ok, I guess.
        CocoaEntities.create_entity(doc, tool)

#
# tangent to a circle construction line
#  
def cline_tan_mode_init(doc, tool):
    doc.setPrompt("Click on the circle to which you want a tangent")
    tool.setHandler("initialize", cline_tan_mode_init)
    tool.setHandler("left_button_press", cline_tan_left_button_press_cb)

def cline_tan_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _viewLoc = _da.convertPoint_fromView_(_loc, None)
    _tol = _da.pointSize().width
    _image = doc.getImage()
    _pt, _new_pt = _image.findPoint(_viewLoc.x, _viewLoc.y, _tol)
    if _pt is not None:
        _x, _y = _pt.getCoords()
        _layer = _image.getActiveLayer()
        _rtd = 180.0/pi
        # I think this is just supposed to be active layer
        _cobj = None
        _angle = None
        _circles = (_layer.getLayerEntities("circle") +
                    _layer.getLayerEntities("ccircle"))
        for _circle in _circles:
            _cx, _cy = _circle.getCenter().getCoords()
            _rad = _circle.getRadius()
            if hypot((_x - _cx), (_y - _cy)) - _rad < 1e-10:
                _cobj = _circle
                _angle = _rtd * atan2((_y - _cy), (_x - _cx))
                if _angle < 0.0:
                    _angle = _angle + 360.0
                break
        if _cobj is None:
            for _arc in _layer.getLayerEntities("arc"):
                _cx, _cy = _arc.getCenter().getCoords()
                _rad = _arc.getRadius()
                if hypot((_cx - _x), (_cy - _y)) - _rad < 1e-10:
                    _angle = _rtd * atan2((_y - _cy), (_x - _cx))
                    if _angle < 0.0:
                        _angle = _angle + 360.0
                    if _arc.throughAngle(_angle):
                        _cobj = _arc
                        break
        if _cobj is not None:
            if _new_pt:
                _image.addObject(_pt)
            if (abs(_angle) < 1e-6 or
                abs(_angle - 180.0) < 1e-6 or
                abs(_angle - 360.0) < 1e-6):
                _tcl = PythonCAD.Generic.vcline.VCLine(_pt)
            elif (abs(_angle - 90.0) < 1e-6 or
                  abs(_angle - 270.0) < 1e-6):
                _tcl = PythonCAD.Generic.hcline.HCLine(_pt)
            else:
                _slope = _angle + 90.0
                _tcl = PythonCAD.Generic.acline.ACLine(_pt, _slope)
            _image.addObject(_tcl)
            # we have to call another function to generate
            # an event to flush out the notification system
            # and draw what we just added.  This one works
            # ok, I guess.
            CocoaEntities.create_entity(doc, tool)
            return   

#
# tangent to two circle construction line
#
   
def cline_tan_2circ_mode_init(doc, tool):
    doc.setPrompt("Click on the first construction circle")
    tool.setHandler("initialize", cline_tan_2circ_mode_init)
    tool.setHandler("left_button_press", cline_tan_2circ_first_left_button_press_cb)
    
def cline_tan_2circ_first_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _viewLoc = _da.convertPoint_fromView_(_loc, None)
    _tol = _da.pointSize().width
    _image = doc.getImage()
    _objdict = _image.mapPoint(_viewLoc.x, _viewLoc.y, _tol, 1)
    if len(_objdict):
        _layer = _image.getActiveLayer()
        if _layer in _objdict:
            _objs = []
            for _obj, _pt in _objdict[_layer]:
                if isinstance(_obj, PythonCAD.Generic.ccircle.CCircle):
                    tool.setFirstCCircle(_obj)
                    tool.setHandler("left_button_press", cline_tan_2circ_second_left_button_press_cb)
                    doc.setPrompt("Click on the second construction circle")
                    
def cline_tan_2circ_second_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _viewLoc = _da.convertPoint_fromView_(_loc, None)
    _tol = _da.pointSize().width
    _image = doc.getImage()
    _objdict = _image.mapPoint(_viewLoc.x, _viewLoc.y, _tol, 1)
    if len(_objdict):
        _layer = _image.getActiveLayer()
        if _layer in _objdict:
            _objs = []
            for _obj, _pt in _objdict[_layer]:
                if isinstance(_obj, PythonCAD.Generic.ccircle.CCircle):
                    _fc = tool.getFirstCCircle()
                    if _obj is _fc:
                        return
                    tool.setSecondCCircle(_obj)
                    if tool.hasTangentPoints():
                        _draw_two_circle_tangents(doc, tool)
                        tool.setHandler("mouse_move", cline_tan_2circ_mouse_move_cb)
                        tool.setHandler("left_button_press", cline_tan_2circ_third_left_button_press_cb) 
                        doc.setPrompt("Click on the segment to keep")
                    else:
                        tool.reset()
                        cline_tan_2circ_mode_init(doc, tool)

def _draw_two_circle_tangents(doc, tool):
    _tanpts = tool.getTangentPoints()
    assert len(_tanpts), "No tangent points defined!"
    _da = doc.getDA()
    _da.setTempObject() #clear it out
    #
    # Make an interesting line style - should be defined globally?
    #
    _styles = PythonCAD.Generic.globals.prefs['STYLES']
    _s = None
    for _style in _styles:
        if _style.getName() == "Dashed Yellow Line":
            _s = _style
            break
    if _s is None:
        raise TypeError, "Style not found for dashed lines."
    for _set in _tanpts:
        _x1, _y1, _x2, _y2 = _set
        _p1 = (_x1, _y1)
        _p2 = (_x2, _y2)
        _seg = PythonCAD.Generic.segment.Segment(_p1, _p2, _s)
        _da.setTempObject(_seg, False)

# dummy function just for update - needs to only be called once
def cline_tan_2circ_mouse_move_cb(doc, np, tool):
    tool.delHandler("mouse_move")
    
def cline_tan_2circ_third_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _viewLoc = _da.convertPoint_fromView_(_loc, None)
    tool.setLocation(_viewLoc.x, _viewLoc.y)
    CocoaEntities.create_entity(doc, tool)
    # there's got to be a better way to do this,
    # but I give up.  Just redraw everything.
    _da.setNeedsDisplay_(True)
    
#
# Construction circle - center point
#

def ccircle_center_mode_init(doc, tool):
    doc.setPrompt("Click in the drawing area or enter a point as 'x, y'")
    tool.setHandler("initialize", ccircle_center_mode_init)
    tool.setHandler("left_button_press", ccircle_center_first_left_button_press_cb)
    tool.setHandler("entry_event", ccircle_point_entry_event_cb)
    
def ccircle_center_first_left_button_press_cb(doc, event, tool):
    CocoaEntities.circle_center_first_left_button_press_cb(doc, event, tool)
    tool.setHandler("mouse_move", ccircle_center_mouse_move_cb)

def ccircle_center_mouse_move_cb(doc, np, tool):
    _p1 = tool.getCenter()
    _r = hypot((_p1[0] - np.x), (_p1[1] - np.y))
    if _r > 0.0:
        _circle = PythonCAD.Generic.ccircle.CCircle(_p1, _r)
        _da = doc.getDA()
        _da.setTempObject(_circle)

def ccircle_point_entry_event_cb(doc, text, tool):
    if len(text):
        CocoaEntities.circle_point_entry_event_cb(doc, text, tool)
        tool.setHandler("mouse_move", ccircle_center_mouse_move_cb)        
    
#
# Construction circle - 2 point
#

def ccircle_tp_mode_init(doc, tool):
    doc.setPrompt("Click in the drawing area or enter a point as 'x, y'")
    tool.setHandler("initialize", ccircle_tp_mode_init)
    tool.setHandler("left_button_press", ccircle_tp_first_left_button_press_cb)
    tool.setHandler("entry_event", ccircle_tp_first_entry_event_cb)

def ccircle_tp_first_left_button_press_cb(doc, event, tool):
    CocoaEntities.circle_tp_first_left_button_press_cb(doc, event, tool)
    tool.setHandler("mouse_move", ccircle_tp_mouse_move_cb)

def ccircle_tp_mouse_move_cb(doc, np, tool):
    _x, _y = tool.getFirstPoint()
    _fp = NSMakePoint(_x, _y)
    if NSEqualPoints(_fp, np):
        return
    tool.setSecondPoint(np.x, np.y)
    _cp = tool.getCenter()
    _r = tool.getRadius()
    if _r is not None and _r > 0:
        _circle = PythonCAD.Generic.ccircle.CCircle(_cp, _r)
        _da = doc.getDA()
        _da.setTempObject(_circle)

def ccircle_tp_first_entry_event_cb(doc, text, tool):
    if len(text):
        CocoaEntities.circle_tp_first_entry_event_cb(doc, text, tool)
        tool.setHandler("mouse_move", ccircle_tp_mouse_move_cb)
    
#
# Construction circle - tangent
#

def ccircle_tan1_mode_init(doc, tool):
    doc.setPrompt("Click on the construction object used for tangency")
    tool.setHandler("initialize", ccircle_tan1_mode_init)
    tool.setHandler("left_button_press", ccircle_tan1_first_left_button_press_cb)

def ccircle_tan1_first_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _viewLoc = _da.convertPoint_fromView_(_loc, None)
    _tol = _da.pointSize().width
    _image = doc.getImage()
    _objdict = _image.mapPoint(_viewLoc.x, _viewLoc.y, _tol, 1)
    if len(_objdict):
        _active_layer = _image.getActiveLayer()
        if _active_layer in _objdict:
            _objs = []
            for _obj, _pt in _objdict[_active_layer]:
                if isinstance(_obj, (PythonCAD.Generic.hcline.HCLine,
                                     PythonCAD.Generic.vcline.VCLine,
                                     PythonCAD.Generic.acline.ACLine,
                                     PythonCAD.Generic.cline.CLine,
                                     PythonCAD.Generic.ccircle.CCircle)):
                    tool.setConstructionLine(_obj)
                    tool.setHandler("left_button_press", ccircle_final_left_button_press_cb)
                    tool.setHandler("mouse_move", ccircle_tan1_mouse_move_cb)
                    doc.setPrompt("Click in the drawing area to place the new construction line")

def ccircle_final_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _viewLoc = _da.convertPoint_fromView_(_loc, None)
    _tol = _da.pointSize().width
    _image = doc.getImage()
    _pt, _flag = _image.findPoint(_viewLoc.x, _viewLoc.y, _tol)
    if _pt is not None:
        _x, _y = _pt.getCoords()
        _viewLoc = NSMakePoint(_x, _y)
    tool.setLocation(_viewLoc.x, _viewLoc.y)
    CocoaEntities.create_entity(doc, tool)
    
def ccircle_tan1_mouse_move_cb(doc, np, tool):
    tool.setLocation(np.x, np.y)
    _cp = tool.getCenter()
    _r = tool.getRadius()
    if _r is not None and _r > 0:
        _circle = PythonCAD.Generic.ccircle.CCircle(_cp, _r)
        _da = doc.getDA()
        _da.setTempObject(_circle)
    
#
# Construction circle - 2 circle tangent
#

def ccircle_tan2_mode_init(doc, tool):
    doc.setPrompt("Click on the first construction line for tangency")
    tool.setHandler("initialize", ccircle_tan2_mode_init)
    tool.setHandler("left_button_press", ccircle_tan2_first_left_button_press_cb)
    
def ccircle_tan2_first_left_button_press_cb(doc, event, tool):
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _viewLoc = _da.convertPoint_fromView_(_loc, None)
    _tol = _da.pointSize().width
    _image = doc.getImage()
    _objdict = _image.mapPoint(_viewLoc.x, _viewLoc.y, _tol, 1)
    if len(_objdict):
        _active_layer = _image.getActiveLayer()
        if _active_layer in _objdict:
            _objs = []
            for _obj, _pt in _objdict[_active_layer]:
                if isinstance(_obj, (PythonCAD.Generic.hcline.HCLine,
                                     PythonCAD.Generic.vcline.VCLine,
                                     PythonCAD.Generic.acline.ACLine,
                                     PythonCAD.Generic.cline.CLine,
                                     PythonCAD.Generic.ccircle.CCircle)):
                    tool.setFirstConObject(_obj)
                    tool.setHandler("left_button_press", ccircle_tan2_second_left_button_press_cb)
                    doc.setPrompt("Click on the second construction line for tangency")
    
def ccircle_tan2_second_left_button_press_cb(doc, event, tool):  
    _loc = event.locationInWindow()
    _da = doc.getDA()
    _viewLoc = _da.convertPoint_fromView_(_loc, None)
    _tol = _da.pointSize().width
    _image = doc.getImage()
    _objdict = _image.mapPoint(_viewLoc.x, _viewLoc.y, _tol, 1)
    if len(_objdict):
        _active_layer = _image.getActiveLayer()
        if _active_layer in _objdict:
            _objs = []
            for _obj, _pt in _objdict[_active_layer]:
                if isinstance(_obj, (PythonCAD.Generic.hcline.HCLine,
                                     PythonCAD.Generic.vcline.VCLine,
                                     PythonCAD.Generic.acline.ACLine,
                                     PythonCAD.Generic.cline.CLine)):
                    tool.setSecondConObject(_obj)
                    tool.setHandler("left_button_press", ccircle_final_left_button_press_cb)
                    tool.setHandler("mouse_move", ccircle_tan2_mouse_move_cb)
                    doc.setPrompt("Click where you want the tangent circle to be")

def ccircle_tan2_mouse_move_cb(doc, np, tool):  
    tool.setLocation(np.x, np.y)
    _cp = tool.getCenter()
    _r = tool.getRadius()
    if _r is not None and _r > 0:
        _circle = PythonCAD.Generic.ccircle.CCircle(_cp, _r)
        _da = doc.getDA()
        _da.setTempObject(_circle)

    
