// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package language

import (
	
	
)

// A Builder allows constructing a Tag from individual components.
// Its main user is Compose in the top-level language package.
type Builder struct {
	Tag Tag

	private    string // the x extension
	variants   []string
	extensions []string
}

// Make returns a new Tag from the current settings.
func ( *Builder) () Tag {
	 := .Tag

	if len(.extensions) > 0 || len(.variants) > 0 {
		sort.Sort(sortVariants(.variants))
		sort.Strings(.extensions)

		if .private != "" {
			.extensions = append(.extensions, .private)
		}
		 := maxCoreSize + tokenLen(.variants...) + tokenLen(.extensions...)
		 := make([]byte, )
		 := .genCoreBytes()
		.pVariant = byte()
		 += appendTokens([:], .variants...)
		.pExt = uint16()
		 += appendTokens([:], .extensions...)
		.str = string([:])
		// We may not always need to remake the string, but when or when not
		// to do so is rather tricky.
		 := makeScanner([:])
		, _ = parse(&, "")
		return 

	} else if .private != "" {
		.str = .private
		.RemakeString()
	}
	return 
}

// SetTag copies all the settings from a given Tag. Any previously set values
// are discarded.
func ( *Builder) ( Tag) {
	.Tag.LangID = .LangID
	.Tag.RegionID = .RegionID
	.Tag.ScriptID = .ScriptID
	// TODO: optimize
	.variants = .variants[:0]
	if  := .Variants();  != "" {
		for ,  := range strings.Split([1:], "-") {
			.variants = append(.variants, )
		}
	}
	.extensions, .private = .extensions[:0], ""
	for ,  := range .Extensions() {
		.AddExt()
	}
}

// AddExt adds extension e to the tag. e must be a valid extension as returned
// by Tag.Extension. If the extension already exists, it will be discarded,
// except for a -u extension, where non-existing key-type pairs will added.
func ( *Builder) ( string) {
	if [0] == 'x' {
		if .private == "" {
			.private = 
		}
		return
	}
	for ,  := range .extensions {
		if [0] == [0] {
			if [0] == 'u' {
				.extensions[] += [1:]
			}
			return
		}
	}
	.extensions = append(.extensions, )
}

// SetExt sets the extension e to the tag. e must be a valid extension as
// returned by Tag.Extension. If the extension already exists, it will be
// overwritten, except for a -u extension, where the individual key-type pairs
// will be set.
func ( *Builder) ( string) {
	if [0] == 'x' {
		.private = 
		return
	}
	for ,  := range .extensions {
		if [0] == [0] {
			if [0] == 'u' {
				.extensions[] =  + [1:]
			} else {
				.extensions[] = 
			}
			return
		}
	}
	.extensions = append(.extensions, )
}

// AddVariant adds any number of variants.
func ( *Builder) ( ...string) {
	for ,  := range  {
		if  != "" {
			.variants = append(.variants, )
		}
	}
}

// ClearVariants removes any variants previously added, including those
// copied from a Tag in SetTag.
func ( *Builder) () {
	.variants = .variants[:0]
}

// ClearExtensions removes any extensions previously added, including those
// copied from a Tag in SetTag.
func ( *Builder) () {
	.private = ""
	.extensions = .extensions[:0]
}

func tokenLen( ...string) ( int) {
	for ,  := range  {
		 += len() + 1
	}
	return
}

func appendTokens( []byte,  ...string) int {
	 := 0
	for ,  := range  {
		[] = '-'
		copy([+1:], )
		 += 1 + len()
	}
	return 
}

type sortVariants []string

func ( sortVariants) () int {
	return len()
}

func ( sortVariants) (,  int) {
	[], [] = [], []
}

func ( sortVariants) (,  int) bool {
	return variantIndex[[]] < variantIndex[[]]
}