//Copyright (C) Ben Parbury - All Rights Reserved. Unauthorized copying of this file, via any medium is strictly prohibited. Written by Ben Parbury <ben@gridlockinteractive.com> 2014
var gCompleteOverlay = new CompleteOverlay;

function CompleteOverlay()
{
	this.enabled = false;
	this.redraw = false;
	this.starsArrived = 0;
	this.width = 0;
	this.endLevelTime = 100;
	this.timer = 0;
	
	this.Update = function()
	{
		if (this.enabled == true && this.starsArrived >= gRulesSystem.GetCompleteStars())
		{
			if(this.timer == this.endLevelTime)
			{
				this.LoadNextLevel();
			}
			else
			{
				this.timer++;
			}				
		}
	}
	
	this.Enable = function()
	{
		this.enabled = true;
		this.redraw = true;
		this.timer = 0;
		this.starsArrived = 0;
		gUndoSystem.Disable();
		this.SetCompleteHintsOverlay();
	}
	
	this.Disable = function()
	{
		this.redraw = true;
		this.DrawClear();
		this.enabled = false;
	}
	
	this.Clear = function()
	{
		this.Disable();
	}
	
	this.StarArrived = function()
	{
		this.starsArrived++;
	}
	
	this.SetCompleteHintsOverlay = function()
	{
		if(!gLevelSystem.IsArcade())
		{
			this.DisplayHint();
		}
	}
	
	this.DisplayHint = function()
	{
		Math.seedrandom();	//Make random
		
		if(this.CanDisplayTutorialHint())
		{
			this.DisplayTutorialHint();
		}
		else if(this.CanDisplayBetter())
		{
			this.DisplayBetter();
		}
		else if (this.CanDisplayUnlockHint() && gDemo == false)
		{
			this.DisplayUnlockHint();
		}
		else
		{
			var totalCounters = 0;
			function HintPair(func, counters)
			{
				this.func = func.bind(gCompleteOverlay);
				this.counters = counters;
				totalCounters += counters;
			}
			
			var randomHints =
			[
				new HintPair(this.DisplayCustomHint, 9),
				new HintPair(this.DisplayStatsHint, 15)
			]
			if(!gDemo)
			{
				randomHints.push(new HintPair(this.DisplayStarsInSetHint, 9))
			}
			
			if(this.CanDisplayInputHint())
			{
				randomHints.push(new HintPair(this.DisplayInputHint, 2))
			}
			
			var counter = Math.round(Math.randomRange(0, totalCounters));
			var counters = 0;
			for(var i = 0; i < randomHints.length; i++)
			{
				counters += randomHints[i].counters;
				if(counter <= counters)
				{
					randomHints[i].func();
					break;
				}
			}
		}
		
		gLevelSystem.SetRandomSeed();	//pseudo-random
	}
	
	this.CanDisplayTutorialHint = function()
	{
		return (gLevelSystem.GetLevelSet().toLowerCase() == "vanilla");
	}
	
	this.DisplayTutorialHint = function()
	{
		switch(gLevelSystem.GetLevelName().toLowerCase())
		{
			case "blocks":
			{
				switch(gInputType)
				{
					case EInputType.Pad:
						gHintsOverlay.Set("Press A to continue, or any button once the stars have landed");
						break;
					case EInputType.Touch:
						gHintsOverlay.Set("Tap to continue");
						break;
					default:
						var key = KeyToString(EKeyCode.space) + " or " + KeyCodeToString(EKeyCode.return);
						gHintsOverlay.Set("Press " + key + " to continue, or any key once the stars have landed");
						break;
				}
			}
			break;
			case "pushy":
			{
				gHintsOverlay.Set("Pushing a block in a direction is 1 push, no matter how far you travel");
			}
			break;
			case "multi":
			{
				gHintsOverlay.Set(gHintsOverlay.RestartHint());
			}
			break;
		}
	}
	
	this.DisplayStarsInSetHint = function()
	{
		var set = gLevelSystem.GetLevelSet().toLowerCase();
		var starsForSet = gStatsSystem.GetStarsForSet(set);
		var maxStarsForSet = gStatsSystem.GetCountForSet(set) * gRulesSystem.kStarCount;
		if (starsForSet == maxStarsForSet)
		{
			//You've collected all 12 stars in Vanilla!
			gHintsOverlay.Set("You've collected all " + starsForSet + " " + this.GetPluralStar() + " in " + Localized(set) + "!")
		}
		else if (maxStarsForSet - starsForSet < 6)
		{
			//Only 1 star left to collect in Vanilla
			var starsLeft = (maxStarsForSet - starsForSet);
			var starWord = starsLeft == 1 ? this.GetSingularStar() : this.GetPluralStar();
			gHintsOverlay.Set("Only " + starsLeft + " " + starWord + " left to collect in " + Localized(set));
		}
		else
		{
			//You've collectd 1 star out of 15 stars in Vanilla
			var starWord = starsForSet == 1 ? this.GetSingularStar() : this.GetPluralStar();
			gHintsOverlay.Set("You've collected " + starsForSet + " " + starWord + " out of " + maxStarsForSet + " " + this.GetPluralStar() + " in " + Localized(set));
		}
	}
	
	this.DisplayStatsHint = function()
	{
		var fraction = Math.random();
		
		if(fraction >= 0.8)
		{
			//You've deleted 184 blocks!
			var stat = this.GetStatsValue(EStatsType.DeletedBlocks);
			gHintsOverlay.Set("You've cleared " + stat + " blocks!");
		}
		else if(fraction >= 0.6)
		{
			//You've pushed 84 times!
			var stat = this.GetStatsValue(EStatsType.Pushes);
			gHintsOverlay.Set("You've pushed " + stat + " times!");
		}
		else if(fraction >= 0.4)
		{
			//You've collected 14 stars in total!
			var stat = this.GetStatsValue(EStatsType.Stars);
			gHintsOverlay.Set("You've collected " + stat + " " + this.GetPluralStar() + " in total!");
		}
		else if (fraction >= 0.2)
		{
			//You've played Polyology for 2 hours and 34 minutes so far!
			var seconds = this.GetStatsValue(EStatsType.Time);
			var minutes = Math.floor(seconds/60);
			var hours = Math.floor(minutes/60);
			
			var displayMinutes = minutes % 60;
			var minuteText = displayMinutes == 1 ? "minute" : "minutes";
			
			if(minutes >= 60)
			{
				var hourText = hours == 1 ? "hour" : "hours";
				if(displayMinutes == 0)
				{
					//You've played Polyology for 1 hour so far!
					gHintsOverlay.Set("You've played Polyology " + (gDemo ? "Demo " : "") + "for " + hours + " " + hourText + " so far!");
				}
				else
				{
					//You've played Polyology for 2 hours and 34 minutes so far!
					var minuteText = minutes == 1 ? "minute" : "minutes";
					gHintsOverlay.Set("You've played Polyology " + (gDemo ? "Demo " : "") + "for " + hours + " " + hourText + " and " + displayMinutes + " " + minuteText + " so far!");
				}
			}
			else
			{
				//You've played Polyology for 1 minute so far!
				gHintsOverlay.Set("You've played Polyology " + (gDemo ? "Demo " : "") + "for " + displayMinutes + " " + minuteText + " so far!");
			}
		}
		else
		{
			//You've completed 23.4% of Polyology!
			var stars = gStatsSystem.GetStat(EStatsType.Stars);
			var starTotal = (gLevelsCount * gRulesSystem.kStarCount);
			var percentage = (stars/starTotal) * 100;
			var displayPercentage = (percentage == Math.round(percentage)) ? percentage : percentage.toFixed(1);
			gHintsOverlay.Set("You've completed " + displayPercentage + "% Polyology" + (gDemo ? " Demo" : "") + "!");
		}
	}
	
	this.CanDisplayUnlockHint = function()
	{
		return gUnlockSystem.HasJustUnlocked();
	}
	
	this.DisplayUnlockHint = function()
	{
		var hint = gUnlockSystem.GetJustUnlockedHint();
		gHintsOverlay.Set(hint);
	}
	
	this.CanDisplayBetter = function()
	{
		return gRulesSystem.IsBetter();
	}
	
	this.DisplayBetter = function()
	{
		gHintsOverlay.Set("Better than 3 " + this.GetPluralStar() + "! You've beaten the developer at his own game!");
	}
	
	this.CanDisplayInputHint = function()
	{
		return gInputType != EInputType.Touch;
	}
	
	this.DisplayInputHint = function()
	{
		var customHints = null;
		switch(gInputType)
		{
			case EInputType.Pad:
				customHints =
				[
					"Restart levels by pressing Y or Back",
					"Undo your actions by holding X or LT",
				]
				break;
			default:
				customHints =
				[
					"You can remap your controls from the pause menu",
					"Shortcut keys are awesome, check out yours in the pause menu",
				]
				break;
		}
		var index = Math.round(Math.randomRange(0, customHints.length - 1));
		gHintsOverlay.Set(customHints[index]);
	}

	this.DisplayCustomHint = function()
	{
		var customHints =
		[
			"You are listening to " + gMusic.GetTrack.title + " by " + gMusic.GetTrack().author,
			"Want to know how you're doing? Check the Statistics menu under Extras",
			"Multiple users on one computer? Check out the Profiles menu under Extras",
			"Finding a puzzle too hard? Try coming back to it later",
			"Polyology " + (gDemo ? "Demo " : "") + "has " + (gLevelsCount * gRulesSystem.kStarCount) + " " + this.GetPluralStar() + " in total to collect",
			"Polyomino is the name for shapes formed by joining one or more squares.",
			"Domino is the name for 2 connected squares, made popular by well, Dominoes.",
			"Tromino is the name for 3 connected squares.",
			"Tetromino is the name for 4 connected squares, made popular by Tetris.",
		]
		if (gInputType != EInputType.Pad)
		{
			customHints.push("Prefer using a controller? Just plug and play!")
		}
		var index = Math.round(Math.randomRange(0, customHints.length - 1));
		gHintsOverlay.Set(customHints[index]);
	}
	
	this.GetStatsValue = function(stat)
	{
		return gStatsSystem.GetLifetimeStat(stat) + gStatsSystem.GetStat(stat);
	}
	
	this.GetSingularStar = function()
	{
		return "star";
	}
	
	this.GetPluralStar = function()
	{
		return "stars";
	}
	
	this.DrawClear = function()
	{
		if(this.enabled && this.redraw)
		{
			if(gLevelSystem.IsArcade())
			{
				this.DrawClearArcadeText();
			}
			else
			{
				this.DrawClearText();
			}
		}
	}
	
	this.Draw = function()
	{
		if(this.enabled && this.redraw)
		{
			if(gLevelSystem.IsArcade())
			{
				this.DrawArcadeText();
			}
			else
			{
				this.DrawText();
			}
			
			this.redraw = true;
		}
	}
	
	this.KeyPress = function(key)
	{
		if (this.enabled && !gLevelSystem.IsArcade() && !gPause.IsPaused())
		{
			switch(key)
			{
				case EKeyCode.r:
				case EKeyCode.pagedown:
				case EKeyCode.c:
				case EKeyCode.home:
				case EKeyCode.p:
				case EKeyCode.escape:
					//Do nothing
					break;
				case EKeyCode.space:
				case EKeyCode.return:
					this.LoadNextLevel();
					break;
				default:
					if (this.starsArrived >= gRulesSystem.GetCompleteStars())
					{
						this.LoadNextLevel();
					}
					break;
			}
		}
	}
	
	this.LoadNextLevel = function()
	{
		var currentSet = gLevelSystem.GetLevelSet();
		var currentLevel = gLevelSystem.GetLevelName()
		var setAndLevel = GetNextLevelAndSet(currentSet, currentLevel);
		gLevelSystem.LoadLevel(setAndLevel.set, setAndLevel.level);
	}
	
	this.GetFontSize = function()
	{
		return GetFontScale(42);
	}
	
	this.GetTextX = function()
	{
		return gHintsOverlay.GetTextX();
	}
	
	this.GetTextY = function()
	{
		return gHintsOverlay.GetText2Y();
	}
	
	this.DrawClearText = function()
	{
		var x = this.GetTextX();
		var y = this.GetTextY();
		var height = this.GetFontSize() + 6;
		var width = this.width + 6;
		gDraw.overlay.clearRect(x - width/2, y - height + 6, width, height);
		//gDraw.overlay.rect(x - width/2, y - height, width, height);
		//gDraw.overlay.fillStyle = "rgb(255, 0, 0)";
		//gDraw.overlay.fill();
	}

	this.DrawText = function()
	{
		var fontSize = this.GetFontSize();
		var x = this.GetTextX();
		var y = this.GetTextY();
		gDraw.overlay.font	 = GetFont(fontSize);
		gDraw.overlay.textAlign	 = 'center';
		gDraw.overlay.textBaseline	 = 'bottom';
		var text = gRulesSystem.IsBetter() ? "Incredible!" : "Complete";
		gDraw.overlay.fillTextShadow(text, x, y, "rgb(255, 255, 255)", "rgb(0, 0, 0)");
		this.width = gDraw.overlay.measureText(text).width
	}
			
	this.GetArcadeTextSpacing = function()
	{
		return kTileSize * 0.1;
	}
	
	this.GetArcadeFontSize = function()
	{
		return 22;
	}
	
	this.GetArcadeTextX = function()
	{
		return kTileSize * 0.1;
	}
	
	this.GetArcadeTextY = function()
	{
		return gDraw.canvas.height - this.GetArcadeTextX();
	}
	
	this.DrawClearArcadeText = function()
	{
		var x = this.GetArcadeTextX();
		var y = this.GetArcadeTextY();
		var spacing = this.GetArcadeTextSpacing();
		var height = (this.GetFontSize() + spacing) * (gHighscoreSystem.count + 2);
		var width = 200;
		gDraw.overlay.clearRect(x, y - height + spacing, width, height);
		//gDraw.overlay.rect(x, y - height + spacing, width, height);
		//gDraw.overlay.fillStyle = "rgb(255, 0, 0)";
		//gDraw.overlay.fill();
	}

	this.DrawArcadeText = function()
	{
		var fontSize = this.GetArcadeFontSize();
		var x = this.GetArcadeTextX();
		var y = this.GetArcadeTextY();
		var spacing = this.GetArcadeTextSpacing();
		gDraw.overlay.font	 = GetFont(fontSize);
		gDraw.overlay.textAlign	 = 'left';
		gDraw.overlay.textBaseline	 = 'alphabetic';	
		var latestScore = gHighscoreSystem.latestScore;
		for(var i = gHighscoreSystem.count - 1; i >= 0; i--)
		{
			var score = gHighscoreSystem.scores[i];
			var text = SecondsToString(score);
			gDraw.overlay.fillTextShadow(text, x, y, "rgb(255, 255, 255)", "rgb(0, 0, 0)");
			if(score == latestScore && gHighscoreSystem.scores[i-1] != latestScore)
			{
				gDraw.overlay.save();
				var width = gDraw.overlay.measureText(text).width;
				gDraw.overlay.font	 = GetFont(fontSize * 0.5);
				gDraw.overlay.fillTextShadow(" New", x + width, y - (fontSize * 0.5), "rgb(255, 255, 255)", "rgb(0, 0, 0)");
				gDraw.overlay.restore();
				latestScore = null;
			}
			y -= (fontSize + spacing);
		}					
		
		y -= spacing;
		gDraw.overlay.fillTextShadow("Highscores", x, y, "rgb(255, 255, 255)", "rgb(0, 0, 0)");	
	}
}
