// Player init

var linesStartTimmingArr = new Array ();
var lineDetailedTimmingArr = new Array ();
var lineDetailedTimmingStringArr = new Array ();

function InitializeKaraoke (lyricsLinesStartTimmingInfo, lyricsLineDetailedTimmingInfo)
{
	linesStartTimmingArr = lyricsLinesStartTimmingInfo.split (",");
	for (i = 0; i < linesStartTimmingArr.length; i++) {
		value = linesStartTimmingArr[i];
		linesStartTimmingArr[i] = (value == "" ? null : value * 1);
	}
	
	tempTimmingArr = lyricsLineDetailedTimmingInfo.split (";");
	for (i = 0; i < tempTimmingArr.length; i++) {
	
		lineDetailedTimmingStringArr[i] = tempTimmingArr[i];
		
		if (tempTimmingArr[i] == "")
			lineDetailedTimmingArr[i] = null;
		else {
			lineDetailedTimmingArr[i] = new Array ();
			tempTimmingArr2 = tempTimmingArr[i].split (",");
			for (j = 0; j < tempTimmingArr2.length; j++) {
				tempTimmingArr3 = tempTimmingArr2[j].split (":");
				elapsedTime = parseInt (tempTimmingArr3[0]);
				elapsedPercentage = parseFloat(tempTimmingArr3[1]);
				timmingInfo = { elapsedTime : elapsedTime, elapsedPercentage : elapsedPercentage };
				insertIndex = lineDetailedTimmingArr[i].length;
				lineDetailedTimmingArr[i][insertIndex] = timmingInfo;
			}
		}
	}
};

// Player interface

var singingBuffer = 100;

var playerMatchingStartTime;
var playerLastMatchedLineIndex;
var playerNextMatchedLineIndex;

var playerTimerId = null;

function StartKaraoke (matchingStartTime)
{
	StopKaraoke ();
	
	playerMatchingStartTime = matchingStartTime;
	playerLastMatchedLineIndex = -1;
	playerNextMatchedLineIndex = -1;
	
	songDiv = document.getElementById ("song-div");
	songDiv.scrollTop = 0;

	SchedulleNextPlayerEvent ();
	StartTitlePlayer ();
};

function StopKaraoke ()
{
	if (playerTimerId != null) {
		clearTimeout(playerTimerId);
		playerTimerId = null;
	}
	StopLinePlayer (playerLastMatchedLineIndex);
	StopTitlePlayer ();
};

function UpdateKareokeUI ()
{
	setTimeout('UpdateKareokeUIAux ()', 200);
};

function GetLinesStartTimmingArr ()
{
	return linesStartTimmingArr;
};

function GetLineDetailedTimmingArr ()
{
	return lineDetailedTimmingArr;
};

function GetLineDetailedTimmingStringArr ()
{
	return lineDetailedTimmingStringArr;
};

// Player behaivor

function UpdateKareokeUIAux ()
{
	if (linePlayerHighlight != null && linePlayerCurrentText != null)
		ShowHighlight (linePlayerHighlight, linePlayerCurrentText, -1, linePlayerCurrentText.offsetHeight);
};

function SchedulleNextPlayerEvent ()
{
	StopLinePlayer (playerLastMatchedLineIndex);
	
	playerLastMatchedLineIndex = playerNextMatchedLineIndex;
	
	StartLinePlayer (playerLastMatchedLineIndex);
	
	playerNextMatchedLineIndex++;
	while (playerNextMatchedLineIndex < linesStartTimmingArr.length && 
		linesStartTimmingArr[playerNextMatchedLineIndex] == null) {
		playerNextMatchedLineIndex++;
	}
		
	if (playerNextMatchedLineIndex < linesStartTimmingArr.length) {
		lineMatchingTimeSpan = linesStartTimmingArr[playerNextMatchedLineIndex];
		now = new Date ();
		elapsedTime = now - playerMatchingStartTime;
		nextPlayerEventDelay = lineMatchingTimeSpan - elapsedTime - singingBuffer;
		if (nextPlayerEventDelay < 0)
			nextPlayerEventDelay = 0;		
		playerTimerId = setTimeout('SchedulleNextPlayerEvent ()', nextPlayerEventDelay);
	}
};

// Line Player behaivor

var linePlayerSingingBuffer = 0;

var linePlayerTimerId = null;
var linePlayerStartTime;
var linePlayerTimmingArr;
var linePlayerTimeFrameIndex;
var linePlayerHighlight = null;
var linePlayerCurrentText = null;

function StartLinePlayer (playerLineIndex)
{
	if (playerLineIndex >= 0) {
		linePlayerTimmingArr = lineDetailedTimmingArr[playerLineIndex];
		if (linePlayerHighlight == null)
			linePlayerHighlight = $('linePlayerHighlight');
		if (linePlayerCurrentText == null)
			linePlayerCurrentText = $('lyricsText' + playerLineIndex);
			
		if (linePlayerTimmingArr == null || linePlayerTimmingArr.length == 0) {
			AmateurKaraokeLineEffect (linePlayerHighlight, linePlayerCurrentText);
		}
		else {
			linePlayerStartTime = new Date ();
			linePlayerTimeFrameIndex = 0;
			SchedulleNextLinePlayerEvent ();
		}
	}
};

function StopLinePlayer (playerLineIndex)
{
	if (playerLineIndex >= 0) {
		if (linePlayerTimerId != null) {
			clearTimeout(linePlayerTimerId);
			linePlayerTimerId = null;
		}
		if (linePlayerHighlight != null)
			linePlayerHighlight.style.display = 'none';
		linePlayerCurrentText = null;
	}		
};

function SchedulleNextLinePlayerEvent ()
{
	if (linePlayerTimmingArr == null || linePlayerHighlight == null || linePlayerCurrentText == null)
		return;

	if (linePlayerTimeFrameIndex >= linePlayerTimmingArr.length)
		return;
		
	timmingInfo = linePlayerTimmingArr[linePlayerTimeFrameIndex];

	elapsedPercentage = timmingInfo.elapsedPercentage;
	lineWidth = linePlayerCurrentText.offsetWidth;
	lineProgress = Math.floor (lineWidth * elapsedPercentage / 100);
	
	ProfessionalKaraokeLineEffect (linePlayerHighlight, linePlayerCurrentText, lineProgress);

	linePlayerTimeFrameIndex++;
	if (linePlayerTimeFrameIndex < linePlayerTimmingArr.length) {
		timmingInfo = linePlayerTimmingArr[linePlayerTimeFrameIndex];
		nextElapsedTime = timmingInfo.elapsedTime;
		now = new Date ();
		elapsedTime = now - linePlayerStartTime;
		nextPlayerEventDelay = nextElapsedTime - elapsedTime - linePlayerSingingBuffer;
		if (nextPlayerEventDelay < 0)
			nextPlayerEventDelay = 0;
		linePlayerTimerId = setTimeout('SchedulleNextLinePlayerEvent ()', nextPlayerEventDelay);
	}
};

function ProfessionalKaraokeLineEffect (playerHighlight, playerText, lineProgress)
{
	highlightWidth = lineProgress;
	if (linePlayerTimeFrameIndex == 0)
		ShowHighlight (playerHighlight, playerText, highlightWidth, playerText.offsetHeight);
	else {
		// Small optimization here, if it's not the first time we 
		// paint the highlight on a line, just expand it's width
		playerHighlight.style.width = highlightWidth + 'px';
	}
};

function AmateurKaraokeLineEffect (playerHighlight, playerText)
{
	ShowHighlight (playerHighlight, playerText, playerText.offsetWidth, playerText.offsetHeight);
};

function ShowHighlight (playerHighlight, playerText, width, height)
{
	pos = get_elem_position( playerText );
	pos_x = pos['left']; pos_y = pos['top'];
	
	highlightBottom = pos_y + height;
	
	songDiv = document.getElementById ("song-div");
	
	windowsHeight = songDiv.offsetHeight;
	topScrollOffset = songDiv.scrollTop;
	bottomScrollOffset = topScrollOffset + windowsHeight;
	
	if (highlightBottom + height * 2 > bottomScrollOffset)
		songDiv.scrollTop += (windowsHeight - height * 4);
	
	playerHighlight.style.position = 'absolute';
	playerHighlight.style.left = pos_x + 'px';
	playerHighlight.style.top = pos_y + 'px';
	if (width >= 0)
		playerHighlight.style.width = width + 'px';
	playerHighlight.style.height = height + 'px';
	playerHighlight.style.display = 'block';
};

// Title Player behaivor

var titlePlayerTimerId = null;
var titlePlayerText = null;
var titlePlayerHighlight = null;
var titlePlayerTimerDelay = 50;

function StartTitlePlayer ()
{
	if (linesStartTimmingArr[0] == null)
		return;
	if (titlePlayerText == null)
		titlePlayerText = $('_songTitle');
	if (titlePlayerHighlight == null)
		titlePlayerHighlight = $('titlePlayerHighlight');
	titlePlayerTimerId = setTimeout('SchedulleNextTitlePlayerEvent ()', titlePlayerTimerDelay);
};

function StopTitlePlayer ()
{
	if (titlePlayerTimerId != null) {
		clearTimeout(titlePlayerTimerId);
		titlePlayerTimerId = null;
	}
	if (titlePlayerHighlight != null)
		titlePlayerHighlight.style.display = 'none';
};

function KaraokeTitleLineEffect (playerHighlight, playerText, lineProgress)
{
	highlightWidth = lineProgress;
	ShowHighlight (playerHighlight, playerText, highlightWidth, playerText.offsetHeight);
};

function SchedulleNextTitlePlayerEvent ()
{
	if (linesStartTimmingArr[0] == null)
		return;

	now = new Date ();
	elapsedTime = now - playerMatchingStartTime;
	elapsedPercentage = (elapsedTime / linesStartTimmingArr[0]) * 100;
	lineProgress = Math.floor (titlePlayerText.offsetWidth * elapsedPercentage / 100);
	
	if (titlePlayerHighlight.offsetWidth >= titlePlayerText.offsetWidth)
		StopTitlePlayer ();
	else {
		KaraokeTitleLineEffect (titlePlayerHighlight, titlePlayerText, lineProgress);
		titlePlayerTimerId = setTimeout('SchedulleNextTitlePlayerEvent ()', titlePlayerTimerDelay);
	}
};
