package door

import (
	"bytes"
	"fmt"
	"strings"
	"time"
)

/*
WOPR

[      GAME      ]
[  TIME ELAPSED  ]
[     XX HRS     ]
[ XX MIN  XX SEC ]
[■               ]  ->
[      GAME      ]
[ TIME REMAINING ]
[     XX HRS     ]
[ XX MIN  XX SEC ]
[               ■]  <-

Border SINGLE
Ok, Width = 16
1000 / 16 = 62.5 ms = 62500 us

Width 16  (at pos 1, update time/sec increment)
Black on Cyan

*/
type WOPR struct {
	ElapsedPanel   Panel
	Elapsed        time.Duration
	RemainingPanel Panel
	Remaining      time.Duration
	Color          string
	Index          int
	Ticker         *time.Ticker
}

// Initialize, Set X, Y on Panels, Animate()

// Initialize, and create panels
func (w *WOPR) Init(elapsed time.Duration, remaining time.Duration, color string) {
	if color == "" {
		color = ColorText("BLACK ON CYAN")
	}
	w.Elapsed = elapsed
	w.Remaining = remaining
	w.Index = 0
	w.ElapsedPanel = Panel{Width: 16,
		BorderColor: color,
		Style:       SINGLE}
	w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, Line{Text: "      GAME      "})
	w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, Line{Text: "  TIME ELAPSED  "})

	var ehour Line = Line{}
	ehour.UpdateF = func() string {
		var hours int = int(w.Elapsed.Hours())
		return fmt.Sprintf("     %02d HRS     ", hours%100)
	}
	ehour.Text = ehour.UpdateF()
	w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, ehour)

	var eminsec Line = Line{}
	eminsec.UpdateF = func() string {
		var mins int = int(w.Elapsed.Minutes()) % 60
		var secs int = int(w.Elapsed.Seconds()) % 60
		return fmt.Sprintf(" %02d MIN  %02d SEC ", mins, secs)
	}
	eminsec.Text = eminsec.UpdateF()
	w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, eminsec)

	var eanimate Line = Line{}
	eanimate.UpdateF = func() string {
		// Left to Right
		if Unicode {
			var buffer []rune = []rune(strings.Repeat(" ", 16))
			buffer[w.Index] = '\u25a0'
			return string(buffer)
		} else {
			var buffer []byte = bytes.Repeat([]byte(" "), 16)
			buffer[w.Index] = '\xfe'
			return string(buffer)
		}
	}
	eanimate.Text = eanimate.UpdateF()
	w.ElapsedPanel.Lines = append(w.ElapsedPanel.Lines, eanimate)

	w.RemainingPanel = Panel{Width: 16,
		BorderColor: color,
		Style:       SINGLE}
	w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, Line{Text: "      GAME      "})
	w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, Line{Text: " TIME REMAINING "})

	var rhour Line = Line{}
	rhour.UpdateF = func() string {
		var hours int = int(w.Remaining.Hours())
		return fmt.Sprintf("     %02d HRS     ", hours%100)
	}
	rhour.Text = rhour.UpdateF()
	w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, rhour)

	var rminsec Line = Line{}
	rminsec.UpdateF = func() string {
		var mins int = int(w.Remaining.Minutes()) % 60
		var secs int = int(w.Remaining.Seconds()) % 60
		return fmt.Sprintf(" %02d MIN  %02d SEC ", mins, secs)
	}
	rminsec.Text = rminsec.UpdateF()
	w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, rminsec)

	var ranimate Line = Line{}
	ranimate.UpdateF = func() string {
		// Left to Right
		if Unicode {
			var buffer []rune = []rune(strings.Repeat(" ", 16))
			buffer[15-w.Index] = '\u25a0'
			return string(buffer)
		} else {
			var buffer []byte = bytes.Repeat([]byte(" "), 16)
			buffer[15-w.Index] = '\xfe'
			return string(buffer)
		}
	}
	ranimate.Text = ranimate.UpdateF()
	w.RemainingPanel.Lines = append(w.RemainingPanel.Lines, ranimate)
}

func (w *WOPR) Inc() {
	w.Index++
	if w.Index == 16 {
		w.Remaining = time.Duration(w.Remaining.Seconds()-1) * time.Second
		w.Elapsed = time.Duration(w.Elapsed.Seconds()+1) * time.Second
		w.Index = 0
	}

}
func (w *WOPR) Animate(d *Door) {
	w.Ticker = time.NewTicker(time.Microsecond * time.Duration(62500))

	go func(d *Door) {
		var output string

		for range w.Ticker.C {
			w.ElapsedPanel.Update()
			w.RemainingPanel.Update()
			output = SavePos + w.ElapsedPanel.Output() + w.RemainingPanel.Output() + RestorePos
			if !d.Disconnect() {
				d.Write(output)
			} else {
				w.Ticker.Stop()
				return
			}

			w.Inc()
		}
	}(d)
}

func (w *WOPR) Stop() {
	w.Ticker.Stop()
}