var BakeHandlerStatics = {};
BakeHandlerStatics.BakingAllowed = true;
BakeHandlerStatics.BakingAllowedChanged = new Action();
BakeHandlerStatics.SetBakingAllowed = function(value)
{
	this.bakingAllowed = value;
	if (this.BakingAllowedChanged != null) this.BakingAllowedChanged.call(this.bakingAllowed);
};

Engine.BakeHandler = class
{
	get baked()
	{
		return (this.parentDrawable.cacheAsBitmap || this.currentFramesUntilRebake >= 0);
	}

	constructor(parent /*Drawable*/, showLog = false/*bool*/)
	{
		this.bakeStarting = new Action();
		this.gameSettingsAllow = false;
		this.bakeAllowed = false;
		this.unbakeableChildren = 0;
		this.currentFramesUntilRebake = -1;
		this.framesUntilRebake = 30;
		this.currSecondsToRebake = -1;
		this.maxSecondsToRebake = 0.5;
		this.showLog = false;
		this.baking = false;
		
		this.parentDrawable = parent;
		this.showLog = showLog;
		Engine.EnterFrameManagerInstance.add(this, this.enterNextFrame);
		this.gameSettingsAllow = BakeHandlerStatics.BakingAllowed;
		BakeHandlerStatics.BakingAllowedChanged.addListener(this, this.updateUICaching);
	}

	updateUICaching(currentValue /*bool*/)
	{
		if (this.gameSettingsAllow != currentValue) this.gameSettingsAllow = currentValue;
		// UnBake if uicaching is disabled
		if (!this.gameSettingsAllow) this.unbake();
	}

	changeUnbakeableChildren(numChildren /*int*/)
	{
		var oldChildren = this.unbakeableChildren;
		this.unbakeableChildren += numChildren;
		if (this.unbakeableChildren < 0) this.unbakeableChildren = 0;
		
		if (this.showLog) Debug.Log("BakeHandler::  " + this.parentDrawable.getGameObjectName() + " unbakeableChildren " + (this.numChildren > 0 ? "+1" : "-1") + " curr: " + this.unbakeableChildren);
		
		if (!this.gameSettingsAllow) return;
		if (this.unbakeableChildren == 0 && oldChildren > 0 && this.bakeAllowed && !this.baked)
		{
			if (this.showLog) Debug.Log("BakeHandler::  " + this.parentDrawable.getGameObjectName() + " CHILDREN ALLOWED TO REBAKE");
			this.bake();
		}
		else if (this.unbakeableChildren > 0 && oldChildren == 0 && this.Baked)
		{
			this.unbake();
		}
	}

	allowBake(bakeAllowed /*bool*/)
	{
		if (this.bakeAllowed == bakeAllowed) return;
		if (this.showLog) Debug.Log("BakeHandler::  " + this.parentDrawable.getGameObjectName() + " AllowBake " + (bakeAllowed ? "turn on" : "turn off"));
		this.bakeAllowed = bakeAllowed;
		
		if (!this.gameSettingsAllow) return;
		if (bakeAllowed && this.unbakeableChildren > 0) return;
		if (bakeAllowed && !this.baked)
		{
			this.bake();
		}
		else if (!bakeAllowed && this.baked)
		{
			this.unbake();
		}
	}

	bake(actualBake = false/*bool*/)
	{
		if (!this.gameSettingsAllow) return;
		if (!this.bakeAllowed) return;
		if (!this.baking)
		{
			this.baking = true;
			if (!this.parentDrawable.cacheAsBitmap)
			{
				if (this.actualBake)
				{
					this.currSecondsToRebake = -1;
					this.currentFramesUntilRebake = -1;
					
					this.parentDrawable.cacheAsBitmap = true;
					//this.parentDrawable.bakeLiveEffects();
				}
				else
				{
					if (this.showLog) Debug.Log("BakeHandler::  " + this.parentDrawable.getGameObjectName() + " setting currseconds to" + this.maxSecondsToRebake);
					this.currSecondsToRebake = 0;
					this.currentFramesUntilRebake = 0;
				}
			}
			this.baking = false;
		}
	}

	unbake()
	{
		this.currSecondsToRebake = -1;
		this.currentFramesUntilRebake = -1;
		if (this.parentDrawable.cacheAsBitmap)
		{
			if (this.showLog)
			{
				Debug.Log("BakeHandler:: " + this.parentDrawable.getGameObjectName() + " Unbaking");
				//UnityEditor.EditorApplication.isPaused = true;
			}
			this.parentDrawable.cacheAsBitmap = false;
			//this.parentDrawable.removeBakedFrame();
		}
	}

	enterNextFrame(timeElapsed /*float*/)
	{
		if (Engine.Drawable.fastRenderMode) return;
		
		if (!this.gameSettingsAllow) return;
		/*
            if (currSecondsToRebake >= 0)
		{
			if (showLog) Debug.Log("BakeHandler::  " + parentDrawable.GetGameObjectName() + " altering currseconds " + currSecondsToRebake);
			currSecondsToRebake += timeElapsed;
			if (currSecondsToRebake >= maxSecondsToRebake)
			{
				this.currSecondsToRebake = -1;
				if (bakeAllowed)
				{
					if (showLog) Debug.Log("BakeHandler::  " + parentDrawable.GetGameObjectName() + " Next Frame Baking");
					this.bake(true);
				}
			}
		}
		*/
        if (this.currentFramesUntilRebake >= 0)
		{
			if (this.showLog) Debug.Log("BakeHandler::  " + this.parentDrawable.getGameObjectName() + " altering currseconds " + this.currentFramesUntilRebake);
			this.currentFramesUntilRebake += 1;
			if (this.currentFramesUntilRebake >= this.framesUntilRebake)
			{
				if (this.bakeAllowed)
				{
					if (this.showLog) Debug.Log("BakeHandler::  " + this.parentDrawable.getGameObjectName() + " Next Frame Baking");
					this.bake(true);
				}
			}
		}
	}
}