Scriptname SHESON_DynDOLOD_Master extends ObjectReference
;this probably should be a quest but I like being at the center of the map doing things
;this looks spaghetti but it is about performance

ObjectReference CurrentRef = None
ObjectReference MyCurrentFirstborn = None
ObjectReference MyOldFirstborn = None
String MyWorld = "None"
String MyImportFileName = "None"
String MyModName = "DynDOLOD.esp"
String MyCurrentFirstbornList = "None"
String MyCurrentMinionList = "None"
String MyOldFirstbornList = "None"
String MyOldMinionList = "None"
Int MyCurrent = 0
Int Index = 0
Int MaxCurrent = 0
Int MaxOld = 0
Int ThrottleCount = 0
Int ThrottleThreshold = 100
Bool MyCurrentAttach

Function IBowToThee(ObjectReference MyFirstborn, String FirstbornList, String MinionList, Bool MyAttach)
	GotoState("Updating")
	Utility.Wait(3)
	MyWorld = StringUtil.Substring(self.GetWorldspace() as string, 13, StringUtil.Find(self.GetWorldspace() as string, "(") - 14)
	MyImportFileName = "DynDOLOD_" + JsonUtil.GetStringValue("DynDOLOD_Worlds", MyWorld, MyWorld)
	if !JsonUtil.Load(MyImportFileName)
		Debug.Notification(MyImportFileName + " file not found")
		GotoState("EmptyState")
		Utility.Wait(3)
	else
		MaxCurrent = JsonUtil.IntListCount(MyImportFileName, FirstbornList)
		if MaxCurrent == 0
			Debug.Notification("DynDOLOD missing data for " + FirstbornList)
			GotoState("EmptyState")
			Utility.Wait(3)
		else
			Debug.Notification("DynDOLOD successfully initialized")
			GotoState("Running")
			IBowToThee(MyFirstborn, FirstbornList, MinionList, MyAttach)
		endIf
	endIf
EndFunction

State Running
	Function IBowToThee(ObjectReference MyFirstborn, String FirstbornList, String MinionList, Bool MyAttach)
		GotoState("Updating")
		MyCurrentFirstborn = MyFirstborn
		MyCurrentAttach = MyAttach
		MyCurrentFirstbornList = FirstbornList
		MyCurrentMinionList = MinionList
		MyWorld = StringUtil.Substring(self.GetWorldspace() as string, 13, StringUtil.Find(self.GetWorldspace() as string, "(") - 14)
		MyImportFileName = "DynDOLOD_" + JsonUtil.GetStringValue("DynDOLOD_Worlds", MyWorld, MyWorld)
		if (MyCurrentAttach)
			StorageUtil.SetFormValue(self, "DynDOLOD_MyActiveFirstborn", MyCurrentFirstborn)
			MyOldFirstborn = MyCurrentFirstborn
			if (MyCurrentMinionList != MyOldMinionList)
				MaxCurrent = JsonUtil.IntListCount(MyImportFileName, MyCurrentMinionList)
				if (MyOldMinionList != "None")
					MaxOld = JsonUtil.IntListCount(MyImportFileName, MyOldMinionList)
				else
					MaxOld = 0
				endIf
				if (MaxCurrent > MaxOld)
					Index = MaxCurrent
				else
					Index = MaxOld
				endIf
				ThrottleCount = 0
				While Index
					Index -= 1
					if (Index < MaxCurrent)
						MyCurrent = JsonUtil.IntListGet(MyImportFileName, MyCurrentMinionList, Index) as Int
						CurrentRef = Game.GetFormFromFile(MyCurrent, MyModName) as ObjectReference
						if (CurrentRef)
							if (MyOldMinionList == "None")
								StorageUtil.SetIntValue(CurrentRef, "GridState", 1)
								CurrentRef.Activate(self)
							else
								if !JsonUtil.IntListHas(MyImportFileName, MyOldMinionList, MyCurrent)
									StorageUtil.SetIntValue(CurrentRef, "GridState", 1)
									CurrentRef.Activate(self)
								endIf
							endIf
						endIf
					endIf
					if (Index < MaxOld)
						MyCurrent = JsonUtil.IntListGet(MyImportFileName, MyOldMinionList, Index) as Int
						CurrentRef = Game.GetFormFromFile(MyCurrent, MyModName) as ObjectReference
						if (CurrentRef)
							if (MyCurrentMinionList == "None")
								StorageUtil.SetIntValue(CurrentRef, "GridState", 0)
								CurrentRef.Activate(Game.GetPlayer())
								ThrottleCount += 1
							else
								if !JsonUtil.IntListHas(MyImportFileName, MyCurrentMinionList, MyCurrent)
									StorageUtil.SetIntValue(CurrentRef, "GridState", 0)
									CurrentRef.Activate(Game.GetPlayer())
									ThrottleCount += 1
								endIf
							endIf
						endIf
					endIf
					if (ThrottleCount > ThrottleThreshold)
 						debug.trace(self+" Minion throttle")
						Utility.Wait(1)
						ThrottleCount = 0
					endIf
				endWhile
				CurrentRef = None
				MyOldMinionList = MyCurrentMinionList
			endIf
			if (MyCurrentFirstbornList != MyOldFirstbornList)
				MaxCurrent = JsonUtil.IntListCount(MyImportFileName, MyCurrentFirstbornList)
				if (MyOldFirstbornList != "None")
					MaxOld = JsonUtil.IntListCount(MyImportFileName, MyOldFirstbornList)
				else
					MaxOld = 0
				endIf
				if (MaxCurrent > MaxOld)
					Index = MaxCurrent
				else
					Index = MaxOld
				endIf
				ThrottleCount = 0
				While Index
					Index -= 1
					if (Index < MaxCurrent)
						MyCurrent = JsonUtil.IntListGet(MyImportFileName, MyCurrentFirstbornList, Index) as Int
						CurrentRef = Game.GetFormFromFile(MyCurrent, MyModName) as ObjectReference
						if (CurrentRef)
							if (MyOldFirstbornList == "None")
								StorageUtil.SetIntValue(CurrentRef, "GridState", 1)
								CurrentRef.Activate(self)
							else
								if !JsonUtil.IntListHas(MyImportFileName, MyOldFirstbornList, MyCurrent)
									StorageUtil.SetIntValue(CurrentRef, "GridState", 1)
									CurrentRef.Activate(self)
								endIf
							endIf
						endIf
					endIf
					if (Index < MaxOld)
						MyCurrent = JsonUtil.IntListGet(MyImportFileName, MyOldFirstbornList, Index) as Int
						CurrentRef = Game.GetFormFromFile(MyCurrent, MyModName) as ObjectReference
						if (CurrentRef)
							if (MyCurrentFirstbornList == "None")
								;this can not really happen but in case it does
								StorageUtil.SetIntValue(CurrentRef, "GridState", 0)
								CurrentRef.Activate(Game.GetPlayer())
								ThrottleCount += 1
							else
								if !JsonUtil.IntListHas(MyImportFileName, MyCurrentFirstbornList, MyCurrent)
									StorageUtil.SetIntValue(CurrentRef, "GridState", 0)
									CurrentRef.Activate(Game.GetPlayer())
									ThrottleCount += 1
								endIf
							endIf
						endIf
					endIf
					if (ThrottleCount > ThrottleThreshold)
						Utility.Wait(1)
						ThrottleCount = 0
					endIf
				endWhile
				CurrentRef = None
				MyOldFirstbornList = MyCurrentFirstbornList
			endIf
		else
			if (MyCurrentFirstborn == MyOldFirstborn)
				StorageUtil.UnsetFormValue(self, "DynDOLOD_MyActiveFirstborn")
				Index = JsonUtil.IntListCount(MyImportFileName, MyOldMinionList)
				ThrottleCount = 0
				While Index
					Index -= 1
					MyCurrent = JsonUtil.IntListGet(MyImportFileName, MyOldMinionList, Index) as Int
					CurrentRef = Game.GetFormFromFile(MyCurrent, MyModName) as ObjectReference
					if (CurrentRef)
						StorageUtil.SetIntValue(CurrentRef, "GridState", 0)
						CurrentRef.Activate(Game.GetPlayer())
						ThrottleCount += 1
					endIf
					if (ThrottleCount > ThrottleThreshold)
						Utility.Wait(1)
						ThrottleCount = 0
					endIf
				endWhile
				Index = JsonUtil.IntListCount(MyImportFileName, MyOldFirstbornList)
				ThrottleCount = 0
				While Index
					Index -= 1
					MyCurrent = JsonUtil.IntListGet(MyImportFileName, MyOldFirstbornList, Index) as Int
					CurrentRef = Game.GetFormFromFile(MyCurrent, MyModName) as ObjectReference
					if (CurrentRef)
						StorageUtil.SetIntValue(CurrentRef, "GridState", 0)
						CurrentRef.Activate(Game.GetPlayer())
						ThrottleCount += 1
					endIf
					if (ThrottleCount > ThrottleThreshold)
 						debug.trace(self+" throttle")
						Utility.Wait(1)
						ThrottleCount = 0
					endIf
				endWhile
				MyOldFirstbornList = "None"
				MyOldMinionList = "None"
				MyOldFirstborn = None
				CurrentRef = None
			endIf
		endIf
		GotoState("Running")
	EndFunction
EndState

State Updating
	Function IBowToThee(ObjectReference MyFirstborn, String FirstbornList, String MinionList, Bool MyAttach)
		;debug.trace(self + " updating - slow down " + MyFirstborn + " " + MyAttach)
		if (MyAttach)
			StorageUtil.SetFormValue(self, "DynDOLOD_MyActiveFirstborn", MyFirstborn)
		else
			StorageUtil.UnsetFormValue(self, "DynDOLOD_MyActiveFirstborn")
		endIf
	EndFunction
EndState

State Missing
	Function IBowToThee(ObjectReference MyFirstborn, String FirstbornList, String MinionList, Bool MyAttach)
	EndFunction
EndState
