func getNumberOfChars(fromCoord COORD, toCoord COORD, screenSize COORD) uint32 {
	if fromCoord.X < 0 || fromCoord.Y < 0 || toCoord.X < 0 || toCoord.Y < 0 {
		return 0
	}
	if fromCoord.X >= screenSize.X || fromCoord.Y >= screenSize.Y || toCoord.X >= screenSize.X || toCoord.Y >= screenSize.Y {
		return 0
	}
	if fromCoord.Y > toCoord.Y {
		return 0
	}
	if fromCoord.Y == toCoord.Y {
		return uint32(toCoord.X-fromCoord.X) + 1
	}
	if fromCoord.Y < toCoord.Y {
		retValue := uint32(screenSize.X-fromCoord.X) + uint32(toCoord.X) + 1
		linesBetween := toCoord.Y - fromCoord.Y - 1
		if linesBetween > 0 {
			retValue = retValue + uint32(linesBetween*screenSize.X)
		}
		return retValue
	}
	return 0
}
Gets the number of space characters to write for "clearing" the section of terminal
package winconsole
import (
	"bytes"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
	"sync"
	"syscall"
	"unsafe"
	"github.com/Sirupsen/logrus"
)
const (
	ENABLE_PROCESSED_INPUT = 0x0001
	ENABLE_LINE_INPUT      = 0x0002
	ENABLE_ECHO_INPUT      = 0x0004
	ENABLE_WINDOW_INPUT    = 0x0008
	ENABLE_MOUSE_INPUT     = 0x0010
	ENABLE_INSERT_MODE     = 0x0020
	ENABLE_QUICK_EDIT_MODE = 0x0040
	ENABLE_EXTENDED_FLAGS  = 0x0080
	ENABLE_PROCESSED_OUTPUT   = 0x0001
	ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002
	FOREGROUND_BLUE       = 1
	FOREGROUND_GREEN      = 2
	FOREGROUND_RED        = 4
	FOREGROUND_INTENSITY  = 8
	FOREGROUND_MASK_SET   = 0x000F
	FOREGROUND_MASK_UNSET = 0xFFF0
	BACKGROUND_BLUE       = 16
	BACKGROUND_GREEN      = 32
	BACKGROUND_RED        = 64
	BACKGROUND_INTENSITY  = 128
	BACKGROUND_MASK_SET   = 0x00F0
	BACKGROUND_MASK_UNSET = 0xFF0F
	COMMON_LVB_REVERSE_VIDEO = 0x4000
	COMMON_LVB_UNDERSCORE    = 0x8000
	ANSI_ATTR_RESET     = 0
	ANSI_ATTR_BOLD      = 1
	ANSI_ATTR_DIM       = 2
	ANSI_ATTR_UNDERLINE = 4
	ANSI_ATTR_BLINK     = 5
	ANSI_ATTR_REVERSE   = 7
	ANSI_ATTR_INVISIBLE = 8
	ANSI_ATTR_UNDERLINE_OFF = 24
	ANSI_ATTR_BLINK_OFF     = 25
	ANSI_ATTR_REVERSE_OFF   = 27
	ANSI_ATTR_INVISIBLE_OFF = 8
	ANSI_FOREGROUND_BLACK   = 30
	ANSI_FOREGROUND_RED     = 31
	ANSI_FOREGROUND_GREEN   = 32
	ANSI_FOREGROUND_YELLOW  = 33
	ANSI_FOREGROUND_BLUE    = 34
	ANSI_FOREGROUND_MAGENTA = 35
	ANSI_FOREGROUND_CYAN    = 36
	ANSI_FOREGROUND_WHITE   = 37
	ANSI_FOREGROUND_DEFAULT = 39
	ANSI_BACKGROUND_BLACK   = 40
	ANSI_BACKGROUND_RED     = 41
	ANSI_BACKGROUND_GREEN   = 42
	ANSI_BACKGROUND_YELLOW  = 43
	ANSI_BACKGROUND_BLUE    = 44
	ANSI_BACKGROUND_MAGENTA = 45
	ANSI_BACKGROUND_CYAN    = 46
	ANSI_BACKGROUND_WHITE   = 47
	ANSI_BACKGROUND_DEFAULT = 49
	ANSI_MAX_CMD_LENGTH = 256
	MAX_INPUT_EVENTS = 128
	MAX_INPUT_BUFFER = 1024
	DEFAULT_WIDTH    = 80
	DEFAULT_HEIGHT   = 24
)
const (
	VK_PRIOR    = 0x21  
	VK_NEXT     = 0x22  
	VK_END      = 0x23  
	VK_HOME     = 0x24  
	VK_LEFT     = 0x25  
	VK_UP       = 0x26  
	VK_RIGHT    = 0x27  
	VK_DOWN     = 0x28  
	VK_SELECT   = 0x29  
	VK_PRINT    = 0x2A  
	VK_EXECUTE  = 0x2B  
	VK_SNAPSHOT = 0x2C  
	VK_INSERT   = 0x2D  
	VK_DELETE   = 0x2E  
	VK_HELP     = 0x2F  
	VK_F1       = 0x70  
	VK_F2       = 0x71  
	VK_F3       = 0x72  
	VK_F4       = 0x73  
	VK_F5       = 0x74  
	VK_F6       = 0x75  
	VK_F7       = 0x76  
	VK_F8       = 0x77  
	VK_F9       = 0x78  
	VK_F10      = 0x79  
	VK_F11      = 0x7A  
	VK_F12      = 0x7B  
)
var kernel32DLL = syscall.NewLazyDLL("kernel32.dll")
var (
	setConsoleModeProc                = kernel32DLL.NewProc("SetConsoleMode")
	getConsoleScreenBufferInfoProc    = kernel32DLL.NewProc("GetConsoleScreenBufferInfo")
	setConsoleCursorPositionProc      = kernel32DLL.NewProc("SetConsoleCursorPosition")
	setConsoleTextAttributeProc       = kernel32DLL.NewProc("SetConsoleTextAttribute")
	fillConsoleOutputCharacterProc    = kernel32DLL.NewProc("FillConsoleOutputCharacterW")
	writeConsoleOutputProc            = kernel32DLL.NewProc("WriteConsoleOutputW")
	readConsoleInputProc              = kernel32DLL.NewProc("ReadConsoleInputW")
	getNumberOfConsoleInputEventsProc = kernel32DLL.NewProc("GetNumberOfConsoleInputEvents")
	getConsoleCursorInfoProc          = kernel32DLL.NewProc("GetConsoleCursorInfo")
	setConsoleCursorInfoProc          = kernel32DLL.NewProc("SetConsoleCursorInfo")
	setConsoleWindowInfoProc          = kernel32DLL.NewProc("SetConsoleWindowInfo")
	setConsoleScreenBufferSizeProc    = kernel32DLL.NewProc("SetConsoleScreenBufferSize")
)
type (
	SHORT int16
	BOOL  int32
	WORD  uint16
	WCHAR uint16
	DWORD uint32
	SMALL_RECT struct {
		Left   SHORT
		Top    SHORT
		Right  SHORT
		Bottom SHORT
	}
	COORD struct {
		X SHORT
		Y SHORT
	}
	CONSOLE_SCREEN_BUFFER_INFO struct {
		Size              COORD
		CursorPosition    COORD
		Attributes        WORD
		Window            SMALL_RECT
		MaximumWindowSize COORD
	}
	CONSOLE_CURSOR_INFO struct {
		Size    DWORD
		Visible BOOL
	}
	KEY_EVENT_RECORD struct {
		KeyDown         BOOL
		RepeatCount     WORD
		VirtualKeyCode  WORD
		VirtualScanCode WORD
		UnicodeChar     WCHAR
		ControlKeyState DWORD
	}
	INPUT_RECORD struct {
		EventType WORD
		KeyEvent  KEY_EVENT_RECORD
	}
	CHAR_INFO struct {
		UnicodeChar WCHAR
		Attributes  WORD
	}
)
type WindowsTerminal struct {
	outMutex            sync.Mutex
	inMutex             sync.Mutex
	inputBuffer         []byte
	inputSize           int
	inputEvents         []INPUT_RECORD
	screenBufferInfo    *CONSOLE_SCREEN_BUFFER_INFO
	inputEscapeSequence []byte
}
func getStdHandle(stdhandle int) uintptr {
	handle, err := syscall.GetStdHandle(stdhandle)
	if err != nil {
		panic(fmt.Errorf("could not get standard io handle %d", stdhandle))
	}
	return uintptr(handle)
}
func WinConsoleStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
	handler := &WindowsTerminal{
		inputBuffer:         make([]byte, MAX_INPUT_BUFFER),
		inputEscapeSequence: []byte(KEY_ESC_CSI),
		inputEvents:         make([]INPUT_RECORD, MAX_INPUT_EVENTS),
	}
	if IsConsole(os.Stdin.Fd()) {
		stdIn = &terminalReader{
			wrappedReader: os.Stdin,
			emulator:      handler,
			command:       make([]byte, 0, ANSI_MAX_CMD_LENGTH),
			fd:            getStdHandle(syscall.STD_INPUT_HANDLE),
		}
	} else {
		stdIn = os.Stdin
	}
	if IsConsole(os.Stdout.Fd()) {
		stdoutHandle := getStdHandle(syscall.STD_OUTPUT_HANDLE)
		screenBufferInfo, err := GetConsoleScreenBufferInfo(stdoutHandle)
		if err != nil {
			panic("could not get console screen buffer info")
		}
		handler.screenBufferInfo = screenBufferInfo
		buffer = make([]CHAR_INFO, screenBufferInfo.MaximumWindowSize.X*screenBufferInfo.MaximumWindowSize.Y)
		stdOut = &terminalWriter{
			wrappedWriter: os.Stdout,
			emulator:      handler,
			command:       make([]byte, 0, ANSI_MAX_CMD_LENGTH),
			fd:            stdoutHandle,
		}
	} else {
		stdOut = os.Stdout
	}
	if IsConsole(os.Stderr.Fd()) {
		stdErr = &terminalWriter{
			wrappedWriter: os.Stderr,
			emulator:      handler,
			command:       make([]byte, 0, ANSI_MAX_CMD_LENGTH),
			fd:            getStdHandle(syscall.STD_ERROR_HANDLE),
		}
	} else {
		stdErr = os.Stderr
	}
	return stdIn, stdOut, stdErr
}
func GetHandleInfo(in interface{}) (uintptr, bool) {
	var inFd uintptr
	var isTerminalIn bool
	switch t := in.(type) {
	case *terminalReader:
		in = t.wrappedReader
	case *terminalWriter:
		in = t.wrappedWriter
	}
	if file, ok := in.(*os.File); ok {
		inFd = file.Fd()
		isTerminalIn = IsConsole(inFd)
	}
	return inFd, isTerminalIn
}
func getError(r1, r2 uintptr, lastErr error) error {
	if r1 == 0 {
		if lastErr != nil {
			return lastErr
		}
		return syscall.EINVAL
	}
	return nil
}
func GetConsoleMode(handle uintptr) (uint32, error) {
	var mode uint32
	err := syscall.GetConsoleMode(syscall.Handle(handle), &mode)
	return mode, err
}
func SetConsoleMode(handle uintptr, mode uint32) error {
	return getError(setConsoleModeProc.Call(handle, uintptr(mode), 0))
}
func SetCursorVisible(handle uintptr, isVisible BOOL) (bool, error) {
	var cursorInfo *CONSOLE_CURSOR_INFO = &CONSOLE_CURSOR_INFO{}
	if err := getError(getConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0)); err != nil {
		return false, err
	}
	cursorInfo.Visible = isVisible
	if err := getError(setConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0)); err != nil {
		return false, err
	}
	return true, nil
}
func SetWindowSize(handle uintptr, width, height, max SHORT) (bool, error) {
	window := SMALL_RECT{Left: 0, Top: 0, Right: width - 1, Bottom: height - 1}
	coord := COORD{X: width - 1, Y: max}
	if err := getError(setConsoleWindowInfoProc.Call(handle, uintptr(1), uintptr(unsafe.Pointer(&window)))); err != nil {
		return false, err
	}
	if err := getError(setConsoleScreenBufferSizeProc.Call(handle, marshal(coord))); err != nil {
		return false, err
	}
	return true, nil
}
func GetConsoleScreenBufferInfo(handle uintptr) (*CONSOLE_SCREEN_BUFFER_INFO, error) {
	var info CONSOLE_SCREEN_BUFFER_INFO
	if err := getError(getConsoleScreenBufferInfoProc.Call(handle, uintptr(unsafe.Pointer(&info)), 0)); err != nil {
		return nil, err
	}
	return &info, nil
}
func setConsoleTextAttribute(handle uintptr, attribute WORD) error {
	return getError(setConsoleTextAttributeProc.Call(handle, uintptr(attribute), 0))
}
func writeConsoleOutput(handle uintptr, buffer []CHAR_INFO, bufferSize COORD, bufferCoord COORD, writeRegion *SMALL_RECT) (bool, error) {
	if err := getError(writeConsoleOutputProc.Call(handle, uintptr(unsafe.Pointer(&buffer[0])), marshal(bufferSize), marshal(bufferCoord), uintptr(unsafe.Pointer(writeRegion)))); err != nil {
		return false, err
	}
	return true, nil
}
func fillConsoleOutputCharacter(handle uintptr, fillChar byte, length uint32, writeCord COORD) (bool, error) {
	out := int64(0)
	if err := getError(fillConsoleOutputCharacterProc.Call(handle, uintptr(fillChar), uintptr(length), marshal(writeCord), uintptr(unsafe.Pointer(&out)))); err != nil {
		return false, err
	}
	return true, nil
}