// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
// Use of this source code is governed by the GPL 3.0

// 2025 note by jcarr:
// this is one of the coolest things ever worked with.
// Personally, I've been working on making a gocui GO plugin
// so I can use it as a generalized console GUI toolkit.
//
// Well done everyone that has contributed to this gocui project !!!
// I am in your debt. Happy hacking & peace.

package main

import (
	"fmt"
	"time"

	"github.com/awesome-gocui/gocui"
	log "go.wit.com/log"
	"go.wit.com/widget"
)

// this function uses the mouse position to highlight & unhighlight things
// this is run every time the user moves the mouse over the terminal window
func mouseMove(g *gocui.Gui) {
	// this runs while the user moves the mouse. this highlights text
	// toggle off all highlight views except for whatever is under the mouse
	// START HIGHLIGHTING
	for _, view := range g.Views() {
		view.Highlight = false
	}
	w, h := g.MousePosition()
	// TODO: try to highlight entire grid rows
	if v, err := g.ViewByPosition(w, h); err == nil {
		// block anything from highlighting while a dialog box is open
		if me.dropdown.active || me.textbox.active {
			if me.dropdown.tk != nil && me.dropdown.tk.v == v {
				v.Highlight = true
			}
			if me.textbox.tk != nil && me.textbox.tk.v == v {
				v.Highlight = true
			}
		} else {
			v.Highlight = true
		}
	}

	// old hack. create the 'msg' view if it does not yet exist
	// TODO: put this somewhere more correct
	if widgetView, _ := g.View("msg"); widgetView == nil {
		if createStdout(g) {
			return
		}
		return
	}

	// END HIGHLIGHTING

	// Super Mouse Mode. very useful for debugging in the past. also, just fun
	if me.supermouse {
		w, h := g.MousePosition()
		for _, tk := range findByXY(w, h) {
			s := fmt.Sprintf("SM (%3d,%3d)", w, h)
			tk.dumpWidget(s)
		}
	}

	if me.mouse.mouseUp {
		return
	}
	// EVERYTHING BELOW THIS IS RELATED TO MOUSE DRAGGING

	// has the mouse been pressed down long enough to start dragging?
	if time.Since(me.mouse.down) < me.mouse.clicktime {
		// not dragging
		return
	}

	if me.dropdown.active || me.textbox.active {
		// can't drag
		return
	}

	// drag whatever was set to drag
	if me.mouse.currentDrag != nil {
		// me.mouse.currentDrag.dumpWidget(fmt.Sprintf("MM (%3d,%3d)", w, h))
		me.mouse.currentDrag.moveNew()
		return
	}
	log.Info(fmt.Sprintf("gocui gui toolkit plugin error. nothing to drag at (%d,%d)", w, h))
	return
}

func (tk *guiWidget) setAsDragging() {
	me.mouse.currentDrag = tk
	tk.lastW = tk.gocuiSize.w0
	tk.lastH = tk.gocuiSize.h0
}

// this is how the window gets dragged around
func (tk *guiWidget) moveNew() {
	w, h := me.baseGui.MousePosition()
	if tk.WidgetType() == widget.Window {
		tk.window.wasDragged = true

		// compute the new location based off how far the mouse has moved
		// since the mouse button was pressed down
		tk.gocuiSize.w0 = tk.lastW + w - me.mouse.downW
		tk.gocuiSize.h0 = tk.lastH + h - me.mouse.downH
		tk.makeWindowActive()
		return
	}
	/*
		if tk.WidgetType() == widget.Flag {
			me.baseGui.SetView(tk.cuiName, w-3, h-3, w+20, h+20, 0)
			// tk.verifyRect()
			s := fmt.Sprintf("move(%dx%d) %s ###", w, h, tk.cuiName)
			tk.dumpWidget(s)
			return
		}
	*/
	if tk.WidgetType() == widget.Stdout {
		if me.mouse.resize {
			newW := w - me.stdout.lastW
			newH := h - me.stdout.lastH
			me.stdout.w = newW
			me.stdout.h = newH
			// log.Info("Resize true", w, h, newW, newH)
			// me.stdout.lastW = w - me.stdout.mouseOffsetW
			// me.stdout.lastH = h - me.stdout.mouseOffsetH
			tk.relocateStdout(me.stdout.lastW, me.stdout.lastH)
		} else {
			// compute the new location based off how far the mouse has moved
			// since the mouse button was pressed down
			newW := tk.lastW + w - me.mouse.downW
			newH := tk.lastH + h - me.mouse.downH
			tk.relocateStdout(newW, newH)
			// log.Info("Resize false", w, h, newW, newH)
		}
		setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
	}
}