package door

import "strings"

type BorderStyle int

const (
	NONE BorderStyle = iota
	SINGLE
	DOUBLE
	DOUBLE_SINGLE
	SINGLE_DOUBLE
)

type Panel struct {
	X           int
	Y           int
	Width       int
	Style       BorderStyle
	BorderColor string
	Lines       []Line
	Title       string
	TitleOffset int
}

// Output the panel
func (p *Panel) Output() string {
	var style int = int(p.Style)
	var box_style *BoxStyle
	var output string

	if style > 0 {
		if Unicode {
			box_style = &BOXES_UNICODE[style-1]
		} else {
			box_style = &BOXES[style-1]
		}
	}

	row := p.Y
	if style > 0 {
		// Top line / border
		output += Goto(p.X, row) + p.BorderColor + box_style.top_left
		if p.Title != "" {
			output += strings.Repeat(box_style.top, p.TitleOffset) + p.Title
		}
		output += strings.Repeat(box_style.top, p.Width-(p.TitleOffset+len(p.Title))) + box_style.top_right
		row++
	}

	for _, line := range p.Lines {
		output += Goto(p.X, row)

		// "Joining" lines code

		// We are not joining lines at this time.

		if style > 0 {
			output += p.BorderColor + box_style.side
		}
		output += line.Output()
		if style > 0 {
			output += p.BorderColor + box_style.side
		}
		row++
	}

	if style > 0 {
		// Bottom / border
		output += Goto(p.X, row) + p.BorderColor + box_style.bottom_left
		output += strings.Repeat(box_style.top, p.Width) + box_style.bottom_right
	}
	return output
}

// Output anything that has updated
func (p *Panel) Update() string {
	var output string
	var style int = int(p.Style)

	row := p.Y
	col := p.X
	if style > 0 {
		row++
		col++
	}

	for _, line := range p.Lines {
		if line.Update() {
			// Yes, line was updated
			output += Goto(col, row) + line.Output()
		}
		row++
	}
	return output
}

// Output the updated line
func (p *Panel) UpdateLine(index int) string {
	var output string
	var style int = int(p.Style)

	row := p.Y + index
	col := p.X
	if style > 0 {
		row++
		col++
	}
	line := &p.Lines[index]
	output += Goto(col, row) + line.Output()
	return output
}

// Goto the end
func (p *Panel) GotoEnd() string {
	row := p.Y
	col := p.X
	if p.Style > 0 {
		row++
		col += 2
	}
	row += len(p.Lines)
	col += p.Width

	return Goto(col, row)
}

// Is the top line of this style a single line?
func Single(bs BorderStyle) bool {
	switch bs {
	case SINGLE, SINGLE_DOUBLE:
		return true
	default:
		return false
	}
}

// Create a spacer line that will be connected maybe to the sides.
func (p *Panel) Spacer() Line {
	l := Line{}
	var pos int

	if Single(p.Style) {
		pos = 0
	} else {
		pos = 1
	}

	if Unicode {
		l.Text = strings.Repeat(BOXES[pos].top, p.Width)
	} else {
		l.Text = strings.Repeat(BOXES_UNICODE[pos].top, p.Width)
	}
	return l
}