package main

import "log"
import "fmt"
import "time"
// import "runtime"
// import "runtime/debug"

import "git.wit.com/wit/gui"
import pb "git.wit.com/wit/witProtobuf"
// import "github.com/davecgh/go-spew/spew"

//
// This was the default handler for all mouse clicks (buttons, areas, etc))
//
// Most mouse clicks are now moved to custom functions
//

// stores the fields we want to map into our private structure 'values'
func makeGuiButtonValues(box *gui.GuiBox, a *pb.Account, vm *pb.Event_VM,
		name string, action string, custom func(*gui.GuiButton)) *myButtonInfo {
	val          := &myButtonInfo{}
	val.Account  = a
	val.Accounts = config.Accounts
	val.VM       = vm
	val.Custom   = custom
	val.Name     = "jcarr"
	val.Action   = action
	return val
}

func makeButton(box *gui.GuiBox, a *pb.Account, vm *pb.Event_VM,
		name string, action string, custom func(*gui.GuiButton)) *gui.GuiButton {
	val := makeGuiButtonValues(box, a, vm, name, action, custom)
	return gui.CreateButton(box, custom, name, val)
}

func mainMouseClick(b *gui.GuiButton) {
	defer r() // a golang trick to try to not crash on certain errors

	if (b == nil) {
		log.Println("mainMouseClick() BACK IN MAIN CONTROL PANEL CODE (button is nil) WHY DID THIS HAPPEN?")
		log.Println("THIS IS PROBABLY A BUG IN git.wit.com/gui")
		onExit(fmt.Errorf("mainMouseClick() got b = nil"))
	}
	log.Println("mainMouseClick() BACK IN CONTROL PANEL CODE")

	gw := b.Box.Window

	if (gw == nil) {
		log.Println("\tTHIS BUTTON IS BROKEN gw = nil")
		panic("something")
	}

	var values *myButtonInfo

	if tmp, ok := b.Values.(*myButtonInfo); ! ok {
		log.Println("\tmainMouseClick() values.Accounts error =", ok)
		log.Println("\tmainMouseClick() values.Accounts tmp   =", tmp)
	} else {
		values = tmp
	}
	log.Println("\tmainMouseClick() values.Accounts =", values.Accounts)
	log.Println("\tmainMouseClick() values.Name =    ", values.Name)

	if (values.Action == "QUIT") {
		onExit(nil)
	} else if (values.Action == "CREATE") {
		log.Println("\tTRY TO ADD A NEW VIRTUAL MACHINE")
		createVmClick(b)
	} else if (values.Action == "SHOW") {
		showAccountClick(b)
	}
	log.Println("mainMouseClick() BACK IN CONTROL PANEL CODE")
	log.Println("mainMouseClick() FAILED TO FIND values.Action =", values.Action)
	log.Println("mainMouseClick() END")
}

func showAccountClick(b *gui.GuiButton) {
	log.Println("\tTRIGGER DISPLAY ACCOUNT")
	State   = "SEND WEBSOCKET"

	var values *myButtonInfo

	if tmp, ok := b.Values.(*myButtonInfo); ! ok {
		log.Println("\tmainMouseClick() values.Accounts error =", ok)
		log.Println("\tmainMouseClick() values.Accounts tmp   =", tmp)
	} else {
		values = tmp
	}
	log.Println("\tmainMouseClick() values.Accounts =", values.Accounts)
	log.Println("\tmainMouseClick() values.Name =    ", values.Name)

	gw := b.Box.Window

	event := pb.MakeGetEvent()
	event.Account = values.Account
	websocketSendProtobuf(event)

	count := 0
	for {
		log.Println("\tSleep() in buttonClick() State =", State)
		time.Sleep(200 * time.Millisecond)
		if (State == "NEW PROTOBUF") {
			if (currentMessage == nil) {
				gui.ErrorWindow(gw,
					"There was a socket error",
					"More detailed information can be shown here.")
				State = "done"
			} else {
				count := countVMS(currentMessage)
				log.Println("\tSHOW VMS currentMessage =", currentMessage)
				log.Println("\tSHOW VMS count =", count)
				// TODO: make sure login worked & the account really has zero VMs
				// if (count != 0) {
					name := "Virtual Machines (" + values.Account.Nick + ")"
					mh := addVmsTab(gw, name, count, values.Account)
					ReadReceivedData(currentMessage, mh, b.Box)
				// }
				currentMessage = nil
				State = "done"
			}
			return
		}
		count += 1
		if (count > 10) {
			log.Println("\tERROR: waited too long for a resposne")
			currentMessage = nil
			State = "done"
			return
		}
	}
}

func createVmClick(b *gui.GuiButton) {
	log.Println("createVmClick()")

	var values *myButtonInfo

	if tmp, ok := b.Values.(*myButtonInfo); ! ok {
		log.Println("\tmainMouseClick() values.Accounts error =", ok)
		log.Println("\tmainMouseClick() values.Accounts tmp   =", tmp)
	} else {
		values = tmp
	}
	log.Println("\tmainMouseClick() values.Accounts =", values.Accounts)
	log.Println("\tmainMouseClick() values.Name =    ", values.Name)

	log.Println("\tTRIGGER CREATE VM")
	State   = "CREATE"
	event := pb.MakeAddVmEvent()
	for key, entry := range gui.Data.AllEntries {
		log.Println("\tdefaultEntryChange() Data.AllEntries =", key, entry)
		log.Println("\tdefaultEntryChange() Data.AllEntries[key].Name =", entry.Name)
		if (entry.Name == "Hostname") {
			event.Vms[0].Hostname = entry.UiEntry.Text()
		}
		if (entry.Name == "Memory") {
			event.Vms[0].Memory = pint64(entry.UiEntry.Text())
		}
		log.Println("\tdefaultEntryChange() Data.AllEntries[key].E =", entry.UiEntry.Text())
		log.Println("\tdefaultEntryChange() Data.AllEntries[key].B =", entry.B)
		if entry.B == b {
			log.Println("defaultEntryChange() FOUND. Entry assigned to Button", b)
		}
	}
	event.Account = values.Account
	log.Println("\tTRIGGERING CREATE event=", event)
	log.Println("\tTRIGGERING CREATE event.Account=", event.Account)
	websocketSendProtobuf(event)
}
