function PuzzleLoader(params) {
	this.containerId	= 1;
	this.puzzleType		= 'puzzle';
	this.puzzleContext	= 'puzzle';
	this.domain			= 'http://www.kryssord.no';
	this.puzzleWidth	= 604;
	this.totalWidth		= 679;
	this.totalHeight	= 0;

	this.puzzleId		= 0;
	this.competitionId	= 0;
	this.puzzleIdentifier = '';

	this.ePuzzle;
	this.puzzle;
	this.puzzleDisplay;

	if(params.puzzleType)		this.puzzleType		= params.puzzleType;
	if(params.puzzleContext)	this.puzzleContext	= params.puzzleContext;
	if(params.domain)			this.domain			= params.domain;
	if(params.puzzleId)			this.puzzleId		= params.puzzleId;
	if(params.competitionId)	this.competitionId	= params.competitionId;
	if(params.puzzleWidth)		this.puzzleWidth	= params.puzzleWidth;
	if(params.totalWidth)		this.totalWidth		= params.totalWidth;
	if(params.totalHeight)		this.totalHeight	= params.totalHeight;

	switch(this.puzzleContext) {
		case 'puzzle':		this.puzzleIdentifier = 'puzzleId='+this.puzzleId; break;
		case 'competition': this.puzzleIdentifier = 'competitionId='+this.competitionId+'&puzzleId='+this.puzzleId; break;
	}
}

PuzzleLoader.prototype = {
	initPuzzle: function() {
		// Create puzzle object
		this.ePuzzle = new ePuzzle(this.containerId);

		switch(this.puzzleType) {
			case 'xword':
				// Create puzzletype object
				this.puzzle = new eXWord(this.ePuzzle, this.puzzleId);

				// Create painter object
				this.puzzleDisplay	= new eXWord_Display(this.ePuzzle, this.puzzle);
			break;

			case 'sudoku':
				// Create puzzletype object
				this.puzzle = new eSudoku(this.ePuzzle, this.puzzleId);

				// Create painter object
				this.puzzleDisplay	= new eSudoku_Display(this.ePuzzle, this.puzzle);
			break;

			default:
				$(this.ePuzzle.puzzleContainer+'_loader').setStyle({display: 'none'});
				return false;
			break;
		}

		this.puzzleDisplay.totalWidth	= (this.totalWidth) ? this.totalWidth : null;
		this.puzzleDisplay.totalHeight	= (this.totalHeight) ? this.totalHeight : null;

		this.puzzle.initPainter();

		this.puzzle.setState('INIT');

		this.puzzle.baseUrl	= '/api?puzzleContext='+this.puzzleContext+'&';
		this.puzzle.domain	= this.domain;

		URL = this.puzzle.domain+this.puzzle.baseUrl+this.puzzleIdentifier+'&apimode=getPuzzle&puzzleWidth='+this.puzzleWidth;

		this.puzzle.url = URL;

		new Ajax.Request(URL, {
			method: 'GET',
			onSuccess: function(response) {
				try {
					try {
						var result = JSON.parse(response.responseText);
						if(result) {
							if(result.result == 'error') {
								alert(result.msg);

								return false;
							}

							switch(puzzleLoader.puzzleType) {
								case 'xword':	puzzleLoader.puzzle.xWord = result; break;
								case 'sudoku':	puzzleLoader.puzzle.sudoku = result;break;
							}
						} else {
							alert('En ukjent feil har oppstått. Kunne ikke åpne oppgaven.');

							return false;
						}
					} catch(JSONError) {
						switch(JSONError.name) {
							case 'JSONError':
								puzzleLoader.puzzle.errorMessage = 'JSON - Feil - ' + JSONError.message;
							break;

							case 'TypeError':
								puzzleLoader.puzzle.errorMessage = 'JSON - Typefeil - ' + JSONError.message;
							break;

							default:
								puzzleLoader.puzzle.errorMessage = 'JSON';
						}

						puzzleLoader.puzzle.setState('ERROR');
					}

					if(puzzleLoader.puzzle.getError()) {
						puzzleLoader.puzzle.errorMessage = this.puzzle.getError();
						puzzleLoader.puzzle.setState('ERROR');
					} else {
						puzzleLoader.puzzle.setState('BUILD');
						puzzleLoader.puzzle.buildPuzzle();
						puzzleLoader.puzzle.setState('IDLE');
						puzzleLoader.puzzle.statusController = new PeriodicalExecuter(puzzleLoader.puzzle.checkStatus.bindAsEventListener(puzzleLoader.puzzle), 1);
						$(puzzleLoader.ePuzzle.puzzleContainer).fire('puzzle:ready');
					}
				} catch(error) {
					switch(error.name) {
						case 'TypeError':
							puzzleLoader.puzzle.errorMessage = error.message;
						break;

						case 'ReferenceError':
							puzzleLoader.puzzle.errorMessage = 'Referansefeil - '+error.message;
						break;

						default:
							puzzleLoader.puzzle.errorMessage = 'Feil ('+error.name+':'+error.message+')';
					}

					puzzleLoader.puzzle.setState('ERROR');
				}
			},
			onException: function(request, error) {
				puzzleLoader.puzzle.errorMessage = 'Feil ('+error.name+':'+error.message+')';

				switch(error.name){
					case 'NS_ERROR_DOM_BAD_URI':
						if(error.message == 'Access to restricted URI denied') {
							puzzleLoader.puzzle.errorMessage = 'Feil - Nettleseren tillater ikke forespørsler mot domenet ' + domain;
						}
					break;

					case 'TypeError':
						puzzleLoader.puzzle.errorMessage = 'Feil - Nettleseren tillater ikke forespørsler mot domenet ' + domain;
					break;
				}

				puzzleLoader.puzzle.setState('ERROR');
			}
		});

	 	document.observe('user:login',this.ePuzzle.controlListener.bindAsEventListener(this.ePuzzle));
	}
}

/*
	Copyright 2008 Egmont Serieforlaget AS

	Developed by Escio AS - http://www.escio.no/
*/

function ePuzzle(containerId) {
	this.containerId			= containerId;
	this.puzzleContainer		= 'puzzle_' + containerId;

	this.puzzleElement			= $(this.puzzleContainer);

	this.puzzleType				= 'Puzzle';
	this.puzzleLevel			= 'Normal';
	this.puzzleLevelCodename	= 'normal';
	this.puzzleStatus			= 'unknown';
	this.puzzleTitle			= 'Puzzle';

	this.buttons				= new Array();

	this.popupWindow;

	this.initPuzzleArea = function() {
		this.puzzleWrapper	= document.createElement('div');
		this.puzzleHeader	= document.createElement('div');

		this.puzzleArea		= document.createElement('div');

		this.puzzleAuthor	= document.createElement('div');

		// Control area
		this.controlArea	= document.createElement('div');
		this.infoArea		= document.createElement('div');
		this.statusArea		= document.createElement('div');
		this.buttonArea		= document.createElement('div');

		var baseId = this.puzzleContainer;

		this.puzzleWrapper.id	= baseId + '_wrapper';
		this.puzzleHeader.id	= baseId + '_header';
		this.puzzleHeader.className	= 'puzzleHeader';

		this.puzzleArea.id		= baseId + '_puzzlearea';
		this.puzzleArea.className = 'puzzleArea';

		this.puzzleAuthor.id	= baseId + '_puzzleauthor';
		this.puzzleAuthor.className	= 'puzzleAuthor';

		// Control area
		this.controlArea.id		= baseId + '_controlarea';
		this.controlArea.className = 'controlArea';

		this.infoArea.id		= baseId + '_infoarea';
		this.infoArea.className = 'infoArea';

		this.statusArea.id		= baseId + '_statusarea';
		this.statusArea.className = 'statusArea';

		this.buttonArea.id		= baseId + '_buttonarea';
		this.buttonArea.className = 'buttonArea';

		this.puzzleElement.appendChild(this.puzzleWrapper);
		this.puzzleWrapper.appendChild(this.puzzleHeader);
		this.puzzleWrapper.appendChild(this.puzzleArea);

		this.puzzleWrapper.appendChild(this.puzzleAuthor);

		// Control area
		this.puzzleWrapper.appendChild(this.controlArea);
		this.controlArea.appendChild(this.infoArea);
		this.controlArea.appendChild(this.statusArea);
		this.controlArea.appendChild(this.buttonArea);
	}

	this.setPuzzleType = function(type) {
		this.puzzleType = type;

		if($(this.puzzleContainer+'_wrapper')) $(this.puzzleContainer+'_wrapper').className = 'puzzle ' + this.puzzleType;
	}

	this.setPuzzleCodename = function(codename) {
		this.puzzleCodename = codename;

		if($(this.puzzleContainer)) $(this.puzzleContainer).className = this.puzzleCodename;
	}

	this.setPuzzleLevel = function(level) {
		this.puzzleLevel = level;

		if(level == 'Lett')			this.puzzleLevelCodename = 'Easy';
		if(level == 'Middels')		this.puzzleLevelCodename = 'Medium';
		if(level == 'Vanskelig')	this.puzzleLevelCodename = 'Hard';
	}

	this.setPuzzleStatus = function(status) {
		this.puzzleStatus = status;
	}

	this.setPuzzleTitle = function(title) {
		this.puzzleTitle = title;

		if($(this.puzzleContainer + '_header')) {
			$(this.puzzleContainer + '_header').innerHTML = '';
			if(this.puzzleStatus == 'free') {
				$(this.puzzleContainer + '_header').innerHTML += '<div class="title"><p>Dagens oppgave</p><h2>'+title+'</h2></div>';
			} else {
				$(this.puzzleContainer + '_header').innerHTML += '<div class="title"><p>&nbsp;</p><h2>'+title+'</h2></div>';
			}
			$(this.puzzleContainer + '_header').innerHTML += '<div class="level"><p>&nbsp;</p><h2>' + this.puzzleLevel + '<img class="icon '+this.puzzleLevelCodename.toLowerCase()+'Large" src="/images/rd08/gif.gif"></h2></div>';
		}
	}

	this.setAuthor = function(author) {
		if(author != '') {
			if($(this.puzzleContainer+'_puzzleauthor')) $(this.puzzleContainer+'_puzzleauthor').innerHTML += '<span class="authorName">Forfatter:</span> ' + author;
		} else {
			if($(this.puzzleContainer+'_puzzleauthor')) $(this.puzzleContainer+'_puzzleauthor').innerHTML += '<span class="authorName">Forfatter:</span> ' + ' Redaksjonen';
		}
	}

	this.setDateTs = function(dateTs) {
		//'Datert: ' + tsToDate(dateTs, 'd.m.Y');
	}

	this.setAdditionalInfo = function(additionalInfo) {
		if($(this.puzzleContainer+'_infoarea')) $(this.puzzleContainer+'_infoarea').innerHTML = additionalInfo;
	}

	this.setStatus = function(newStatus) {
		if($(this.puzzleContainer+'_statusarea')) $(this.puzzleContainer+'_statusarea').innerHTML = newStatus;
	}

	this.addButton = function(listener, title, id, enabled) {
		this.buttons.push(id);

	 	var newButton = document.createElement('input');
		newButton.type = 'button';

		newButton.id = this.puzzleContainer+ '_' + id;

		if(!enabled) {
			newButton.disabled = true;
			newButton.className = 'button ' +  id + ' inactive';
		} else {
			newButton.className = 'button ' +  id;
		}
		newButton.value = title;

	 	$(this.puzzleContainer+'_buttonarea').appendChild(newButton);

		Event.observe(newButton.id,'click',listener.controlListener.bindAsEventListener(listener));
	}

	this.removeButton = function(buttonId) {
		if(!$(this.puzzleContainer+'_'+buttonId)) return false;

		$(this.puzzleContainer+'_'+buttonId).remove();

		return true;
	}

	this.removeButtons = function() {
		Element.extend(this.buttons);
		this.buttons.each(function(buttonId) {
			puzzleLoader.ePuzzle.removeButton(buttonId);
		});
	}

	this.enableButton = function(buttonId) {
		if(!$(this.puzzleContainer+'_'+buttonId)) return false;

		if($(this.puzzleContainer+'_'+buttonId).disabled) {
			$(this.puzzleContainer+'_'+buttonId).enable();
			$(this.puzzleContainer+'_'+buttonId).className = 'button ' + buttonId;

			return true;
		}

		return false;
	}

	this.disableButton = function(buttonId) {
		if(!$(this.puzzleContainer+'_'+buttonId)) return false;

		if(!$(this.puzzleContainer+'_'+buttonId).disabled) {
			$(this.puzzleContainer+'_'+buttonId).disable();
			$(this.puzzleContainer+'_'+buttonId).className = 'button ' + buttonId + ' inactive';

			return true;
		}

		return false;
	}

	this.confirm = function(message, callback) {
		var confirmWindow = new domPupup();

		confirmWindow.setClassName('Confirm');
		confirmWindow.setCaption('Bekreft');
		confirmWindow.setCloseText('');
		confirmWindow.setBody(message);

		confirmWindow.setSizeXY(400, 100);

		var containerPosition	= this.puzzleElement.positionedOffset();
		var containerSize		= this.puzzleElement.getHeight();

		confirmWindow.setPositionXY(containerPosition['left']+103,containerPosition['top']+containerSize-250);
		
		//confirmWindow.setCentered(true);

		confirmWindow.setConfirm('YESNO', {yes:'Ja',no:'Nei'}, callback);

		return confirmWindow.display();
	}

	this.buyPuzzleInfo = function() {
		this.popupWindow = new domPupup();

		this.popupWindow.setCaption('Kjøp av konkurranseoppgave');
		this.popupWindow.setCloseText('Lukk');

		switch(puzzleLoader.puzzleType) {
			case 'xword':	var puzzle = puzzleLoader.puzzle.xWord; break;
			case 'sudoku':	var puzzle = puzzleLoader.puzzle.sudoku; break;
		}

		var buyPuzzleInfo = '';
		buyPuzzleInfo += '<div class="buyPuzzle">';
		buyPuzzleInfo += '	<p align="justify">Denne oppgaven er en konkurranseoppgave. Ved å kjøpe denne oppgaven får du mulighet til å delta i konkurransen.</p>';
		buyPuzzleInfo += '	<p align="justify">For konkurranser som inneholder flere oppgaver, kan du også kjøpe og løse de andre oppgavene i konkurransen for å øke dine vinnersjanser.</p>';
		buyPuzzleInfo += '	<p align="justify">Betalingen skjer enkelt ved å belaste ditt mobilabonnement etter at du har bekreftet kjøpet. Du vil motta kvittering på SMS. En betalt oppgave kan løses flere ganger og vil også være tilgjengelig under «<a href="/minside/kjopshistorikk/">Min Side</a>».</p>';
		buyPuzzleInfo += '	<p>Lykke til!</p>'; 
		buyPuzzleInfo += '	<div class="puzzleData">'; 
		buyPuzzleInfo += '		<table>'; 
		buyPuzzleInfo += '			<tbody>'; 
		buyPuzzleInfo += '				<tr>'; 
		buyPuzzleInfo += '					<th>Oppgavetype</th>'; 
		buyPuzzleInfo += '					<td>'+puzzle.type+'</td>'; 
		buyPuzzleInfo += '				</tr>'; 
		buyPuzzleInfo += '				<tr>'; 
		buyPuzzleInfo += '					<th>Oppgavetittel</th>'; 
		buyPuzzleInfo += '					<td>'+puzzle.name+'</td>'; 
		buyPuzzleInfo += '				</tr>'; 
		buyPuzzleInfo += '				<tr>'; 
		buyPuzzleInfo += '					<th>Vanskelighetsgrad</th>'; 
		buyPuzzleInfo += '					<td>'+puzzle.level+'</td>'; 
		buyPuzzleInfo += '				</tr>'; 
		buyPuzzleInfo += '				<tr>'; 
		buyPuzzleInfo += '					<th>Pris</th>'; 
		buyPuzzleInfo += '					<td>'+puzzle.priceEffective+',-</td>'; 
		buyPuzzleInfo += '				</tr>'; 
		buyPuzzleInfo += '			</tbody>'; 
		buyPuzzleInfo += '		</table>'; 
		buyPuzzleInfo += '	</div>';
		buyPuzzleInfo += '	<div id="puzzleActivator">';
		buyPuzzleInfo += '		<input type="button" class="arrowButton" value="Kjøp oppgaven" onclick="puzzleLoader.ePuzzle.checkPayment();" />';
		buyPuzzleInfo += '	</div>';
		buyPuzzleInfo += '</div>';
		this.popupWindow.setBody(buyPuzzleInfo);

		var containerPosition	= this.puzzleElement.positionedOffset();
		var containerSize		= this.puzzleElement.getHeight();
		var popupSize			= this.popupWindow.popupContainer.getHeight();

		var topLeft				= (containerPosition['top'] + containerSize) - (popupSize + 95);

		this.popupWindow.setPositionXY(containerPosition['left']+55,topLeft);

		this.popupWindow.display();
	}

	this.paymentStatus = 'idle';
	this.timeoutCount = 0;

	this.checkPayment = function(paymentId) {
		if(this.paymentStatus == 'idle') {
			var activatorText = '<div class="waitPaymentProcessing">';
			activatorText += '<img src="'+puzzleLoader.domain+'/images/activity-indicator.gif"/>';
			activatorText += '<br />';
			activatorText += '<br />';
			activatorText += '<br />';
			activatorText += '<b>Vennligst vent! Kontrollerer betaling...</b><br />';
			activatorText += '<br />';
			activatorText += '<div class="disclaimer" />';
			activatorText += 'Dette kan ta noe tid. Det er ikke nødvendig å vente til siden oppdateres.<br />';
			activatorText += 'Du vil motta en SMS-kvittering når oppgaven er betalt.<br />'
			activatorText += 'Du har oversikt over betalte oppgaver på «Min Side»</a>';
			activatorText += '</div>';
			activatorText += '</div>';

			var puzzleActivator = document.getElementById('puzzleActivator');
			puzzleActivator.innerHTML = activatorText;

			this.paymentStatus = 'busy';
		}

		var URL = puzzleLoader.puzzle.baseUrl+puzzleLoader.puzzleIdentifier+'&apimode=buyPuzzle';
		var postBody = 'sVer=3.0';
		if(paymentId) postBody = postBody+'&pId='+paymentId;

		new Ajax.Request(URL, {
			method:		'POST',
			postBody:	postBody,
			onSuccess:	function(response) {
				try {
					result = JSON.parse(response.responseText);

					puzzleLoader.ePuzzle.checkPaymentResult(result);
				} catch(e) {
					switch(e.name) {
						case 'TypeError':
							puzzleLoader.puzzle.errorMessage = e.message;
						break;

						default:
							puzzleLoader.puzzle.errorMessage = 'Feil';
						break;
					}

					puzzleLoader.puzzle.setState('ERROR');
				}
			}
		});
	}

	this.checkPaymentResult = function(result) {
		switch(result.result) {
			case 'error':
				this.paymentFailed('error', result.msg);
			break;

			case 'paymentInitialized':
				setTimeout(function(){puzzleLoader.ePuzzle.checkPayment(result.pId)}, 2500);
			break;

			case 'paymentPending':
				if(this.timeoutCount >= 6) {
					this.paymentFailed('timeoutError', 'Betalingen tok for lang tid.');
				} else {
					setTimeout(function(){puzzleLoader.ePuzzle.checkPayment(result.pId)}, 5000);
				}
			break;

			case 'paymentOK':
				puzzleLoader.puzzle.puzzleBought();

				puzzle = puzzleLoader.puzzle;
				new Ajax.Request(puzzleLoader.puzzle.url, {
					method: 'GET',
					onSuccess: function(response) {
						try {
							switch(puzzleLoader.puzzleType) {
								case 'xword':
									puzzleLoader.puzzle.xWord = JSON.parse(response.responseText);
								break;

								case 'sudoku':
									puzzleLoader.puzzle.sudoku = JSON.parse(response.responseText);
								break;
							}

							puzzleLoader.ePuzzle.removeButtons();
							puzzleLoader.puzzle.addButtons();
							puzzleLoader.puzzle.setAdditionalInfo();

							puzzleLoader.ePuzzle.popupWindow.close();
						} catch(JSONError) {
							debugger;
						}
					}
				});
			break;

			case 'paymentError':
				this.paymentFailed(result.errorType, result.errorMessage);
			break;
		}
	}

	this.paymentFailed = function(errorType, errorMessage) {
		var popupWindow = puzzleLoader.ePuzzle.popupWindow;
		popupWindow.close();

		var warningWindow = new domPupup();

		warningWindow.setClassName('Warning');
		warningWindow.setCaption('Betalingsfeil');
		warningWindow.setCloseText('Lukk');
		warningWindow.setBody('Betalingen kunne ikke gjennomføres<br /><br/><b>Årsak: </b>'+errorMessage);

		warningWindow.setSizeXY(400, 100);

		var containerPosition	= this.puzzleElement.positionedOffset();
		var containerSize		= this.puzzleElement.getHeight();

		warningWindow.setPositionXY(containerPosition['left']+103,containerPosition['top']+containerSize-250);

		warningWindow.display();
	}

	this.controlListener = function(event) {
		var targetElement = Event.element(event);

		switch(event.type) {
			case 'dataavailable':
				if(event.eventName == 'user:login') {
					puzzle = puzzleLoader.puzzle;

					new Ajax.Request(puzzleLoader.puzzle.url, {
						method: 'GET',
						onSuccess: function(response) {
							try {
								switch(puzzleLoader.puzzleType) {
									case 'xword':
										puzzleLoader.puzzle.xWord = JSON.parse(response.responseText);
									break;
	
									case 'sudoku':
										puzzleLoader.puzzle.sudoku = JSON.parse(response.responseText);
									break;
								}

								puzzleLoader.ePuzzle.removeButtons();
								puzzleLoader.puzzle.addButtons();
								puzzleLoader.puzzle.setAdditionalInfo();
							} catch(JSONError) {
								debugger;
								
							}
						}
					});
				}
			break;

			case 'click':
				if(stringPart(targetElement.id,-15) == 'buyPuzzleButton') {
					this.buyPuzzleInfo();
				}
			break;
		}
	}		
}

function hex2R(h) {return parseInt((cutHex(h)).substring(0,2),16)}
function hex2G(h) {return parseInt((cutHex(h)).substring(2,4),16)}
function hex2B(h) {return parseInt((cutHex(h)).substring(4,6),16)}
function cutHex(h) {return (h.charAt(0)=="#") ? h.substring(1,7):h}

