package main

import (
	"bytes"
	"fmt"
	"red-green/door"
	"strconv"
	"strings"
	"time"
)

func display_information(d *door.Door) {
	d.WriteS(door.Clrscr)

	var headerColor string = door.ColorText("BRI CYAN")
	var keyColor string = door.ColorText("BRI GREEN")
	var sepColor string = door.ColorText("BRI YEL")
	var valColor string = door.ColorText("CYAN")

	var nice_format func(string, string) string = func(key string, value string) string {
		return fmt.Sprintf("%s%-20s %s: %s%s", keyColor, key, sepColor, valColor, value) + door.CRNL
	}

	var offset string
	var header string = "DropFile: "
	offset = strings.Repeat(" ", len(header))

	d.WriteA(headerColor, header)
	d.WriteA(nice_format("Comm Type", strconv.Itoa(d.Config.Comm_type)))

	if d.Config.BBSID != "" {
		d.WriteA(offset, nice_format("BBS Software", d.Config.BBSID))
	}
	d.WriteA(offset, nice_format("Time Left", strconv.Itoa(d.Config.Time_left)))
	d.WriteA(offset, nice_format("Real Name", d.Config.Real_name))
	// d.Write(nice_format("Comm Handle", strconv.Itoa(d.Config.Comm_handle)))
	d.WriteA(offset, nice_format("Handle", d.Config.Handle))
	d.WriteA(offset, nice_format("User #", strconv.Itoa(d.Config.User_number)))
	d.WriteA(offset, nice_format("Security Level", strconv.Itoa(d.Config.Security_level)))
	d.WriteA(offset, nice_format("Node #", strconv.Itoa(d.Config.Node)))

	header = "Detected: "
	offset = strings.Repeat(" ", len(header))
	d.WriteA(door.CRNL, headerColor, header)
	d.WriteA(nice_format("Unicode", strconv.FormatBool(door.Unicode)))
	d.WriteA(offset, nice_format("CP437", strconv.FormatBool(door.CP437)))
	d.WriteA(offset, nice_format("Full CP437", strconv.FormatBool(door.Full_CP437)))
	d.WriteA(offset, nice_format("Screen Size", fmt.Sprintf("%d X %d", door.Width, door.Height)))
	var time time.Duration = d.TimeLeft()
	d.WriteA(offset, nice_format("Door Time Left", fmt.Sprintf("%d Hours, %d Minutes, %d Seconds", int(time.Hours()), int(time.Minutes())%60, int(time.Seconds())%60)))
	time = d.TimeUsed()
	d.WriteA(offset, nice_format("Door Time Used", fmt.Sprintf("%d Minutes, %d Seconds", int(time.Minutes()), int(time.Seconds())%60)))
	press_a_key(d)

	d.WriteA(door.Clrscr, door.CRNL, door.CRNL, door.CRNL)
	modules := GetModules()
	header = "Build:    "
	offset = strings.Repeat(" ", len(header))
	d.WriteA(headerColor, header)
	gover, gitver, goarch, goos := GetVersion()
	d.WriteA(nice_format("go version", gover))
	d.WriteA(offset, nice_format("git commit", gitver))
	d.WriteA(offset, nice_format("Arch", goarch))
	d.WriteA(offset, nice_format("OS", goos))
	for mod, version := range modules {
		d.WriteA(offset, nice_format(mod, version))
	}
}

func display_ansi(d *door.Door) {
	var art []string = ANSIGrowl()
	d.WriteS(door.Clrscr)
	for _, line := range art {
		d.WriteS(line + door.CRNL)
	}
}

func input_demo(d *door.Door) {
	var ticker *time.Ticker = time.NewTicker(time.Second)
	var StopIt = make(chan bool)

	go func() {
		for {
			select {
			case <-StopIt:
				return

			case t := <-ticker.C:
				const tf = "January 2, 2006 03:04:05 PM MST"
				output := door.SavePos + door.GotoS(5, 2) + door.ColorText("BRI WHI ON CYAN") + t.Format(tf) + door.RestorePos
				d.WriteS(output)
			}
		}
	}()

	var inputColor string = door.ColorText("BRI WHI ON BLUE")
	var inputColor2 string = door.ColorText("BRI WHI ON GREEN")
	var prompt door.Line = door.NewLine("What is YOUR Name: ")
	prompt.RenderF = door.RenderBlueYellow
	d.WriteA(prompt.Output(), inputColor)
	var name string = d.Input(25)
	d.WriteA(door.Reset, door.CRNL)
	prompt.Text.Reset()
	prompt.Text.WriteString("What is Your Quest:")
	d.WriteA(prompt.Output(), inputColor2)
	var quest string = d.Input(35)
	d.WriteA(door.Reset, door.CRNL)
	prompt.Text.Reset()
	prompt.Text.WriteString("What is your Favorite CoLoR: ")
	d.WriteA(prompt.Output(), inputColor)
	var color string = d.Input(15)
	d.WriteA(door.Reset, door.CRNL)
	ticker.Stop()
	StopIt <- true
	d.WriteA(fmt.Sprintf("You're %s on the %s quest, and fond of %s."+door.CRNL, name, quest, color))
}

func pctUpdate(pct *int64) func() int64 {
	return func() int64 {
		return *pct
	}
}

func progress_bars(d *door.Door) {
	d.WriteA(door.Clrscr)

	var barHalf door.BarLine = door.BarLine{Line: door.Line{DefaultColor: door.ColorText("BOLD YELLOW")}, Width: 20, Style: door.HALF_STEP}
	var barPercent door.BarLine = door.BarLine{Width: 30, Style: door.SOLID, PercentStyle: door.PERCENT_SPACE}

	barPercent.ColorRange = []door.BarRange{
		{Percent: 2500, Color: door.ColorText("RED")},
		{Percent: 5000, Color: door.ColorText("BROWN")},
		{Percent: 7500, Color: door.ColorText("BOLD YEL")},
		{Percent: 9500, Color: door.ColorText("GREEN")},
		{Percent: 10100, Color: door.ColorText("BRI GRE")}}

	var barGradient door.BarLine = door.BarLine{Width: 15, Style: door.GRADIENT, Line: door.Line{DefaultColor: door.ColorText("CYAN")}}

	var percentage int64
	barHalf.UpdateP = pctUpdate(&percentage)
	barPercent.UpdateP = pctUpdate(&percentage)
	barGradient.UpdateP = pctUpdate(&percentage)

	update_bars := func() {
		barHalf.Update()
		barPercent.Update()
		barGradient.Update()
	}

	d.WriteA(door.Goto(3, 12), "Half-Step")
	d.WriteA(door.Goto(25, 12), "% with space and Color Range")
	d.WriteA(door.Goto(57, 12), "Gradient")
	d.WriteA(door.HideCursor)

	bar_start := door.Goto(3, 15)

	for f := 0; f <= 100; f++ {

		d.WriteA(door.Goto(3, 10), door.Reset+fmt.Sprintf("Value: %d", f))
		percentage = int64(f * 100)

		update_bars()
		d.WriteA(bar_start, barHalf.Output(), "  ", door.Reset, barPercent.Output(), door.Reset+"  ", barGradient.Output())

		if d.Disconnect() {
			// don't continue to sleep if we're disconnected
			break
		}

		time.Sleep(time.Millisecond * 100)
	}
	d.WriteA(door.ShowCursor)
}

func width_demo(d *door.Door) {
	var w int = door.Width
	var panel door.Panel = door.Panel{X: 1, Y: 1, Width: w}
	var lineColor string = door.ColorText("WHI")
	var line string

	for y := 1; y <= door.Height; y++ {
		if y%10 == 0 {
			line = strings.Repeat("1234567890", w/10)
			for x := len(line); x < w; x++ {
				line += strconv.Itoa((x + 1) % 10)
			}
		} else {
			line = ""
			for x := 1; x < w; x++ {
				if x%10 == 0 {
					line += strconv.Itoa(y % 10)
				} else {
					line += " "
				}
			}
		}
		var l door.Line = door.Line{Text: bytes.NewBuffer([]byte(line)), DefaultColor: lineColor}
		panel.Lines = append(panel.Lines, l)
	}
	var message string = fmt.Sprintf("Screen Size: %d X %d", door.Width, door.Height)
	d.Write(panel.Output())

	// Output alert on top of panel
	var cx, cy int
	cx = (door.Width - len(message) + 2) / 2
	cy = (door.Height - 3) / 2
	var alert []string = door.AlertBox(message, 1)
	d.WriteA(door.ColorText("BRI YEL ON BLUE"))
	for idx, ab := range alert {
		d.WriteA(door.Goto(cx, cy+idx), ab)
	}
	d.WriteA(door.Reset, panel.GotoEnd())

	// Pause for key
	d.WaitKey(door.Inactivity)

	panel.Lines = make([]door.Line, 0)
	var background string = "BUGZ Test Door in GO "
	var bl int = len(background)
	for y := 1; y <= door.Height; y++ {
		offset := (y - 1) % bl
		line = background[offset:]
		for len(line) < w {
			if len(line)+bl <= w {
				line += background
			} else {
				line += background[0 : w-len(line)]
			}
		}
		var l door.Line = door.Line{Text: bytes.NewBuffer([]byte(line)), RenderF: door.RenderBlueYellow}
		panel.Lines = append(panel.Lines, l)
	}
	d.Write(panel.Output())
	d.WaitKey(door.Inactivity)
}