
def getcenter(lEdges, r):
    import math
    rndEdges = lEdges[0:2]
    rndEdges = Part.__sortEdges__(rndEdges)

    lVertexes = rndEdges[0].Vertexes + [rndEdges[1].Vertexes[-1]]
    U1 = lVertexes[0].Point.sub(lVertexes[1].Point)
    U1.normalize()
    U2 = lVertexes[2].Point.sub(lVertexes[1].Point)
    U2.normalize()

    alpha = U1.getAngle(U2)
    # Edges have same direction
    '''if (round(alpha, 0) == 0) or (round(alpha - math.pi, 0) == 0):
        pt1 = FreeCAD.Vector(U1)
        x = pt1.x
        pt1.x = pt1.y
        pt1.y = -x
        return rndEdges
        pointsDirection = lineSelected.discretize(Number=500)  # discretize the path line first selection
        v = pointsDirection[0].sub(pointsDirection[1])  # avec vecteurs 1 et 2 (direction debut ligne)
        r = App.Rotation(App.Vector(0, 0, 1), v)'''

    dToCenter = r / math.sin(alpha / 2.0)
    # dToTangent = (dToCenter ** 2 - r ** 2) ** 0.5
    dirVect = U2.add(U1)
    dirVect.normalize()
    dirVect.scale(dToCenter, dToCenter, dToCenter)
    pt1 = lVertexes[1].Point.add(dirVect)
    pt2 = -1 * pt1
    pt2.z = pt1.z
    print(pt1, " - ", pt2)
    return [pt1, pt2]

# from DRAFT
def split_wire(wire, newPoint, edgeIndex):
    import Draft
    wire1Points = []
    wire2Points = []
    print("New Point: ", newPoint)
    print("edgeIndex: ", edgeIndex)
    for index, point in enumerate(wire.Points):
        print("index: ", index, " - point: ", point)
        if index == edgeIndex:
            wire1Points.append(point)
            wire1Points.append(wire.Placement.inverse().multVec(newPoint))
            wire2Points.append(newPoint)
            # wire2Points.append(wire.Placement.multVec(point))
        elif index < edgeIndex:
            wire1Points.append(point)
        elif index > edgeIndex:
            wire2Points.append(wire.Placement.multVec(point))
    if len(wire1Points) == 1:
        wire1Points.insert(0, wire.Points[0])
    if len(wire2Points) == 1:
        wire2Points.appen(wire.Points[-1])
    wire.Points = wire1Points
    wire2 = Draft.makeWire(wire2Points, placement=wire.Placement)
    FreeCAD.ActiveDocument.recompute()
    wires = [wire, wire2]
    return sorted(wires, key=lambda obj: obj.Length, reverse=True)


def SplitTrench(trench, point):
    if not trench or not point:
        return None

    import Part
    wire = trench.Base
    vertex = Part.Vertex(point)

    '''Find the minimum distance to another shape:

    - distToShape(shape) -> (dist, vectors, infos) dist is the minimum distance, in mm (float value).
        vectors is a list of pairs of App.Vector. Each pair corresponds to solution.

    Example: 
      [(Vector (2.0, -1.0, 2.0), Vector (2.0, 0.0, 2.0)), (Vector (2.0,-1.0, 2.0), Vector (2.0, -1.0, 3.0))] 
        - First vector is a point on self, second vector is a point on s.
      infos contains additional info on the solutions. It is a list of tuples: (topo1, index1, params1, topo2, index2, params2)
        - topo1, topo2 are strings identifying type of BREP element: 'Vertex', 'Edge', or 'Face'.
        - index1, index2 are indexes of the elements (zero-based).
        - params1, params2 are parameters of internal space of the elements. For vertices, params is None. 
          For edges, params is one float, u. For faces, params is a tuple (u,v).
    (719762.0578530617, 
    [(Vector (225057.375, 783988.625, 715062.875), Vector (306961.4605149741, 778138.3688035253, 0.0))], 
    [('Vertex', 0, None, 'Edge', 0, 79697.52668425611)])
    '''

    (dist, vectors, infos) = vertex.distToShape(wire.Shape)
    if not dist:
        return None

    Location = FreeCAD.Vector(vectors[0][1])
    if not Location:
        return None

    Normal = None
    edind = 0
    if infos[0][3] == 'Vertex':
        vec = Location.sub(point)
        Normal = FreeCAD.Vector(vec[1], -vec[0], vec[2])
        edind = int(infos[0][4]) - 1
    elif infos[0][3] == 'Edge':
        ed = wire.Shape.Edges[int(dist[2][0][4])]
        Normal = ed.Vertexes[1].Point.sub(ed.Vertexes[0].Point)
        edind = int(infos[0][4])

    wires = split_wire(wire, Location, edind)
    trench.Base = wires[0]
    trench1 = makeTrench(wire[1])
    return Location, [trench, trench1], node

def JoinTrench(trench1, trench2):
    if not trench1 or not trench2:
        return None


class CommandSplitTrench:  # V1:
    """Gui command for the Line tool."""

    def GetResources(self):
        """Set icon, menu and tooltip."""
        return {'Pixmap': str(os.path.join(DirIcons, "trench.svg")),
                'MenuText': "Trench",
                'Accel': "C, T",
                'ToolTip': "Creates a Trench object from setup dialog."}

    def IsActive(self):
        return (not (FreeCAD.ActiveDocument is None) and
                not (FreeCAD.ActiveDocument.getObject("Trench") is None))

    def Activated(self):
        """Execute when the command is called."""

        sel = FreeCADGui.Selection.getSelection()
        done = False

        if len(sel) > 0:
            import Draft
            for obj in sel:
                if Draft.getType(obj) == "Wire":
                    FreeCAD.ActiveDocument.openTransaction("Create Trench")
                    makeTrench(obj)
                    FreeCAD.ActiveDocument.commitTransaction()
                    FreeCAD.ActiveDocument.recompute()
                    done = True
                    break

        if not done:
            taskd = TrenchTaskPanel()
            if taskd:
                FreeCADGui.Control.showDialog(taskd)
            else:
                print(" No ha sido posible crear el formulario")


class CommandJoinTrench:  # V1:
    """Gui command for the Line tool."""

    def GetResources(self):
        """Set icon, menu and tooltip."""
        return {'Pixmap': str(os.path.join(DirIcons, "trenchsplit.svg")),
                'MenuText': "Semi-Automatic Trench Generator",
                'Accel': "T, S",
                'ToolTip': "Creates a Trench object from setup dialog."}

    def IsActive(self):
        return (not (FreeCAD.ActiveDocument is None) and
                not (FreeCAD.ActiveDocument.getObject("Trench") is None))

    def Activated(self):
        """Execute when the command is called."""
        semi = semiAutomaticTrench()


if FreeCAD.GuiUp:
    class CommandTrenchGroup:

        def GetCommands(self):
            return tuple(['PVPlantSplitTrench',
                          'PVPlantJoinTrench',
                          ])

        def GetResources(self):
            return {'MenuText': 'Trench operations',
                    'ToolTip': 'Trench operations'
                    }

        def IsActive(self):
            active = not (FreeCAD.ActiveDocument is None)
            terrain = not (FreeCAD.ActiveDocument.getObject("Terrain") is None)
            active = active and terrain
            if terrain:
                active = active and not (FreeCAD.ActiveDocument.getObject("Terrain").Mesh is None)
            return active

    FreeCADGui.addCommand('PVPlantTrench', CommandTrench())
    FreeCADGui.addCommand('PVPlantSemiAutomaticTrench', CommandSemiAutomaticTrench())
    FreeCADGui.addCommand('Trenches', CommandTrenchGroup())