package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
	"time"
)

const (
	MAX_INT      = int(^uint(0) >> 1)
	MIN_INT      = -MAX_INT - 1
	CLEAR_SCREEN = "\033[H\033[2J"
	DEBUG        = true
	SLOW_IT_DOWN = true

	FLOW_NO = iota
	FLOW_D
	FLOW_LR
	FLOW_L
	FLOW_R
	FLOW_ERR
)

func main() {
	input := stdinToStringSlice()
	part1(input)
	//part2(input)
}

var scan [2000][2000]byte
var minX, maxX int = MAX_INT, MIN_INT
var minY, maxY int = MAX_INT, MIN_INT

func part1(input []string) {
	for _, v := range input {
		pts := strings.Split(v, ", ")
		fst := strings.Split(pts[0], "=")
		scd := strings.Split(pts[1], "=")
		scdRange := strings.Split(scd[1], "..")
		var x, y int
		if fst[0] == "x" {
			x = Atoi(fst[1])
			for y = Atoi(scdRange[0]); y <= Atoi(scdRange[1]); y++ {
				if y < 50 && x > 450 && x < 550 {
					minmax(x, y)
					scan[x][y] = '#'
				}
			}
		} else if fst[0] == "y" {
			y = Atoi(fst[1])
			for x := Atoi(scdRange[0]); x <= Atoi(scdRange[1]); x++ {
				if y < 50 && x > 450 && x < 550 {
					minmax(x, y)
					scan[x][y] = '#'
				}
			}
		}
	}
	// The water starts at 500, 0
	for {
		printScan()
		if SLOW_IT_DOWN {
			time.Sleep(time.Millisecond * 250)
		}
		if !fillSpot(500, 1) {
			break
		}
	}
	printScan()
}

func part2(input []string) {
}

func fillSpot(x, y int) bool {
	if y > maxY {
		return false
	} else if !canFill(x, y) {
		return false
	}

	if scan[x][y] == 0 {
		scan[x][y] = '|'
		return true
	}

	if canFill(x, y+1) {
		return fillSpot(x, y+1)
	} else if canFill(x-1, y) && canFill(x+1, y) {
		return fillLeft(x-1, y) || fillRight(x+1, y)
	} else if canFill(x-1, y) {
		return fillLeft(x-1, y)
	} else if canFill(x+1, y) {
		return fillRight(x+1, y)
	}

	scan[x][y] = '~'
	return true
}

func fillLeft(x, y int) bool {
	if !canFill(x, y) {
		return false
	}

	if scan[x][y] == 0 {
		scan[x][y] = '|'
		return true
	}

	if canFill(x, y+1) {
		return fillSpot(x, y+1)
	} else if canFill(x-1, y) {
		return fillLeft(x-1, y)
	}

	scan[x][y] = '~'
	return true
}

func fillRight(x, y int) bool {
	if !canFill(x, y) {
		return false
	}

	if scan[x][y] == 0 {
		scan[x][y] = '|'
		return true
	}

	if canFill(x, y+1) {
		return fillSpot(x, y+1)
	} else if canFill(x+1, y) {
		return fillRight(x+1, y)
	}

	scan[x][y] = '~'
	return true
}

func gud(x, y int) bool {
	return x != MIN_INT && y != MIN_INT
}

func printScan() {
	fmt.Print(CLEAR_SCREEN)
	for y := minY; y <= maxY; y++ {
		for x := minX; x <= maxX; x++ {
			if scan[x][y] == 0 {
				fmt.Print(".")
			} else {
				fmt.Print(string(scan[x][y]))
			}
		}
		fmt.Println()
	}
}
func canFill(x, y int) bool {
	return scan[x][y] == 0 || scan[x][y] == '|'
}

func minmax(x, y int) {
	if x < minX {
		minX = x
	}
	if x > maxX {
		maxX = x
	}
	if y < minY {
		minY = y
	}
	if y > maxY {
		maxY = y
	}
}

func stdinToStringSlice() []string {
	var input []string
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		input = append(input, scanner.Text())
	}
	return input
}

func Atoi(i string) int {
	var ret int
	var err error
	if ret, err = strconv.Atoi(i); err != nil {
		log.Fatal("Invalid Atoi: " + i)
	}
	return ret
}
