package readline

import (
//	"fmt"
	"os"
	"regexp"
	"strconv"
)

// Lmorg code
// -------------------------------------------------------------------------------

func leftMost() []byte {
	fd := int(os.Stdout.Fd())
	w, _, err := GetSize(fd)
	if err != nil {
		return []byte{'\r', '\n'}
	}

	b := make([]byte, w+1)
	for i := 0; i < w; i++ {
		b[i] = ' '
	}
	b[w] = '\r'

	return b
}

var rxRcvCursorPos = regexp.MustCompile("^\x1b([0-9]+);([0-9]+)R$")

func (rl *Instance) getCursorPos() (x int, y int) {
	if !rl.EnableGetCursorPos {
		return -1, -1
	}

	disable := func() (int, int) {
		os.Stderr.WriteString("\r\ngetCursorPos() not supported by terminal emulator, disabling....\r\n")
		rl.EnableGetCursorPos = false
		return -1, -1
	}

	print(seqGetCursorPos)
	b := make([]byte, 64)
	i, err := os.Stdin.Read(b)
	if err != nil {
		return disable()
	}

	if !rxRcvCursorPos.Match(b[:i]) {
		return disable()
	}

	match := rxRcvCursorPos.FindAllStringSubmatch(string(b[:i]), 1)
	y, err = strconv.Atoi(match[0][1])
	if err != nil {
		return disable()
	}

	x, err = strconv.Atoi(match[0][2])
	if err != nil {
		return disable()
	}

	return x, y
}

// DISPLAY ------------------------------------------------------------
// All cursorMoveFunctions move the cursor as it is seen by the user.
// This means that they are not used to keep any reference point when
// when we internally move around clearning and printing things

/*
func moveCursorUpBuffered(i int) {
	if i < 1 {
		return
	}

	fmt.Fprintf(rl.bufferedOut, "\x1b[%dA", i)
}

func moveCursorDownBuffered(i int) {
	if i < 1 {
		return
	}

	fmt.Fprintf(rl.bufferedOut, "\x1b[%dB", i)
}

func moveCursorForwardsBuffered(i int) {
	if i < 1 {
		return
	}

	fmt.Fprintf(rl.bufferedOut, "\x1b[%dC", i)
}

func moveCursorUpBuffered(i int) {
	if i < 1 {
		return
	}

	fmt.Fprintf(rl.bufferedOut, "\x1b[%dD", i)
}
*/

func moveCursorUp(i int) {
	if i < 1 {
		return
	}

	printf("\x1b[%dA", i)
}

func moveCursorDown(i int) {
	if i < 1 {
		return
	}

	printf("\x1b[%dB", i)
}

func moveCursorForwards(i int) {
	if i < 1 {
		return
	}

	printf("\x1b[%dC", i)
}

func moveCursorBackwards(i int) {
	if i < 1 {
		return
	}

	printf("\x1b[%dD", i)
}

func hideCursor() {
	print(seqHideCursor)
}

func unhideCursor() {
	print(seqUnhideCursor)
}

func (rl *Instance) backspace(forward bool) {
	if len(rl.line) == 0 || rl.pos == 0 {
		return
	}

	rl.deleteBackspace(forward)
}

func (rl *Instance) moveCursorByAdjust(adjust int) {
	switch {
	case adjust > 0:
		rl.pos += adjust
	case adjust < 0:
		rl.pos += adjust
	}

	// The position can never be negative
	if rl.pos < 0 {
		rl.pos = 0
	}

	// The cursor can never be longer than the line
	if rl.pos > len(rl.line) {
		rl.pos = len(rl.line)
	}

	// If we are at the end of line, and not in Insert mode, move back one.
	if rl.modeViMode != VimInsert && (rl.pos == len(rl.line)) && len(rl.line) > 0 {
		if rl.modeViMode != VimInsert {
			rl.pos--
		} else if rl.modeViMode == VimInsert && rl.searchMode == HistoryFind && rl.modeAutoFind {
			rl.pos--
		}
	}
}