package cview

import (
	
	

	
)

// ProgressBar indicates the progress of an operation.
type ProgressBar struct {
	*Box

	// Rune to use when rendering the empty area of the progress bar.
	emptyRune rune

	// Color of the empty area of the progress bar.
	emptyColor tcell.Color

	// Rune to use when rendering the filled area of the progress bar.
	filledRune rune

	// Color of the filled area of the progress bar.
	filledColor tcell.Color

	// If set to true, instead of filling from left to right, the bar is filled
	// from bottom to top.
	vertical bool

	// Current progress.
	progress int

	// Progress required to fill the bar.
	max int

	sync.RWMutex
}

// NewProgressBar returns a new progress bar.
func () *ProgressBar {
	 := &ProgressBar{
		Box:         NewBox(),
		emptyRune:   tcell.RuneBlock,
		emptyColor:  Styles.PrimitiveBackgroundColor,
		filledRune:  tcell.RuneBlock,
		filledColor: Styles.PrimaryTextColor,
		max:         100,
	}
	.SetBackgroundColor(Styles.PrimitiveBackgroundColor)
	return 
}

// SetEmptyRune sets the rune used for the empty area of the progress bar.
func ( *ProgressBar) ( rune) {
	.Lock()
	defer .Unlock()

	.emptyRune = 
}

// SetEmptyColor sets the color of the empty area of the progress bar.
func ( *ProgressBar) ( tcell.Color) {
	.Lock()
	defer .Unlock()

	.emptyColor = 
}

// SetFilledRune sets the rune used for the filled area of the progress bar.
func ( *ProgressBar) ( rune) {
	.Lock()
	defer .Unlock()

	.filledRune = 
}

// SetFilledColor sets the color of the filled area of the progress bar.
func ( *ProgressBar) ( tcell.Color) {
	.Lock()
	defer .Unlock()

	.filledColor = 
}

// SetVertical sets the direction of the progress bar.
func ( *ProgressBar) ( bool) {
	.Lock()
	defer .Unlock()

	.vertical = 
}

// SetMax sets the progress required to fill the bar.
func ( *ProgressBar) ( int) {
	.Lock()
	defer .Unlock()

	// TODO progress bar needs at least 1 step, or the drawing will hang
	if  < 1 {
		 = 1
	}
	.max = 
}

// GetMax returns the progress required to fill the bar.
func ( *ProgressBar) () int {
	.RLock()
	defer .RUnlock()

	return .max
}

// AddProgress adds to the current progress.
func ( *ProgressBar) ( int) {
	.Lock()
	defer .Unlock()

	.progress += 
	if .progress < 0 {
		.progress = 0
	} else if .progress > .max {
		.progress = .max
	}
}

// SetProgress sets the current progress.
func ( *ProgressBar) ( int) {
	.Lock()
	defer .Unlock()

	.progress = 
	if .progress < 0 {
		.progress = 0
	} else if .progress > .max {
		.progress = .max
	}
}

// GetProgress gets the current progress.
func ( *ProgressBar) () int {
	.RLock()
	defer .RUnlock()

	return .progress
}

// Complete returns whether the progress bar has been filled.
func ( *ProgressBar) () bool {
	.RLock()
	defer .RUnlock()

	return .progress >= .max
}

// Draw draws this primitive onto the screen.
func ( *ProgressBar) ( tcell.Screen) {
	if !.GetVisible() {
		return
	}

	.Box.Draw()

	.Lock()
	defer .Unlock()

	, , ,  := .GetInnerRect()

	 := 
	 := 
	if .vertical {
		 = 
		 = 
	}

	 := int(math.RoundToEven(float64() * (float64(.progress) / float64(.max))))
	if  >  {
		 = 
	}

	for  := 0;  < ; ++ {
		for  := 0;  < ; ++ {
			if .vertical {
				.SetContent(+, +(-1-), .filledRune, nil, tcell.StyleDefault.Foreground(.filledColor).Background(.backgroundColor))
			} else {
				.SetContent(+, +, .filledRune, nil, tcell.StyleDefault.Foreground(.filledColor).Background(.backgroundColor))
			}
		}
		for  := ;  < ; ++ {
			if .vertical {
				.SetContent(+, +(-1-), .emptyRune, nil, tcell.StyleDefault.Foreground(.emptyColor).Background(.backgroundColor))
			} else {
				.SetContent(+, +, .emptyRune, nil, tcell.StyleDefault.Foreground(.emptyColor).Background(.backgroundColor))
			}
		}
	}
}