package parser

import (
	
	
	
)

type linkReferenceParagraphTransformer struct {
}

// LinkReferenceParagraphTransformer is a ParagraphTransformer implementation
// that parses and extracts link reference from paragraphs.
var LinkReferenceParagraphTransformer = &linkReferenceParagraphTransformer{}

func ( *linkReferenceParagraphTransformer) ( *ast.Paragraph,  text.Reader,  Context) {
	 := .Lines()
	 := text.NewBlockReader(.Source(), )
	 := [][2]int{}
	for {
		,  := parseLinkReferenceDefinition(, )
		if  > -1 {
			if  ==  {
				++
			}
			 = append(, [2]int{, })
			continue
		}
		break
	}

	 := 0
	for ,  := range  {
		if .Len() == 0 {
			break
		}
		 := .Sliced([1]-, .Len())
		.SetSliced(0, [0]-)
		.AppendAll()
		 = [1]
	}

	if .Len() == 0 {
		 := ast.NewTextBlock()
		.SetBlankPreviousLines(.HasBlankPreviousLines())
		.Parent().ReplaceChild(.Parent(), , )
		return
	}

	.SetLines()
}

func parseLinkReferenceDefinition( text.Reader,  Context) (int, int) {
	.SkipSpaces()
	,  := .PeekLine()
	if  == nil {
		return -1, -1
	}
	,  := .Position()
	,  := util.IndentWidth(, 0)
	if  > 3 {
		return -1, -1
	}
	if  != 0 {
		++
	}
	if [] != '[' {
		return -1, -1
	}
	.Advance( + 1)
	,  := .FindClosure('[', ']', linkFindClosureOptions)
	if ! {
		return -1, -1
	}
	var  []byte
	if .Len() == 1 {
		 = .Value(.At(0))
	} else {
		for  := 0;  < .Len(); ++ {
			 := .At()
			 = append(, .Value()...)
		}
	}
	if util.IsBlank() {
		return -1, -1
	}
	if .Peek() != ':' {
		return -1, -1
	}
	.Advance(1)
	.SkipSpaces()
	,  := parseLinkDestination()
	if ! {
		return -1, -1
	}
	, _ = .PeekLine()
	 :=  == nil || util.IsBlank()

	,  := .Position()
	, ,  := .SkipSpaces()
	 := .Peek()
	if  != '"' &&  != '\'' &&  != '(' {
		if ! {
			return -1, -1
		}
		 := NewReference(, , nil)
		.AddReference()
		return ,  + 1
	}
	if  == 0 {
		return -1, -1
	}
	.Advance(1)
	 := 
	if  == '(' {
		 = ')'
	}
	,  = .FindClosure(, , linkFindClosureOptions)
	if ! {
		if ! {
			return -1, -1
		}
		 := NewReference(, , nil)
		.AddReference()
		.AdvanceLine()
		return ,  + 1
	}
	var  []byte
	if .Len() == 1 {
		 = .Value(.At(0))
	} else {
		for  := 0;  < .Len(); ++ {
			 := .At()
			 = append(, .Value()...)
		}
	}

	, _ = .PeekLine()
	if  != nil && !util.IsBlank() {
		if ! {
			return -1, -1
		}
		 := NewReference(, , )
		.AddReference()
		return , 
	}

	, _ = .Position()
	 := NewReference(, , )
	.AddReference()
	return ,  + 1
}