1// +build windows
2
3package winterm
4
5const (
6	horizontal = iota
7	vertical
8)
9
10func (h *windowsAnsiEventHandler) getCursorWindow(info *CONSOLE_SCREEN_BUFFER_INFO) SMALL_RECT {
11	if h.originMode {
12		sr := h.effectiveSr(info.Window)
13		return SMALL_RECT{
14			Top:    sr.top,
15			Bottom: sr.bottom,
16			Left:   0,
17			Right:  info.Size.X - 1,
18		}
19	} else {
20		return SMALL_RECT{
21			Top:    info.Window.Top,
22			Bottom: info.Window.Bottom,
23			Left:   0,
24			Right:  info.Size.X - 1,
25		}
26	}
27}
28
29// setCursorPosition sets the cursor to the specified position, bounded to the screen size
30func (h *windowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL_RECT) error {
31	position.X = ensureInRange(position.X, window.Left, window.Right)
32	position.Y = ensureInRange(position.Y, window.Top, window.Bottom)
33	err := SetConsoleCursorPosition(h.fd, position)
34	if err != nil {
35		return err
36	}
37	h.logf("Cursor position set: (%d, %d)", position.X, position.Y)
38	return err
39}
40
41func (h *windowsAnsiEventHandler) moveCursorVertical(param int) error {
42	return h.moveCursor(vertical, param)
43}
44
45func (h *windowsAnsiEventHandler) moveCursorHorizontal(param int) error {
46	return h.moveCursor(horizontal, param)
47}
48
49func (h *windowsAnsiEventHandler) moveCursor(moveMode int, param int) error {
50	info, err := GetConsoleScreenBufferInfo(h.fd)
51	if err != nil {
52		return err
53	}
54
55	position := info.CursorPosition
56	switch moveMode {
57	case horizontal:
58		position.X += int16(param)
59	case vertical:
60		position.Y += int16(param)
61	}
62
63	if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
64		return err
65	}
66
67	return nil
68}
69
70func (h *windowsAnsiEventHandler) moveCursorLine(param int) error {
71	info, err := GetConsoleScreenBufferInfo(h.fd)
72	if err != nil {
73		return err
74	}
75
76	position := info.CursorPosition
77	position.X = 0
78	position.Y += int16(param)
79
80	if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
81		return err
82	}
83
84	return nil
85}
86
87func (h *windowsAnsiEventHandler) moveCursorColumn(param int) error {
88	info, err := GetConsoleScreenBufferInfo(h.fd)
89	if err != nil {
90		return err
91	}
92
93	position := info.CursorPosition
94	position.X = int16(param) - 1
95
96	if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
97		return err
98	}
99
100	return nil
101}
102