package d2sequence

import (
	
	

	

	
	
	
	
)

// Layout runs the sequence diagram layout engine on objects of shape sequence_diagram
//
// 1. Run layout on sequence diagrams
// 2. Set the resulting dimensions to the main graph shape
func ( context.Context,  *d2graph.Graph,  d2graph.LayoutGraph) error {
	// used in layout code
	.Root.Shape.Value = d2target.ShapeSequenceDiagram

	,  := layoutSequenceDiagram(, .Root)
	if  != nil {
		return 
	}
	.Root.Box = geo.NewBox(nil, .getWidth()+GROUP_CONTAINER_PADDING*2, .getHeight()+GROUP_CONTAINER_PADDING*2)

	// the sequence diagram is the only layout engine if the whole diagram is
	// shape: sequence_diagram
	.Root.TopLeft = geo.NewPoint(0, 0)

	 := .Root

	.LabelPosition = go2.Pointer(label.InsideTopCenter.String())

	// shift the sequence diagrams as they are always placed at (0, 0) with some padding
	.shift(
		geo.NewPoint(
			.TopLeft.X+GROUP_CONTAINER_PADDING,
			.TopLeft.Y+GROUP_CONTAINER_PADDING,
		),
	)

	.Children = make(map[string]*d2graph.Object)
	.ChildrenArray = make([]*d2graph.Object, 0)
	for ,  := range .actors {
		.Children[strings.ToLower(.ID)] = 
		.ChildrenArray = append(.ChildrenArray, )
	}
	for ,  := range .groups {
		if .Parent.AbsID() == .AbsID() {
			.Children[strings.ToLower(.ID)] = 
			.ChildrenArray = append(.ChildrenArray, )
		}
	}

	.Edges = append(.Edges, .lifelines...)

	return nil
}

// layoutSequenceDiagram finds the edges inside the sequence diagram and performs the layout on the object descendants
func layoutSequenceDiagram( *d2graph.Graph,  *d2graph.Object) (*sequenceDiagram, error) {
	var  []*d2graph.Edge
	for ,  := range .Edges {
		// both Src and Dst must be inside the sequence diagram
		if  == .Root || (strings.HasPrefix(.Src.AbsID(), .AbsID()+".") && strings.HasPrefix(.Dst.AbsID(), .AbsID()+".")) {
			 = append(, )
		}
	}

	,  := newSequenceDiagram(.ChildrenArray, )
	if  != nil {
		return nil, 
	}
	 = .layout()
	return , 
}