package main

import (
	"fmt"
	"github.com/awesome-gocui/gocui"
	"go.wit.com/lib/widget"
	"go.wit.com/log"
)

// set isCurrent = false everywhere
func unsetCurrent(n *node) {
	w := n.tk
	w.isCurrent = false

	if n.WidgetType == widget.Tab {
		// n.tk.color = &colorTab
		// n.setColor()
	}

	for _, child := range n.children {
		unsetCurrent(child)
	}
}

// when adding a new widget, this will update the display
// of the current widgets if that widget is supposed
// to be in current display
func (n *node) updateCurrent() {
	log.Log(NOW, "updateCurrent()", n.progname)
	if n.WidgetType == widget.Tab {
		if n.IsCurrent() {
			// n.tk.color = &colorActiveT
			n.setColor(&colorActiveT)
			n.hideView()
			n.showView()
			setCurrentTab(n)
		} else {
			// n.tk.color = &colorTab
			// n.setColor()
		}
		return
	}
	if n.WidgetType == widget.Window {
		if n.IsCurrent() {
			// setCurrentWindow(n)
		}
		return
	}
	if n.WidgetType == widget.Root {
		return
	}
	n.parent.updateCurrent()
}

// shows the widgets in a window
func setCurrentWindow(n *node) {
	if n.IsCurrent() {
		return
	}
	w := n.tk
	if n.WidgetType != widget.Window {
		return
	}
	unsetCurrent(me.rootNode)

	if n.hasTabs {
		// set isCurrent = true on the first tab
		for _, child := range n.children {
			child.tk.isCurrent = true
			break
		}
	} else {
		w.isCurrent = true
	}
}

// shows the widgets in a tab
func setCurrentTab(n *node) {
	w := n.tk
	if n.WidgetType != widget.Tab {
		return
	}
	unsetCurrent(me.rootNode)
	w.isCurrent = true
	p := n.parent.tk
	p.isCurrent = true
	log.Log(NOW, "setCurrent()", n.progname)
}

func (n *node) doWidgetClick() {
	switch n.WidgetType {
	case widget.Root:
		// THIS IS THE BEGINING OF THE LAYOUT
		log.Log(NOW, "doWidgetClick()", n.progname)
		redoWindows(0, 0)
	case widget.Flag:
		log.Log(NOW, "doWidgetClick() FLAG widget name =", n.progname)
		log.Log(NOW, "doWidgetClick() if this is the dropdown menu, handle it here?")
	case widget.Window:
		if me.currentWindow == n {
			return
		}
		if me.currentWindow != nil {
			unsetCurrent(me.currentWindow)
			me.currentWindow.setColor(&colorWindow)
			me.currentWindow.hideWidgets()
		}
		n.hideWidgets()
		me.currentWindow = n
		// setCurrentWindow(n) // probably delete this
		n.setColor(&colorActiveW)
		n.redoTabs(me.TabW, me.TabH)
		for _, child := range n.children {
			if child.currentTab == true {
				log.Log(NOW, "FOUND CURRENT TAB", child.progname)
				setCurrentTab(child)
				child.placeWidgets(me.RawW, me.RawH)
				child.showWidgets()
				return
			}
		}
		/* FIXME: redo this
		if ! n.hasTabs {
		}
		*/
	case widget.Tab:
		if n.IsCurrent() {
			return // do nothing if you reclick on the already selected tab
		}
		// find the window and disable the active tab
		p := n.parent
		if p != nil {
			p.hideWidgets()
			p.redoTabs(me.TabW, me.TabH)
			unsetCurrent(p)
			for _, child := range p.children {
				if child.WidgetType == widget.Tab {
					child.setColor(&colorTab)
					n.currentTab = false
				}
			}
		}
		n.currentTab = true
		n.setColor(&colorActiveT)
		setCurrentTab(n)
		n.placeWidgets(me.RawW, me.RawH)
		n.showWidgets()
	case widget.Group:
		// n.placeWidgets(p.tk.startH, newH)
		n.toggleTree()
	case widget.Checkbox:
		if widget.GetBool(n.value) {
			n.setCheckbox(false)
		} else {
			n.setCheckbox(true)
		}
		n.doUserEvent()
	case widget.Grid:
		newR := n.realGocuiSize()

		// w,h := n.logicalSize()
		// w := newR.w1 - newR.w0
		// h := newR.h1 - newR.h0

		n.placeGrid(newR.w0, newR.h0)
		n.showWidgets()
	case widget.Box:
		// w.showWidgetPlacement(logNow, "drawTree()")
		if n.direction == widget.Horizontal {
			log.Log(NOW, "BOX IS HORIZONTAL", n.progname)
		} else {
			log.Log(NOW, "BOX IS VERTICAL", n.progname)
		}
		// n.placeWidgets()
		n.toggleTree()
	case widget.Button:
		n.doUserEvent()
	case widget.Dropdown:
		log.Log(NOW, "do the dropdown here")
		if me.ddview == nil {
			me.ddview = addDropdown()
			tk := me.ddview.tk
			tk.gocuiSize.w0 = 20
			tk.gocuiSize.w1 = 40
			tk.gocuiSize.h0 = 10
			tk.gocuiSize.h1 = 25
			tk.v, _ = me.baseGui.SetView("ddview",
				tk.gocuiSize.w0,
				tk.gocuiSize.h0,
				tk.gocuiSize.w1,
				tk.gocuiSize.h1, 0)
			if tk.v == nil {
				return
			}
			tk.v.Wrap = true
			tk.v.Frame = true
			tk.v.Clear()
			fmt.Fprint(tk.v, "example.com\nwit.com")
			me.ddview.SetVisible(true)
			return
		}
		log.Log(NOW, "doWidgetClick() visible =", me.ddview.Visible())
		if me.ddview.Visible() {
			me.ddview.SetVisible(false)
			me.baseGui.DeleteView("ddview")
			me.ddview.tk.v = nil
		} else {
			var dnsList string
			for i, s := range n.vals {
				log.Log(NOW, "AddText()", n.progname, i, s)
				dnsList += s + "\n"
			}
			me.ddNode = n
			log.Log(NOW, "new dns list should be set to:", dnsList)
			me.ddview.label = dnsList
			me.ddview.SetText(dnsList)
			me.ddview.SetVisible(true)
		}
		for i, s := range n.vals {
			log.Log(NOW, "AddText()", n.progname, i, s)
		}
	default:
	}
}

var toggle bool = true

func (n *node) toggleTree() {
	if toggle {
		n.drawTree(toggle)
		toggle = false
	} else {
		n.hideWidgets()
		toggle = true
	}
}

// display the widgets in the binary tree
func (n *node) drawTree(draw bool) {
	w := n.tk
	if w == nil {
		return
	}
	n.showWidgetPlacement(true, "drawTree()")
	if draw {
		// w.textResize()
		n.showView()
	} else {
		n.deleteView()
	}

	for _, child := range n.children {
		child.drawTree(draw)
	}
}

func click(g *gocui.Gui, v *gocui.View) error {
	// var l string
	// var err error

	log.Log(INFO, "click() START", v.Name())
	// n := me.rootNode.findWidgetName(v.Name())
	n := findUnderMouse()
	if n != nil {
		log.Log(NOW, "click() Found widget =", n.WidgetId, n.progname, ",", n.label)
		if n.progname == "DropBox" {
			log.Log(NOW, "click() this is the dropdown menu. set a flag here what did I click? where is the mouse?")
			log.Log(NOW, "click() set a global dropdown clicked flag=true here")
			me.ddClicked = true
		}
		n.doWidgetClick()
	} else {
		log.Log(NOW, "click() could not find node name =", v.Name())
	}

	if _, err := g.SetCurrentView(v.Name()); err != nil {
		log.Log(NOW, "click() END err =", err)
		return err
	}

	log.Log(NOW, "click() END")
	return nil
}

func findUnderMouse() *node {
	var found *node
	var widgets []*node
	var f func(n *node)
	w, h := me.baseGui.MousePosition()

	// find buttons that are below where the mouse button click
	f = func(n *node) {
		widget := n.tk
		// ignore widgets that are not visible
		if n.Visible() {
			if (widget.gocuiSize.w0 <= w) && (w <= widget.gocuiSize.w1) &&
				(widget.gocuiSize.h0 <= h) && (h <= widget.gocuiSize.h1) {
				widgets = append(widgets, n)
				found = n
			}
		}
		if n == me.ddview {
			log.Log(NOW, "findUnderMouse() found ddview")
			if n.Visible() {
				log.Log(NOW, "findUnderMouse() and ddview is visable. hide it here. TODO: find highlighted row")
				found = n
				// find the actual value here and set the dropdown widget
				me.baseGui.DeleteView("ddview")
			} else {
				log.Log(NOW, "findUnderMouse() I was lying, actually it's not found")
			}
		}

		for _, child := range n.children {
			f(child)
		}
	}
	f(me.rootNode)
	// widgets has everything that matches
	// TODO: pop up menu with a list of them
	for _, n := range widgets {
		//log(logNow, "ctrlDown() FOUND widget", widget.id, widget.name)
		n.showWidgetPlacement(true, "findUnderMouse() FOUND")
	}
	return found
}

// find the widget under the mouse click
func ctrlDown(g *gocui.Gui, v *gocui.View) error {
	var found *node
	// var widgets []*node
	// var f func (n *node)
	found = findUnderMouse()
	if me.ctrlDown == nil {
		setupCtrlDownWidget()
		me.ctrlDown.label = found.progname
		me.ctrlDown.tk.cuiName = "ctrlDown"
		// me.ctrlDown.parent = me.rootNode
	}
	cd := me.ctrlDown.tk
	if found == nil {
		found = me.rootNode
	}
	me.ctrlDown.label = found.progname
	newR := found.realGocuiSize()
	cd.gocuiSize.w0 = newR.w0
	cd.gocuiSize.h0 = newR.h0
	cd.gocuiSize.w1 = newR.w1
	cd.gocuiSize.h1 = newR.h1
	if me.ctrlDown.Visible() {
		me.ctrlDown.hideView()
	} else {
		me.ctrlDown.showView()
	}
	me.ctrlDown.showWidgetPlacement(true, "ctrlDown:")
	return nil
}
