package d2isometric

import (
	
	
	
	
	
)

// A sequence scope is an explicit source container, or the source root (-1).
// The exporter omits the root's sequence type in many compiled diagrams, so
// an exact synthetic lifeline also confirms that scope. Z indices alone do
// not classify unrelated shapes in a mixed ordinary/sequence diagram.
func classifySequence( *Scene,  map[string]int,  []int) {
	 := map[int]bool{-1: .Root.Type == d2target.ShapeSequenceDiagram}
	 := make([]int, len(.Nodes))
	for  := range .Nodes {
		[] = -1
		for  := [];  >= 0;  = [] {
			if .Nodes[].Type == d2target.ShapeSequenceDiagram {
				[] = 
				break
			}
		}
		if .Nodes[].Type == d2target.ShapeSequenceDiagram {
			.Nodes[].SequenceRole = "container"
			[] = true
		}
	}
	for  := range .Edges {
		 := &.Edges[]
		,  := [.Source]
		,  := [.Target]
		if ! ||  || .Metadata.Original.ZIndex != d2sequence.LIFELINE_Z_INDEX ||
			.SourceArrow != d2target.NoArrowhead || .TargetArrow != d2target.NoArrowhead || len(.Metadata.Original.Route) != 2 {
			continue
		}
		// Object.ID is formatted D2 syntax, not the decoded IDVal. The
		// synthetic hash retains quoting around dots, quotes and escapes.
		,  := d2parser.ParseKey(.Source)
		if  != nil || len(.Path) == 0 {
			continue // BuildScene already validated every real source node ID.
		}
		 := d2format.Format(&d2ast.KeyPath{Path: .Path[len(.Path)-1:]})
		if .Target != d2sequence.LifelineEndID() {
			continue
		}
		.SequenceRole = "lifeline"
		.Nodes[].SequenceRole = "actor"
		[[]] = true
	}
	for ,  := range  {
		.HasSequence = .HasSequence || 
	}
	if !.HasSequence {
		return
	}
	for  := range .Nodes {
		 := &.Nodes[]
		if .SequenceRole != "" || ![[]] {
			continue
		}
		switch .Metadata.Original.ZIndex {
		case d2sequence.SPAN_Z_INDEX:
			.SequenceRole = "span"
		case d2sequence.GROUP_Z_INDEX:
			if .Metadata.Original.Blend {
				.SequenceRole = "group"
			}
		case d2sequence.NOTE_Z_INDEX:
			.SequenceRole = "note"
		}
	}
	for  := range .Edges {
		 := &.Edges[]
		,  := [.Source]
		,  := [.Target]
		if .SequenceRole == "" && .Metadata.Original.ZIndex == d2sequence.MESSAGE_Z_INDEX &&
			 &&  && [] == [] && [[]] {
			.SequenceRole = "message"
		}
	}
	// ParentID remains the authored hierarchy. A span or note is a timeline
	// annotation of an actor, not evidence that the actor encloses its box.
	// Real ordinary children still turn their actor into a physical container.
	for  := range .Nodes {
		.Nodes[].Container = .Nodes[].SequenceRole == "container"
	}
	for  := range .Nodes {
		if sequenceSemanticChild(.Nodes[].SequenceRole) {
			continue
		}
		 := []
		for  >= 0 && sequenceSemanticChild(.Nodes[].SequenceRole) {
			 = []
		}
		if  >= 0 {
			.Nodes[].Container = true
		}
	}
}

func sequenceSemanticChild( string) bool {
	return  == "span" ||  == "note" ||  == "group"
}