// **********************************************
// Inspired by the IE only Jigsaw Puzzle at
// http://www.webreference.com/dhtml/column8/
// **********************************************

// User settings
var borderWidth = 3; // how wide is the border?
var puzzAcross = 2; // default puzzle pieces across
var puzzDown = 2; // default puzzle pieces down
var flashTotal = 4; // how many flashes when piece is placed in right spot?
var isGridOn = true; // is grid on initially?
var gridButtonGoOn = 'Images/Puzzle/Indsaet.jpg'; // Button for grid to show
var gridButtonGoOff = 'Images/Puzzle/Fjern.jpg'; // Button for grid to hide

// Internal settings
var puzzLeft = null; // puzzle left (without border)
var puzzRight = null; // puzzle right (without border)
var puzzTop = null; // puzzle top (without border)
var puzzBottom = null; // puzzle bottom (without border)
var puzzWidth = null; // puzzle width (without border)
var puzzHeight = null; // puzzle height (without border)
var puzzPieces = 0; // count of puzzle pieces?
var pieceWidth = 0; // piece width
var pieceHeight = 0; // piece height
var solvedPieces = 0; // solved pieces
var pieceNext = 0; // next piece to solve
var flashCount = 0; // count of flashes
var flashTimer = null; // flash timer interval
var breakUpActive = false; // Check for impatient user clicks
var theDiv = null; // temporary storage of div elements during manipulation
var theImage = null; // temporary storage of img elements during manipulation
var i = 0; // for counting within for loops
var wW = 0; // window width
var wH = 0; // window height
var imgWidth = 0; // image width
var imgHeight = 0; // image height

// elements to get a handle to
var body = null;
var elSmallImages = null;
var elNewImage = null;
var intervalNewImage = null;
var elPuzzle = null;
var elImage = null;
var elGrid = null;
var elControls = null;
var elButtons = null;
var elSelects = null;
var elButSolve = null;
var elButDoNext = null;
var elButToView = null;
var elButBreak = null;
var elButGrid = null;
var elAcross = null;
var elDown = null;


// Start up ***********************

function addListeners() {
	body = document.getElementsByTagName('body')[0];

	var allSelects = document.getElementsByTagName('select');
	for (i = 0; i < allSelects.length; i++)
		addEvent(allSelects[i], 'change', blurListener, false);

	// Get elements
	elSmallImages = getEl('smallImages');
	elPuzzle = getEl('divPuzzle');
	elImage = getEl('imgImage');
	elGrid = getEl('divGrid');
	elControls = getEl('divControls');
	elButtons = getEl('divButtons');
	elSelects = getEl('divSelects');
	elButSolve = getEl('butSolve');
	elButDoNext = getEl('butDoNext');
	elButToView = getEl('butToView');
	elButBreak = getEl('butBreak');
	elButGrid = getEl('butGrid');
	elAcross = getEl('selAcross');
	elDown = getEl('selDown');
	wW = winWidth();
	wH = winHeight();

	// Reset in breakUp and clearUp!
	elButSolve.style.display = 'none';
	elButDoNext.style.display = 'none';
	elButBreak.style.display = 'inline';
	elButToView.style.display = 'inline';
	elButGrid.style.display = 'none';
	elAcross.value = puzzAcross; // Go to intitial state
	elDown.value = puzzDown; // Go to intitial state

	// Create Start Up Images
	elSmallImages.style.top = (isIE) ? '20px' : '10px';
	var j = imagesArray.length;
	for (i = 0; i < j; i++) {
		theImage = document.createElement('img');
		theImage.src = 'Images/Puzzle/Small/' + imagesArray[i][0];
		theImage.BigImage = 'Images/Puzzle/' + imagesArray[i][0];
		theImage.className = 'smallImage';
		theImage.title = imagesArray[i][3];
		elSmallImages.appendChild(theImage);
	}

	var allImages = document.getElementsByTagName('img');
	var j = allImages.length;
	for (i = 0; i < j; i++) {
		theImage = allImages[i];
		if (theImage.className.indexOf('smallImage') != -1) {
			addEvent(theImage, 'mousedown', loadPuzzle, false);
			addEvent(theImage, 'mouseover', highlightImage, false);
			addEvent(theImage, 'mouseout', highlightImage, false);
		} else if (theImage.className.indexOf('controlButton') != -1) {
			addEvent(theImage, 'mouseover', rollImage, false);
			addEvent(theImage, 'mouseout', rollImage, false);
			theImage.overSrc = getFront(theImage.src, '.jpg') + 'Over.jpg';
			theImage.outSrc = theImage.src;
		}
	}
}

function loadPuzzle() {
	elNewImage = new Image();
	elNewImage.onload = function() {
		puzzWidth = elNewImage.width;
		puzzHeight = elNewImage.height;
		elImage.src = elNewImage.src;
		elImage.width = puzzWidth;
		elImage.height = puzzHeight;
		centerPuzzle();

		elPuzzle.style.border = borderWidth + 'px solid #000';
		elPuzzle.style.width	= elButtons.style.width = puzzWidth + 'px';

		// Reset in goToView
		elSmallImages.style.display = 'none'; // If visibility is used, window can be scrolled downward
		elPuzzle.style.visibility = 'visible';
		elImage.style.visibility = 'visible';
		elSelects.style.visibility = 'visible';
	};
	elNewImage.src = this.BigImage;
}

function goToView() {
	elPuzzle.style.visibility = 'hidden';
	elImage.src = 'Images/empty.gif';
	elImage.style.visibility = 'hidden';
	elSelects.style.visibility = 'hidden';
	elSmallImages.style.display = 'block'; // If visibility is used, window can be scrolled downward
}


// Break up ***********************

function breakUp() {
	if (breakUpActive) return;;
	breakUpActive = true;
	puzzLeft = findPosX('divPuzzle') + borderWidth;
	puzzTop = findPosY('divPuzzle') + borderWidth;
	puzzAcross = elAcross.value;
	puzzDown = elDown.value;
	puzzPieces = puzzAcross * puzzDown;
	pieceWidth = puzzWidth / puzzAcross;
	pieceHeight = puzzHeight / puzzDown;
	puzzRight = puzzLeft + puzzWidth;
	puzzBottom = puzzTop + puzzHeight;

	// Reset in clearUp
	elImage.style.visibility = 'hidden';
	elButSolve.style.display = 'inline';
	elButDoNext.style.display = 'inline';
	elButBreak.style.display = 'none';
	elButToView.style.display = 'none';
	elButGrid.style.display = 'inline';
	elSelects.style.display = 'none';

	makeGrid();
	createPuzzle();
	dragObject.init(); // Make pieces draggable

	pieceNext = 1;
	solvedPieces = 0;
	breakUpActive = false;
}

function makeGrid() {
	var setLeft = 0;
	var setTop = 0;
	for (i = 1; i <= puzzPieces; i++) {
		theDiv = document.createElement('div');
		theDiv.style.position = 'absolute';
		theDiv.style.left = setLeft + 'px';
		theDiv.style.top = setTop + 'px';
		setLeft += pieceWidth;
		if ((i % puzzAcross) == 0) {
			setLeft = 0;
			setTop += pieceHeight;
		}
		theDiv.style.border = '1px solid #808080';
		theDiv.style.visibility = 'inherit';
		theDiv.style.width = pieceWidth + 'px';
		theDiv.style.height = pieceHeight + 'px';
		elGrid.appendChild(theDiv);
	}

	if (isGridOn) {
		elButGrid.src = gridButtonGoOff;
		elButGrid.overSrc = getFront(gridButtonGoOff, '.jpg') + 'Over.jpg';
		elButGrid.outSrc = gridButtonGoOff;
		elGrid.style.visibility = 'visible';
	} else {
		elButGrid.src = gridButtonGoOn;
		elButGrid.overSrc = getFront(gridButtonGoOn, '.jpg') + 'Over.jpg';
		elButGrid.outSrc = gridButtonGoOn;
		elGrid.style.visibility = 'hidden';
	}
}

function createPuzzle() {
	var topCount = 0;
	for (i = 1; i <= puzzPieces;) {
		pixT = topCount * pieceHeight;
		pixB = (topCount + 1) * pieceHeight;
		for (var j = 1; j <= puzzAcross; j++) {
			pixR = pieceWidth * j;
			pixL = pieceWidth * (j-1);
			theDiv = document.createElement('div');
			theDiv.id = 'divPiece' + i;
			theDiv.className = 'draggable';
			theDiv.style.clip = 'rect(' + pixT + 'px, ' + pixR + 'px, ' + pixB + 'px, ' + pixL + 'px)';
			theDiv.style.left = getRandomNumber('width') + -pixL + 'px';
			theDiv.style.top = getRandomNumber('height') + -pixT + 'px';
			theDiv.pixelLeft = pixL;
			theDiv.pixelTop = pixT;
			theDiv.style.visibility = 'visible';
			theDiv.style.cursor = 'move';
			theDiv.style.zIndex = 1; // Unsolved pieces have a zIndex of 1
			theDiv.isSolved = false;
			theImage = document.createElement('img');
			theImage.name = 'imgPiece' + i
			theImage.id = 'imgPiece' + i
			theImage.src = elImage.src;
			theDiv.appendChild(theImage);
			body.appendChild(theDiv);
			i++;
		}
		topCount++
	}
}


// Make up ************************

function checkPieceDrop(obj, dropLeft, dropTop) { // Called from PuzzleDrag.js!
	theDiv = obj.selectedObject;
	theDivLeft = parseInt(theDiv.style.left);
	theDivTop = parseInt(theDiv.style.top);

	if ((dropLeft >= puzzLeft) && (dropLeft <= puzzRight) && (dropTop >= puzzTop) && (dropTop <= puzzBottom)) {
		// Piece is inside puzzle
		if ((Math.abs(puzzLeft - theDivLeft) < (pieceWidth / 2)) && (Math.abs(puzzTop - theDivTop) < (pieceHeight / 2))) {
			// Piece is in the right spot
			theDiv.style.left = puzzLeft + 'px';
			theDiv.style.top = puzzTop + 'px';
			clearInterval(flashTimer); // If pieces is filled too quickly
			checkPieces(); // To make solved pieces visible if clearInterval stopped flash at hidden state
			theDiv.isSolved = true;
			flashTimer = setInterval("flash(false)", 80);
		} else { // Piece is not in the right spot
			theDiv.style.left = theDivLeft + 10 + 'px';
			theDiv.style.top = theDivTop + 10 + 'px';
		}
	} else { // Piece is outside puzzle. Check for offscreen left & top
		if (theDivLeft < (-theDiv.pixelLeft - (pieceWidth * 0.5)))
			theDiv.style.left = -theDiv.pixelLeft + 10 + 'px';
		if (theDivTop < (-theDiv.pixelTop - (pieceHeight * 0.5)))
			theDiv.style.top = -theDiv.pixelTop + 10 + 'px';
	}
}

function checkChoice() {
	if (confirm("Er du sikker på, at du vil samle puslespillet?"))
		return true;
	else
		return false;
}

function solvePuzzle(doAllPieces) {
	theDiv = getEl('divPiece' + pieceNext);
	pieceNext++;

	while (theDiv.isSolved) {
		theDiv = getEl('divPiece' + pieceNext);
		pieceNext++;
	}

	if (doAllPieces)
		flashTimer = setInterval("flash(true)", 120);
	else
		flashTimer = setInterval("flash(false)", 120);
}

function flash(doAllPieces) {
	if (flashCount != flashTotal) {
		theDiv.style.visibility = (theDiv.style.visibility == 'visible') ? 'hidden' : 'visible';
		flashCount++;
	} else {
		clearInterval(flashTimer);
		flashCount = 0;
		// When flash is over we can finish off the piece ...
		if (solvedPieces < puzzPieces)
			finishPiece();
		// ... and continue with next piece if doAllPieces is true and there is a next piece :-)
		if (doAllPieces && (solvedPieces < puzzPieces))
			solvePuzzle(true);
	}
}

function finishPiece() {
	theDiv.style.left = puzzLeft + 'px'; // If not dropped by user but called from solvePuzzle --> flash
	theDiv.style.top = puzzTop + 'px'; // If not dropped by user but called from solvePuzzle --> flash
	dragObject.removeDrag(theDiv);
	theDiv.isSolved = true;
	theDiv.style.zIndex = 0; // Make solved piece show below unsolved pieces
	theDiv.style.cursor = 'default';
	solvedPieces++;
	if (solvedPieces == puzzPieces)
		clearUp();
}

function clearUp() {
	clearInterval(flashTimer);
	for (i = 1; i <= puzzPieces; i++) {
		theDiv = getEl('divPiece' + i);
		if (theDiv)
			body.removeChild(theDiv);
	}

	elButSolve.style.display = 'none';
	elButDoNext.style.display = 'none';
	elButBreak.style.display = 'inline';
	elButToView.style.display = 'inline';
	elButGrid.style.display = 'none';
	elSelects.style.display = 'block';
	elGrid.innerHTML = ''; // To make room for image to show
	elImage.style.visibility = 'visible';

	theDiv = elImage; // To make whole image flash
	flashTimer = setInterval("flash(false)", 80);
}


// Little Local Helpers

function blurListener() { // This operates on select; not a
	this.blur();
}

function highlightImage(e) {
	var e = e || window.event;
	if (e.type == 'mouseover') {
		this.style.borderColor = 'red';
		this.style.borderStyle = 'outset';
	}
	if (e.type == 'mouseout') {
		this.style.borderColor = '#fff';
		this.style.borderStyle = 'solid';
	}
}

function rollImage(e) {
	var e = e || window.event;
	if (e.type == 'mouseover')
		this.src = this.overSrc;
	else if (e.type == 'mouseout')
		this.src = this.outSrc;
}

function centerPuzzle() {
	wW = winWidth();
	wH = winHeight();
	if (elNewImage) {
		elPuzzle.style.left = (wW/2 - elNewImage.width/2) + 'px';
		elButtons.style.left = (wW/2 - elNewImage.width/2) + 'px';
		var topTest = ((wH/2) - (elNewImage.height/2)) - 35;
	} else {
		elPuzzle.style.left = (wW/2 - parseInt(getElementWidth('imgImage')/2)) + 'px';
		elButtons.style.left = (wW/2 - parseInt(getElementWidth('imgImage')/2)) + 'px';
		var topTest = (wH/2 - parseInt(getElementHeight('imgImage')/2) - 35);
	}
	if (topTest > 50) topTest = 50;
	elPuzzle.style.top = topTest + 'px';
}

function gridToggle() {
	if (!isGridOn) {
		elButGrid.src = gridButtonGoOff;
		elButGrid.overSrc = getFront(gridButtonGoOff, '.jpg') + 'Over.jpg';
		elButGrid.outSrc = gridButtonGoOff;
		elGrid.style.visibility = 'visible';
		isGridOn = true;
	} else {
		elButGrid.src = gridButtonGoOn;
		elButGrid.overSrc = getFront(gridButtonGoOn, '.jpg') + 'Over.jpg';
		elButGrid.outSrc = gridButtonGoOn;
		elGrid.style.visibility = 'hidden';
		isGridOn = false;
	}
}

function getRandomNumber(dimension) {
	var rNum = 0;
	if (dimension == 'width')
		rNum = Math.floor(Math.random() * (wW - 20 - pieceWidth)) + 1; // Adjust for screen width, scrollbar and pieceWidth
	else if (dimension == 'height')
		rNum = Math.floor(Math.random() * (wH - 20 - pieceHeight)) + 1; // Adjust for screen width, scrollbar and pieceHeight
	return parseInt(rNum);
}

function checkPieces() {
	if (solvedPieces < puzzPieces) {
		for (i = 1; i < puzzPieces; i++) { // Count only to second last
			if (getEl('divPiece' + i))
				getEl('divPiece' + i).style.visibility = 'visible';
		}
	}
}

addEvent(window, 'load', addListeners, false);
addEvent(window, 'resize', centerPuzzle, false);

