package main

import (
	"strings"
	"time"
	gc "github.com/rthornton128/goncurses"
)

func login(stdscr *gc.Window, in chan gc.Key) (username , password string) {
	gc.Cursor(1)
	stdscr.Clear()

	// Initialize the fields and Set field options
	fields := make([]*gc.Field, 3)
	fields[0], _ = gc.NewField(1, 28, 2, 12, 0, 0)
	defer fields[0].Free()
	fields[0].SetBackground(gc.ColorPair(5) | gc.A_UNDERLINE)
	fields[0].SetOptionsOff(gc.FO_AUTOSKIP)

	fields[1], _ = gc.NewField(1, 28, 4, 12, 0, 0)
	defer fields[1].Free()
	fields[1].SetBackground(gc.ColorPair(5) | gc.A_UNDERLINE)
	fields[1].SetOptionsOff(gc.FO_PUBLIC)
	fields[1].SetOptionsOff(gc.FO_AUTOSKIP)

	fields[2], _ = gc.NewField(1, 11, 7, 18, 0, 0)
	defer fields[2].Free()
	fields[2].SetBuffer("< Connect >")
	fields[2].SetBackground(gc.ColorPair(1))
	fields[2].SetOptionsOff(gc.FO_EDIT)
	fields[2].SetOptionsOff(gc.FO_AUTOSKIP)

	// Create the form and post it
	form, _ := gc.NewForm(fields)
	defer form.Free()

	// Create the window to be associated with the form
	rows, cols := stdscr.MaxYX()
	height, width := 14, 44
	y, x := (rows-height)/2, (cols-width)/2

	mainwin, _ := gc.NewWindow(height, width, y, x)
	defer mainwin.Delete()
	defer mainwin.Erase()
	mainwin.Keypad(true)

	// Set main window and sub window
	form.SetWindow(mainwin)
	form.SetSub(mainwin.Derived(8, 42, 3, 1))

	// Print a border around the main window and print a title
	mainwin.Box(0, 0)

	y, x = mainwin.MaxYX()
	title := "SRS ADLIN - Login"
	mainwin.ColorOn(2)
	mainwin.MovePrint(1, (x/2)-(len(title)/2), title)
	mainwin.ColorOff(1)
	mainwin.MoveAddChar(2, 0, gc.ACS_LTEE)
	mainwin.HLine(2, 1, gc.ACS_HLINE, x-2)
	mainwin.MoveAddChar(2, x-1, gc.ACS_RTEE)
	stdscr.Refresh()

	form.Post()
	defer form.UnPost()

	mainwin.MovePrint(5, 3, "Login:")
	mainwin.MovePrint(7, 3, "Password:")

	form.Driver(gc.REQ_FIRST_FIELD)

	stdscr.Refresh()
	mainwin.Refresh()

login:
	for {
		select {
		case ch := <- in:
			switch ch {
			case gc.KEY_DOWN, gc.KEY_TAB:
				form.Driver(gc.REQ_NEXT_FIELD)
				form.Driver(gc.REQ_END_LINE)
			case gc.KEY_UP:
				form.Driver(gc.REQ_PREV_FIELD)
				form.Driver(gc.REQ_END_LINE)
			case gc.KEY_BACKSPACE:
				form.Driver(gc.REQ_CLR_FIELD)
			case gc.KEY_RETURN:
				form.Driver(gc.REQ_NEXT_FIELD)
				form.Driver(gc.REQ_END_LINE)
				if len(strings.TrimSpace(fields[0].Buffer())) > 0 && len(strings.TrimSpace(fields[1].Buffer())) > 0 {
					break login
				}
			default:
				form.Driver(ch)
			}
		}
		mainwin.Refresh()
	}

	username = strings.TrimSpace(fields[0].Buffer())
	password = strings.TrimSpace(fields[1].Buffer())

	return
}

func connection(stdscr *gc.Window, in chan gc.Key, validator chan bool, validator_err chan error) (canContinue bool) {
	gc.Cursor(0)
	stdscr.Clear()

	// Create the window to be associated with the form
	rows, cols := stdscr.MaxYX()
	height, width := 10, 60
	y, x := (rows-height)/2, (cols-width)/2

	mainwin, _ := gc.NewWindow(height, width, y, x)
	defer mainwin.Delete()
	mainwin.Keypad(true)

	// Print a border around the main window and print a title
	mainwin.Box(0, 0)

	y, x = mainwin.MaxYX()
	title := "SRS ADLIN - Login"
	mainwin.ColorOn(2)
	mainwin.MovePrint(1, (x/2)-(len(title)/2), title)
	mainwin.ColorOff(2)
	mainwin.MoveAddChar(2, 0, gc.ACS_LTEE)
	mainwin.HLine(2, 1, gc.ACS_HLINE, x-2)
	mainwin.MoveAddChar(2, x-1, gc.ACS_RTEE)
	stdscr.Refresh()

	mainwin.MovePrint(4, 4, "  Please wait...")
	mainwin.ColorOn(3)
	mainwin.MovePrint(6, 2, "Connecting to login server...")
	mainwin.ColorOff(3)

	stdscr.Refresh()
	mainwin.Refresh()

	ticker := time.NewTicker(time.Millisecond * 150)

	rotPos := 0
loginloop:
	for {
		select {
		case ch := <- in:
			if gc.Char(ch) == gc.Char('r') {
				break loginloop
			}
		case st := <- validator:
			if st {
				canContinue = true
				break loginloop
			} else {
				e := <- validator_err

				mainwin.ColorOn(4)
				mainwin.MovePrint(4, 2, e.Error())
				mainwin.ColorOff(4)
				ticker.Stop()

				mainwin.MovePrint(6, 2, "    Press any key to retry   ")
				mainwin.Refresh()
				<- in

				break loginloop
			}
		case <- ticker.C:
			switch rotPos += 1; rotPos {
			case 0,4:
				mainwin.MovePrint(4, 4, "|")
			case 1,5:
				mainwin.MovePrint(4, 4, "/")
			case 2,6:
				mainwin.MovePrint(4, 4, "-")
			case 3,7:
				mainwin.MovePrint(4, 4, "\\")
			default:
				mainwin.MovePrint(4, 4, "|")
				rotPos = 0
			}
		}
		mainwin.Refresh()
	}
	ticker.Stop()

	return
}

func okreboot(stdscr *gc.Window, login string, ip string) {
	gc.Cursor(0)
	stdscr.Clear()

	// Create the window to be associated with the form
	rows, cols := stdscr.MaxYX()
	height, width := 14, 42
	y, x := (rows-height)/2, (cols-width)/2

	mainwin, _ := gc.NewWindow(height, width, y, x)
	defer mainwin.Delete()
	mainwin.Keypad(true)

	// Print a border around the main window and print a title
	mainwin.Box(0, 0)

	y, x = mainwin.MaxYX()
	title := "SRS ADLIN"
	mainwin.ColorOn(2)
	mainwin.MovePrint(1, (x/2)-(len(title)/2), title)
	mainwin.ColorOff(2)
	mainwin.MoveAddChar(2, 0, gc.ACS_LTEE)
	mainwin.HLine(2, 1, gc.ACS_HLINE, x-2)
	mainwin.MoveAddChar(2, x-1, gc.ACS_RTEE)
	stdscr.Refresh()

	mainwin.ColorOn(2)
	mainwin.MovePrint(4, 2, "You are now successfully logged in as: ")
	mainwin.ColorOff(2)
	mainwin.ColorOn(3)
	mainwin.MovePrint(5, (x/2)-(len(login)/2), login)
	mainwin.ColorOff(3)

	mainwin.MovePrint(8, 2, "Your computer will automatically")
	mainwin.MovePrint(9, 2, "reboot in a few seconds...")

	mainwin.MovePrint(11, 2, "|------------------------------------|")

	stdscr.Refresh()
	mainwin.Refresh()

	ticker := time.NewTicker(time.Millisecond * 98)

	pos := 0
rebootloop:
	for {
		select {
		case <- ticker.C:
			mainwin.MovePrint(11, 3 + pos, "*")
			pos += 1
			if pos > 36 {
				break rebootloop
			}
		}
		mainwin.Refresh()
	}
	ticker.Stop()
}
