package main

import (
	"fmt"
	"time"

	intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor"
)

func part2(prog []int) {
	p := intcode.NewProgram(prog)
	p.SetProgramValueAt(0, 2)

	var input []string
	// Main Sequence
	input = append(input, "A,B,A,C,A,C,B,C,C,B"+string(byte(10)))
	// A
	input = append(input, "L,4,L,4,L,10,R,4"+string(byte(10)))
	// B
	input = append(input, "R,4,L,4,L,4,R,8,R,10"+string(byte(10)))
	// C
	input = append(input, "R,4,L,10,R,10"+string(byte(10)))

	go func() {
		printAllOutput(p)
		for k := range input {
			writeString(p, input[k])
			printAllOutput(p)
		}
		for !p.NeedsInput() {
			time.Sleep(1)
		}
		p.Input(int('n'))
		for !p.NeedsInput() {
			time.Sleep(1)
		}
		p.Input(10)

		printAllOutput(p)
	}()

	fmt.Println("Running")
	p.Run()
	fmt.Println("Done")
}

func readString(p *intcode.Program) string {
	var ret string
	for {
		if !p.NeedsOutput() {
			time.Sleep(1)
		}
		out := p.Output()
		if byte(out) == '\n' {
			return ret
		}
		ret = ret + string(out)
	}
}

func writeString(p *intcode.Program, str string) {
	fmt.Println("Printing", str)
	for k := range str {
		if p.NeedsInput() {
			fmt.Print(string(str[k]))
			p.Input(int(str[k]))
			printAllOutput(p)
		}
		if p.NeedsOutput() {
			return
		}
		time.Sleep(1)
	}
}

func printAllOutput(p *intcode.Program) {
	for {
		if p.NeedsInput() {
			return
		}
		if p.NeedsOutput() {
			out := p.Output()
			switch out {
			case '#', '.', DIR_N, DIR_E, DIR_S, DIR_W:
				fmt.Print(string(out))
			default:
				fmt.Println(out)
			}
		}
		time.Sleep(1)
	}
}
