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

package main

import (
	"fmt"

	"go.wit.com/log"
	"go.wit.com/widget"
)

/*
// this didn't work. panic()
func (tk *guiWidget) DeleteNode() {
	p := tk.parent
	for i, child := range p.children {
		log.Log(GOCUI, "parent has child:", i, child.node.WidgetId, child.node.GetProgName())
		if tk == child {
			log.Log(GOCUI, "Found child ==", i, child.node.WidgetId, child.node.GetProgName())
			log.Log(GOCUI, "Found n ==", i, tk.node.WidgetId, tk.node.GetProgName())
			p.children = append(p.children[:i], p.children[i+1:]...)
		}
	}
		for i, child := range p.children {
			log.Log(TREE, "parent now has child:", i, child.WidgetId, child.GetProgName())
		}
}
*/

func (tk *guiWidget) doWindowClick() {
	w, h := me.baseGui.MousePosition()
	tk.dumpWidget(fmt.Sprintf("doWindowClick(%d,%d)", w, h))

	// compare the mouse location to the 'X' indicator to close the window
	if tk.gocuiSize.inRect(w, h) {
		offset := w - tk.gocuiSize.w1
		if (offset < 2) && (offset > -2) {
			// close enough // close the window here
			tk.dumpWidget(fmt.Sprintf("Close Window(%d,%d) (off=%d)", w, h, offset))
			tk.hideWindow()
			n := tk.node
			tk.deleteNode()
			me.myTree.SendWindowCloseEvent(n)
			/*
				n.DeleteNode()

				tk.DeleteNode()
			*/
			return
		}
		if tk.window.collapsed {
			tk.dumpWidget(fmt.Sprintf("collapse = false"))
			tk.window.collapsed = false
		} else {
			tk.dumpWidget(fmt.Sprintf("collapse = true"))
			tk.window.collapsed = true
		}
	} else {
		tk.window.collapsed = false
	}
	// if there is a current window, hide it
	if me.currentWindow != nil {
		me.currentWindow.setColor(&colorWindow)
	}

	// now set this window as the current window
	me.currentWindow = tk

	tk.redrawWindow(w, h)
	setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
}

// this whole things was impossible to make but it got me where I am now
// the debugging is way way better now with it being visible in the Stdout window
// so now it's possible to redo all this and make it better
func (tk *guiWidget) doWidgetClick(w int, h int) {
	tk.dumpWidget(fmt.Sprintf("doWidgetClick(%d,%d)", w, h))
	switch tk.node.WidgetType {
	case widget.Window:
		tk.doWindowClick()
		return
	case widget.Checkbox:
		if tk.node.State.Checked {
			log.Log(WARN, "checkbox is being set to false")
			tk.node.State.Checked = false
			tk.setCheckbox()
		} else {
			log.Log(WARN, "checkbox is being set to true")
			tk.node.State.Checked = true
			tk.setCheckbox()
		}
		me.myTree.SendUserEvent(tk.node)
	case widget.Button:
		me.myTree.SendFromUser(tk.node)
	case widget.Combobox:
		tk.showDropdown()
	case widget.Dropdown:
		tk.showDropdown()
	case widget.Textbox:
		tk.showTextbox()
	case widget.Flag:
		tk.dropdownClicked(w, h)
	case widget.Stdout:
		tk.dumpWidget("stdout click()")
	default:
		tk.dumpWidget("undef click()")
	}
}

// handles a mouse click
func doMouseClick(w int, h int) {
	// Flag widgets (dropdown menus, etc) are the highest priority. ALWAYS SEND MOUSE CLICKS THERE FIRST
	// handle an open dropdown menu or text entry window first
	if me.dropdown.active || me.textbox.active {
		// can't drag or do anything when dropdown or textbox are visible
		for _, tk := range findByXY(w, h) {
			if tk.node.WidgetId == me.dropdown.wId {
				log.Info("got dropdwon click", w, h, tk.cuiName)
				tk.dropdownClicked(w, h)
				return
			}
			if tk.node.WidgetId == me.textbox.wId {
				log.Info("got textbox click", w, h, tk.cuiName)
				textboxClosed()
				return
			}
		}
		log.Info("a dropdown or textbox is active. you can't click anywhere else (otherwise hit ESC)", w, h)
		return
	}

	win := findWindowUnderMouse()
	if win != nil {
		// look in this window for widgets
		// widgets have priority. send the click here first
		for _, tk := range win.findByXYreal(w, h) {
			switch tk.node.WidgetType {
			case widget.Checkbox:
				if tk.node.State.Checked {
					log.Log(WARN, "checkbox is being set to false")
					tk.node.State.Checked = false
					tk.setCheckbox()
				} else {
					log.Log(WARN, "checkbox is being set to true")
					tk.node.State.Checked = true
					tk.setCheckbox()
				}
				me.myTree.SendUserEvent(tk.node)
				return
			case widget.Button:
				tk.dumpWidget("click()") // enable this to debug widget clicks
				me.myTree.SendFromUser(tk.node)
				return
			case widget.Combobox:
				tk.showDropdown()
				return
			case widget.Dropdown:
				tk.showDropdown()
				return
			case widget.Textbox:
				tk.showTextbox()
				return
			default:
				// TODO: enable the GUI debugger in gocui
				// tk.dumpWidget("undef click()") // enable this to debug widget clicks
			}
		}
		log.Info("you clicked on a window, but not any widgets", win.cuiName)
		win.redrawWindow(win.gocuiSize.w0, win.gocuiSize.h0)
		me.stdout.outputOnTop = false
		setThingsOnTop()
		return
	}

	var found bool

	for _, tk := range findByXY(w, h) {
		// will show you everything found on a mouse click. great for debugging!
		// tk.dumpWidget("click()")
		if tk.node.WidgetType == widget.Stdout {
			// don't send clicks to the stdout debugging window
			// continue
		}
		found = true
		// tk.doWidgetClick(w, h)
		return
	}
	if found {
		return
	}

	log.Log(GOCUI, "click() nothing was at:", w, h)
	return
}

func doMouseDoubleClick(w int, h int) {
	me.mouse.double = false
	// log.Printf("actually a double click (%d,%d)", w, h)

	if me.dropdown.active || me.textbox.active {
		// can't drag or do anything when dropdown or textbox are visible
		log.Info("can't double click. dropdown or textbox is active")
		return
	}

	for _, tk := range findByXY(w, h) {
		if tk.node.WidgetType == widget.Window {
			tk.redrawWindow(tk.gocuiSize.w0, tk.gocuiSize.h0)
			me.stdout.outputOnTop = false
			setThingsOnTop()
			return
		}

		if tk.node.WidgetType == widget.Stdout {
			if me.stdout.outputOnTop {
				me.stdout.outputOnTop = false
				setThingsOnTop()
			} else {
				me.stdout.outputOnTop = true
				setThingsOnTop()
			}
			return
		}
	}
}