extends GameExtender

const manager = preload("res://Modules/FoxLib/Internal/FoxLibAudioManager.gd")
const Globals = preload("res://FoxLib/Globals.gd")
const FoxUIManager = preload("res://FoxLib/FoxUIManager.gd")

var Smod = GlobalRegistry.getModule("SoundModule")
var wasScene:SceneBase
var inSexEngine:bool
var pack
var playedThisUpdate = false
var variance = Smod.pitchVarianceOption
var sfxPlayer2:AudioStreamPlayer

var oneshot = {
	"DomBondage":"chain",
	"DomLeashesSub":"chain",
	"Spanking":"spank",
	"BeatingUpWhenAngry":"slap",
	"DomUndressActions":"clothes",
	"DomUndressesSub":"clothes",
	"SubUndressActions":"clothes",
}

func _init():
	id = "SoundPlayer"
	# triggers sounds in response to player stats
	
	
func register(_GES:GameExtenderSystem):
	_GES.register(self, ExtendGame.pcUpdateNonBattleEffects) # this will run SoundPlayer every time the player's status effects are checked

func pcUpdateNonBattleEffects(_pc:Player):
	playedThisUpdate = false # sound plays only once, no infinite looping
	var currentScene = FoxUIManager.getCurrentScene()
	sfxPlayer2 = AudioStreamPlayer.new()
	currentScene.add_child(sfxPlayer2)
#	yield(GM.main, "saveLoadingFinished")
	if(GM.main.sceneStack.size() > 0): #wait until the game is loaded
		wasScene = GM.main.getCurrentScene() #need this to detect some exceptions
		
	var _floop = Smod.voicepackoption #should retrieve the selected voicepack from options menu (set by FoxLib) but sometimes it doesn't work
	pack = _floop.substr(_floop.find("_")+1,-1)
		
	variance = Smod.pitchVarianceOption/100
#	print(variance)
	if(Smod.HypnoOption):
		if(GM.pc.hasEffect(StatusEffect.Suggestible) and GM.pc.getEffect(StatusEffect.Suggestible).isHypnotized()):
			manager.playBGM(manager.getFoxAudio("SoundModule:Effecthum"))
		elif(GM.pc.hasEffect(StatusEffect.UnderHypnosis) or GM.pc.hasEffect(StatusEffect.HypnoVisorActive)):
			manager.playBGM(manager.getFoxAudio("SoundModule:Effecthum"))
		if(!GM.pc.hasEffect(StatusEffect.UnderHypnosis) and !GM.pc.hasEffect(StatusEffect.HypnoVisorActive)):
			manager.playBGM(null)
	
	#exception for sexEngine orgasm event
	if(wasScene.sceneID == "GenericSexScene"):
		if(wasScene.sexEngine.isInvolved("pc")):
			inSexEngine = true
			var engine:SexEngine = wasScene.sexEngine
			if(engine.hasSexEnded()): inSexEngine = false
			var asd = wasScene.sexEngine.getCharInfo("pc")
			if(asd.didJustCame()):
				orgasm()
			if(asd.hadStim):
				pleased()
			handleSexEngine(engine)
		else:
			return
			
	#exception for struggling
	if(wasScene.sceneID == "StrugglingScene"):
		if(wasScene.state == "startStruggleAgainst"):
			struggled()
			
	if(!GM.pc.is_connected("lust_changed",self,"bazinga")):
		GM.pc.connect("lust_changed",self,"bazinga")
#	if(!GM.pc.is_connected("stamina_changed",self,"on_stamina")):
#		GM.pc.connect("stamina_changed",self,"on_stamina")
	if(!GM.pc.is_connected("pain_changed",self,"bazinga")):
		GM.pc.connect("pain_changed",self,"ishurted")

func ishurted(pain, initialpain):
	if !inSexEngine:
		return
	var engine:SexEngine = GM.main.getCurrentScene().sexEngine
	var activity = engine.currentLastActivityID
	var test:SexActivityBase = engine.getActivityWithUniqueID(activity-1)
	if(test.id == "Spanking" && pain > initialpain && Smod.spankOption):
		play_effect(engine, "spank")
	elif(test.id == "BeatingUpWhenAngry" && pain > initialpain && Smod.punchOption):
		play_effect(engine, "slap")



func bazinga(lust, initialLust):
	if(initialLust-lust == GM.pc.lustThreshold()):
		orgasm()
	elif(GM.pc.getArousal() != 0 || inSexEngine):
		pleased()
	elif(lust > initialLust):
		teased()

func handleSexEngine(engine):
	var activity = engine.currentLastActivityID
	var test:SexActivityBase = engine.getActivityWithUniqueID(activity-1)
	var peeps = engine.getCharIDList()
	if(Smod.cumEffect):
		for pers in peeps:
			var _temp = engine.getCharInfo(pers)
			if(_temp.didJustCame()):
		#					randi() % 5 + 1
				cum(GM.main.getCharacter(pers))
				yield(wasScene.get_tree().create_timer(1.2),"timeout")
				cum(GM.main.getCharacter(pers))
				yield(wasScene.get_tree().create_timer(1.5),"timeout")
				cum(GM.main.getCharacter(pers))
	if(test == null):
		return
	elif(test.id == "DomUndressActions" or test.id == "SubUndressActions" or test.id == "DomUndressesSub"):
		if(Smod.clothOption):
			var _to_play = oneshot[test.id]
			play_effect(engine, _to_play)
	elif(test.id == "DomLeashesSub" && Smod.chainOption):
		for pers in peeps:
			if(engine.isLeashed()):
				return
		var _to_play = oneshot[test.id]
		play_effect(engine, _to_play)
	elif(test.id == "DomBondage" && Smod.chainOption):
		var _to_play = oneshot[test.id]
		play_effect(engine, _to_play)

func playXTimes(_sound, _times, _delay):
	
	pass
	
func orgasm():
	var sound
	if(Smod.Osoundoption && !playedThisUpdate):
		if(GM.pc.hasEffect(StatusEffect.Gagged) && Smod.gagsoundoption):
			sound = manager.getFoxAudio("SoundModule:Soundorgasm_gagged"+pack)
		else:
			sound = manager.getFoxAudio("SoundModule:Soundorgasm"+pack)
#		var sound2 = manager.getFoxAudio("SoundModule:Effectcum")
#		if(GM.pc.hasBodypart(BodypartSlot.Vagina) and not GM.pc.hasBodypart(BodypartSlot.Penis)):
#			sound2 = manager.getFoxAudio("SoundModule:Effectsquirt")
		if sound == null:
			Log.printerr("[SoundMod] Failed to locate FoxAudio SoundModule: " + pack)
		else:
			sound.setPitchVariance(variance)
			sound.playAsSFX()
#			sound2.playAsBGM()
#			yield(wasScene.get_tree().create_timer(3),"timeout")
#			manager.playBGM(null)
		
		Log.print("[SoundMod] Playing Audio Object: " + sound.getId())
		playedThisUpdate = true

func pleased():
	var sound
	if(Smod.Psoundoption && !playedThisUpdate):
		if(GM.pc.hasEffect(StatusEffect.Gagged) && Smod.gagsoundoption):
			sound = manager.getFoxAudio("SoundModule:Soundpleasure_gagged"+pack)
		else:sound = manager.getFoxAudio("SoundModule:Soundpleasure"+pack)
		if sound == null:
			Log.printerr("[SoundMod] Failed to locate FoxAudio SoundModule: " + pack)
		else:
			sound.setPitchVariance(variance)
			sound.playAsSFX()
		Log.print("[SoundMod] Playing Audio Object: " + sound.getId())
		playedThisUpdate = true
	
func teased():
	var sound
	if(Smod.Tsoundoption && !playedThisUpdate):
		if(GM.pc.hasEffect(StatusEffect.Gagged) && Smod.gagsoundoption):
			sound = manager.getFoxAudio("SoundModule:Soundtease_gagged"+pack)
		else:sound = manager.getFoxAudio("SoundModule:Soundtease"+pack)
		if sound == null:
			Log.printerr("[SoundMod] Failed to locate FoxAudio SoundModule: " + pack)
		else:
			sound.setPitchVariance(variance)
			sound.playAsSFX()
		Log.print("[SoundMod] Playing Audio Object: " + sound.getId())
		playedThisUpdate = true


func struggled():
	var sound
	if(Smod.Ssoundoption && !playedThisUpdate):
		if(GM.pc.hasEffect(StatusEffect.Gagged) && Smod.gagsoundoption):
			sound = manager.getFoxAudio("SoundModule:Soundstruggle_gagged"+pack)
		else:sound = manager.getFoxAudio("SoundModule:Soundstruggle"+pack)
		if sound == null:
			Log.printerr("[SoundMod] Failed to locate FoxAudio SoundModule: " + pack)
		else:
			sound.setPitchVariance(variance)
			sound.playAsSFX()
		Log.print("[SoundMod] Playing Audio Object: " + sound.getId())
		playedThisUpdate = true
	
func on_stamina():
	pass

func playCh2(audioSample, pitchDiff=0.0):
	if audioSample != null and ((audioSample is AudioStreamOGGVorbis) or (audioSample is AudioStreamMP3)) and audioSample.loop:
		# Disable looping for incomming audio samples as we do not support looping audio properly.
		audioSample.loop = false
	if pitchDiff < -0.5:
		pitchDiff = -0.5
	elif pitchDiff > 0.5:
		pitchDiff = 0.5
	if sfxPlayer2.is_playing():
		sfxPlayer2.stop()
	if audioSample != null:
		sfxPlayer2.pitch_scale = 1.0 + pitchDiff
		sfxPlayer2.set_stream(audioSample)
		sfxPlayer2.play()
	else:
		sfxPlayer2.pitch_scale = 1.0

func play_effect(_engine:SexEngine, _activity):
	var sound
	sound = manager.getFoxAudio("SoundModule:Effect"+_activity)
	if sound == null: 
		Log.printerr("[SoundMod] Failed to locate FoxAudio SoundModule: " + pack)
	else:
		playCh2(sound.getLoadedAudio(),variance)
		playedThisUpdate = true
		Log.print("[SoundMod] Playing Audio Object: " + sound.getId())
			
			
func cum(_ch):
	var sound = manager.getFoxAudio("SoundModule:Effectcum")
	if(_ch.hasBodypart(BodypartSlot.Vagina) and not _ch.hasBodypart(BodypartSlot.Penis)):
		if(Smod.squirtEffect):
			sound = manager.getFoxAudio("SoundModule:Effectsquirt")
	if sound == null:
		Log.printerr("[SoundMod] Failed to locate FoxAudio SoundModule: " + pack)
	else:
		playCh2(sound.getLoadedAudio(),variance)
		playedThisUpdate = true
