jQuery(
	function($j)
	{
		/*******************************************************
		******************** Global variables ******************
		*******************************************************/
		var debug = false; // Enable debugging
		
		var publications = 	
		[
			{
				'id' 	: '1',
				'name' 	: 'adressa',
				'url'	: 'adressa',
				'prodId': 1,
				'profId': 6,
                                'adPath': 'jobb/stillinger'
			},
			{
				'id' 	: '2',
				'name' 	: 'avisa-st',
				'url'	: 'avisa-st',
				'prodId': 6,
				'profId': 6,
                                'adPath': 'jobb'
			},
			{
				'id' 	: '3',
				'name' 	: 'fosna-folket',
				'url'	: 'fosna-folket',
				'prodId': 6,
				'profId': 6,
                                'adPath': 'jobb'
			},
			{
				'id' 	: '4',
				'name' 	: 'hitra-froya',
				'url'	: 'hitra-froya',
				'prodId': 6,
				'profId': 6,
                                'adPath': 'jobb'
			},
			{
				'id' 	: '5',
				'name' 	: 'levangeravisa',
				'url'	: 'levangeravisa',
				'prodId': 6,
				'profId': 6,
                                'adPath': 'jobb'
			},
			{
				'id' 	: '6',
				'name' 	: 'tronderbladet',
				'url'	: 'tronderbladet',
				'prodId': 6,
				'profId': 6,
                                'adPath': 'jobb'
			},
			{
				'id' 	: '7',
				'name' 	: 'verdalingen',
				'url'	: 'verdalingen',
				'prodId': 6,
				'profId': 6,
                                'adPath': 'jobb'
			},
			{
				'id' 	: '8',
				'name' 	: 'ht',
				'url'	: 'ht',
				'prodId': 7,
				'profId': 8,
                                'adPath': 'jobb'
			},
			{
				'id' 	: '9',
				'name' 	: 'itromso',
				'url'	: 'itromso',
				'prodId': 7,
				'profId': 8,
                                'adPath': 'jobb'
			},
			{
				'id' 	: '10',
				'name' 	: 'folkebladet',
				'url'	: 'folkebladet',
				'prodId': 7,
				'profId': 8,
                                'adPath': 'jobb'
			},
			{
				'id' 	: '11',
				'name' 	: 'altaposten',
				'url'	: 'altaposten',
				'prodId': 7,
				'profId': 8,
                                'adPath': 'jobb'
			},
			{
				'id' 	: '12',
				'name' 	: 'framtidinord',
				'url'	: 'framtidinord',
				'prodId': 7,
				'profId': 8,
                                'adPath': 'jobb'
			},
			{
				'id' 	: '13',
				'name' 	: 'vol',
				'url'	: 'vol',
				'prodId': 7,
				'profId': 8,
                                'adPath': 'jobb'
			},
			{
				'id' 	: '14',
				'name' 	: 'banett',
				'url'	: 'banett',
				'prodId': 7,
				'profId': 8,
                                'adPath': 'jobb'
			},
			{
				'id' 	: '15',
				'name' 	: 'saltenposten',
				'url'	: 'saltenposten',
				'prodId': 7,
				'profId': 8,
                                'adPath': 'jobb'
			}
		];
		
		/* 
			Get publication based on publication stylesheet
			ex. <link rel="stylesheet" type="text/css" href="http://static.polarismedia.no/skins/prod/publication/avisa-st/css/avisa-st.css"/>
		*/
		var publicationId = publications[0].id; //Default: adressa
		var publicationName = publications[0].name; //Default: adressa
		var publicationUrl = publications[0].url; //Default: adressa
		var publicationProdId = publications[0].prodId; //Default: adressa
		var publicationProfId = publications[0].profId; //Default: adressa
        var publicationAdPath = publications[0].adPath; //Default: adressa
		
		$j('link').each(
			function(index)
			{
				if (this.href.indexOf("publication") > -1) 
				{
					var publicationName = this.href.slice(this.href.indexOf("/css/")+5, this.href.indexOf(".css"));
					for( var i = 0; i < publications.length; i++)
					{
						if (publications[i].name === publicationName)
						{
							publicationId = publications[i].id;
							publicationName = publications[i].name;
							publicationUrl = publications[i].url;
							publicationProdId = publications[i].prodId;
							publicationProfId = publications[i].profId;
                                                        publicationAdPath = publications[i].adPath;
							trace('Publication id: ' + publicationId);
							trace('Publication name: ' + publicationName);
							trace('Publication url: ' + publicationUrl);
							trace('Publication prodId: ' + publicationProdId);
							trace('Publication profId: ' + publicationProfId);
                            trace('Publication adPath: ' + publicationAdPath);
						}

					}
				}
			}
		);
		
		var ajaxTimeout = 10000;
		var adsPerPage = 20; //Number of job ads per page
		var curJobAdPage = 1; //Default
		var allCategories = {}; //All categories with job ads
		var selectedCategories = [];
		var rootPath = 'http://www.' + publicationUrl + '.no'; //Must be set for each publication
                var pathSeeAllAds = rootPath + '/' + publicationAdPath;
		var pathToJobAd = 'http://www.adressa.no/jobb/stillinger/';
		var baseUrl = rootPath + '/marsellus/withoutproxy?url=http://jobbfeed.webassistenten.no/jobAds%3F';
		var pageIsJobAd = false;
		var emptySearchMessage = 'Søket ga ingen treff';

		var pageSize = '%26pageSize='+adsPerPage;
		var categoryIds = '';
		var excludeCategoryIds = '';
		var countyIds = '';
		var searchQuery = '';
		var sortOrder = '';
		var pageNumber = '';
		var companyId = '';
		var mediaChannelId = '%26mediaChannelId=' + publicationId;
		var productId = '%26productId=' + publicationProdId;
		var profilerteStillingerId = '%26productId=' + publicationProfId;

		/*******************************************************
		******************** Global functions ******************
		*******************************************************/
		// Retrieves JSON-data based on input url and creates list of job ads
		function displayAds(url)
		{
			// Ref. to element containing list of job ads
			var contentDiv = $j('#jobAdsContainer');
			// Show preloader .gif while loading 
			insertPreloader(contentDiv);
			// Variable to store markup for job ad list
			var markup = '';
			
			// Go to selected page when clicked in paginator
			function gotoPage(page)
			{
				pageNumber = '%26page=' + page;
				contentDiv.css('height', contentDiv.outerHeight(true));
				displayAds(getCurrentUrl());
			}
			
			$j.ajax(
			{
				url: url,
				timeout: ajaxTimeout,
				success: function(data) 
				{
					if (data)
					{
						/* Check if returned data contains any records */
						if (data.totalRecords > 0)
						{
							curJobAdPage = data.page;
							var numOfPages = data.numOfPages;
							var numOfAds = data.records.length;
														
							// Loop through the ads and create markup for each job ad
							for(x = 0; x < numOfAds; x++)
							{
								// Create style classes for current ad
								var categoryClasses = '';
								for(i = 0; i < data.records[x].categories.length; i++)
								{
									categoryClasses += 'category' + data.records[x].categories[i].categoryId + ' ';
								}
								
								var city = '';
								if (data.records[x].address.city !== '')
								{
									city = '<div class="location"><strong>Sted: </strong>'+data.records[x].address.city+'</div>';
								}
								markup +=
									'<li class="jobAd ' + categoryClasses + '">'+
										'<img src="'+formatLogoUrl(data.records[x].company.companyLogoPath)+'" alt="'+data.records[x].company.name+'" />' +
										'<div class="jobInfo">'+
											'<div class="company">'+data.records[x].company.name+' s&oslash;ker:</div>'+
											'<h3 class="position"><a href="'+pathToJobAd+'?jobAdId='+data.records[x].jobAdId+'">'+data.records[x].adTitle+'</a></h3>'+
											'<div class="deadline">S&oslash;knadsfrist: '+parseDate(data.records[x].validTo)+'</div>'+
											city +
										'</div>'+
										'<div class="about">'+
											data.records[x].adTeaserText +
										'</div>'+
									'</li>';
							}
							// If no ads, display no hits message
							if (markup === '')
							{
								markup = '<li style="margin-bottom: 20px;">' + emptySearchMessage + '</li>';
							}

							//Insert markup and animate height of container
							contentDiv.css('height', contentDiv.outerHeight(true)).html('<ul>'+markup+'</ul>').animate({height: $j('#jobAdsContainer ul').outerHeight(true) + verticalPaddingAndMargin(contentDiv)}, 250,
								function()
								{
									$j('ul', this).fadeTo(250, 1);
								}
							);

							//Create paginator if number of pages > 1
							if (numOfPages > 1)
							{
								$j('.jobPaginator').addClass('active');
								var prevLink = '';
								var nextLink = '';
								var allPages = '';

								//"Previous page" link
								if (curJobAdPage > 1)
								{
									prevLink = '<li class="prev">Forrige side</li>';
								}
								else
								{
									prevLink = '<li class="prev inactive">Forrige side</li>';
								}

								//"Next page" link
								if (curJobAdPage < numOfPages)
								{
									nextLink = '<li class="next">Neste side</li>';
								}
								else
								{
									nextLink = '<li class="next inactive">Neste side</li>';
								}

								//"Directly to page" link
								for(y = 0; y < numOfPages; y++)
								{
									pageNum = y + 1;
									classes = 'pageLink page'+pageNum;
									if (pageNum === curJobAdPage)
									{
										classes += ' active';
									}
									allPages += '<li class="'+classes+'">' + pageNum + '</li>';
								}

								//Insert paginator markup
								$j('.jobPaginator').html('<ul>' + prevLink + allPages + nextLink + '</ul>');

								//Paginator on click handlers: "directly to page" links
								$j('.pageLink').click(
									function()
									{
										var gotoPageNum = $j(this).text();
										if (gotoPageNum !== curJobAdPage)
										{
											gotoPage(gotoPageNum);
										}
									}
								);

								//Paginator on click handler: "previous page" link
								$j('.jobPaginator .prev').click(
									function()
									{
										if (curJobAdPage > 1)
										{
											gotoPage(curJobAdPage - 1);
										}
									}
								);

								//Paginator on click handler: "next page" link
								$j('.jobPaginator .next').click(
									function()
									{
										if (curJobAdPage < numOfPages)
										{
											gotoPage(curJobAdPage + 1);
										}
									}
								);
							}
						}
						else
						{
							$j('#jobAdsContainer').html('<span class="noHits">' + emptySearchMessage + '</span>');
						}
					}
					else 
					{
						hideElement('#jobAdsContainer');
					}
				}
			});
		}
		
		// Creates <ul>-list with all available categories
		function createCategoryList(url, numberOfColumns, hideList)
		{
			$j.ajax(
			{
				url: url,
				timeout: ajaxTimeout,
				success: 
					function(data) 
					{
						if (data)
						{
							trace('hello world');
							var markup = '';
							var tempMarkup = '';
							var slash = new RegExp('/', 'g');
							var numOfAds = 0;
							var numOfCats = data.records.length;
							var categoryList = [];
							
							var headline = '<h3 id="headlineAllCategories"><span class="headline">Kategorier</span> <span class="showAll">Velg alle</span></h3>';
	
							for(x = 0; x < numOfCats; x++)
							{
								// Only show categories with job ads
								if (data.records[x].countedAds > 0)
								{
									tempMarkup =
										'<li>'+
											'<input type="checkbox" name="categoryId" value="'+data.records[x].categoryId+'" />'+
											'<a href="'+pathToJobAd+'?categoryId='+data.records[x].categoryId+'">'+data.records[x].categoryName.replace(slash, ' / ')+'</a>'+
											'<span>('+data.records[x].countedAds+')</span>'+
										'</li>';
									allCategories[data.records[x].categoryId] = data.records[x].categoryName;
									numOfAds += data.records[x].countedAds;
									categoryList.push(tempMarkup);
								}
							}
	
							numOfCats = categoryList.length;
							// Default: all categories in a single column
							var numOfCols = 1;
							// If numberOfColumns is specified, use this value instead. 
							if (numberOfColumns > 0 && numberOfColumns < numOfCats)
							{
								numOfCols = numberOfColumns;
							}
	
							var adsPerCol = Math.ceil(numOfCats / numOfCols);
							
							for(y = 0; y < numOfCats; y++)
							{
								markup += categoryList[y];
								if (y > 0 && y < (numOfCats-1) && (y+1)%adsPerCol === 0)
								{
									markup += '</ul><ul class="catList">';
								}
							}
							
							var expanded = 'expanded';
							if (hideList) 
							{
								expanded = '';	
							}
							
							markup = '<div class="' + expanded + '">' + headline + '<ul class="first catList">' + markup + '</ul></div>';
							$j("#jobCategoryList").html(markup);
							displaySelectedCategories();
						}
					}
				}
			);
		}
		
		// Creates <ul>-list with checkboxes for all available counties
		function createCountyList(url, numberOfColumns, hideList)
		{
			$j.ajax(
			{
				url: url,
				timeout: ajaxTimeout,
				success: function(data) 
				{
					if (data)
					{
						var markup = '';
						var tempMarkup = '';
						var slash = new RegExp('/', 'g');
						var numOfAds = 0;
						var numOfCats = data.records.length;
						var countyList = [];
						
						var headline = '<h3 id="headlineAllCounties"><span class="headline">Fylker</span> <span class="showAll">Velg alle</span></h3>';

						for(x = 0; x < numOfCats; x++)
						{
							//Only show categories with job ads
							if (data.records[x].countedAds > 0)
							{ 
								tempMarkup =
									'<li>'+
										'<input type="checkbox" name="countyId" value="'+data.records[x].countyId+'" />'+
										'<a href="'+pathToJobAd+'?countyId='+data.records[x].countyId+'">'+data.records[x].countyName.replace(slash, ' / ')+'</a>'+
										'<span>('+data.records[x].countedAds+')</span>'+
									'</li>';
								numOfAds += data.records[x].countedAds;
								countyList.push(tempMarkup);
							}
						}

						numOfCats = countyList.length;
						var numOfCols = 1;
						
						// If numberOfColumns is specified, use this value instead. 
						if (numberOfColumns > 0 && numberOfColumns < numOfCats)
						{
							numOfCols = numberOfColumns;
						}
						
						var adsPerCol = Math.ceil(numOfCats / numOfCols);
						for(y = 0; y < numOfCats; y++)
						{
							markup += countyList[y];
							if (y > 0 && y < (numOfCats-1) && (y+1)%adsPerCol === 0)
							{
								markup += '</ul><ul class="countyList">';
							}
						}
						
						var expanded = 'expanded';
						if (hideList) 
						{
							expanded = '';	
						}
						markup = '<div class="' + expanded + '">' + headline + '<ul class="first countyList">' +markup+ '</ul></div>';
						$j("#jobCountyList").html(markup);
					}
				}
			});
		}
		
		// Insert selected categories into search result box (#selectedCategories)
		function displaySelectedCategories()
		{
			markup = '';
			var numOf = selectedCategories.length;
			if (numOf > 0)
			{
				for(x = 0; x < numOf; x++) 
				{
					markup += '<li><a rel="' + selectedCategories[x] + '">' + allCategories[selectedCategories[x]] + '</a></li>';
				}
			}
			else 
			{
				var y = '';
				for(y in allCategories) 
				{
					if (allCategories.hasOwnProperty(y))
					{
						markup += '<li><a rel="' + y + '">' + allCategories[y] + '</a></li>';
					}
				}
			}
			$j('#selectedCategories').html(markup);
		}

		// Insert markup in div#rubrikkannonse
		function rubrikkannonse(url)
		{
			insertPreloader($j('#rubrikkannonse'));
			$j.ajax(
			{
				url: url,
				timeout: ajaxTimeout,
				success: function(data) 
				{
					if (data)
					{
						// This element is set to "display: none" as default
						$j('#rubrikkannonse').show();
						var logo = (data.records[0].company.companyLogoPath) ? '<img class="logo" src="'+formatLogoUrl(data.records[0].company.companyLogoPath)+'" alt="'+data.records[0].company.name+'" />' : '';
						var adTitle = (data.records[0].adTitle) ? '<h2>' + data.records[0].adTitle + '</h2>' : '';
						var companyProfile = (data.records[0].companyProfile) ? '<p class="companyProfile">' + data.records[0].companyProfile + '</p>' : '';
						var applyLink = (data.records[0].applicationInfo.url) ? '<a class="apply" href="' + data.records[0].applicationInfo.url + '">Søk på stillingen</a>' : '';						
						// Job ad content. rowWrap returns a html table row with the input data.
						var companyName = rowWrap('Firma', data.records[0].company.name) || '';
						var contacts = rowWrap('Kontakt', data.records[0].company.contacts) || '';
						var hoursText = rowWrap('Omfang', data.records[0].hoursText) || '';
						var contractText = rowWrap('Varighet', data.records[0].contractText) || '';
						var sectorText = rowWrap('Sektor', data.records[0].sectorText) || '';
						var expiration = rowWrap('Søknadsfrist', parseDate(data.records[0].expiration)) || '';
						var markup =
							logo +
							companyProfile +
							adTitle +
							applyLink +
							data.records[0].adText +
							'<table cellpadding="0" cellspacing="0" border="0"><tbody>' +
								companyName +
								contacts +
								hoursText +
								contractText +
								sectorText +
								expiration +
							'</tbody></table>' +
							applyLink +
							'<p class="moreAds"><a href="?companyId=' + data.records[0].company.companyId + '">Andre stillinger fra ' + data.records[0].company.name + '</a></p>';
						$j('#rubrikkannonse').html(markup);
					}
					else
					{
						hideElement('#rubrikkannonse');
					}
				}
			});
			
			// Return an html table row if "value" !empty
			function rowWrap(key, value)
			{
				if (value)
				{
					return '<tr><td class="key">' + key + ':</td><td class="value">' + value + '</td></tr>';
				}
			}
		}

		/* Insert markup in "sisteStillinger"-module */
		function sisteStillinger(url)
		{
			var contentDiv = $j('#sisteStillinger .content');
			insertPreloader(contentDiv);
			var maxNum = 5;
			$j.ajax(
			{
				url: url,
				timeout: ajaxTimeout,
				success: function(data) 
				{
					if (data)
					{
						totalRecords = data.totalRecords;
						// Hide module if there are no job ads to display
						if (totalRecords === 0)
						{
							$j('#sisteStillinger').hide();
						}
						else
						{
							var markup = '';
							var length = Math.min(maxNum, data.records.length);
							for(x = 0; x < length; x++)
							{
								markup +=
									'<li>'+
										'<h3><a href="'+pathToJobAd+'?jobAdId='+data.records[x].jobAdId+'">'+data.records[x].adTitle+'</a></h3><p>'+data.records[x].company.name+'</p>'+
									'</li>';
							}
							contentDiv.html('<ul>'+markup+'</ul>');
						}
					}
					// If no data, hide the module
					else
					{
						hideElement('#sisteStillinger');
					}
				}
			});
		}

		/* Insert markup in "rekrutteringsselskaper"-module */
		function rekrutteringsselskaper(url, companies, ads, mini)
		{
			var contentDiv ='';
			var baseDivId = '';
			if (mini)
			{
				contentDiv = $j('#rekrutteringsselskaperMin .content');
				baseDivId = '#rekrutteringsselskaperMin';
			}
			else
			{
				contentDiv = $j('#rekrutteringsselskaper .content');
				baseDivId = '#rekrutteringsselskaper';
			}
			insertPreloader(contentDiv);

			var adsPerPage = companies; // number of ads to display per "page"
			var currentPage = 0; //default
			var totalRecords = 0;
			var markupArray = [];
			var cssClass = '';
			
			$j.ajax(
			{
				url: url,
				timeout: ajaxTimeout,
				success: function(data) 
				{
					if (data)
					{
						totalRecords = data.totalRecords;
	
						if (totalRecords === 0)
						{
							$j(baseDivId).hide();
						}
						else 
						{
							var length = data.records.length;
							for(x = 0; x < length; x++)
							{
								var tempMarkup = '';
								tempMarkup += '<a href="'+data.records[x].company.companyUrl+'"><img src="'+formatLogoUrl(data.records[x].company.companyLogoPath)+'" alt="'+data.records[x].company.name+'" /></a>';
								var numOfAds = Math.min(ads, data.records[x].jobAds.length);
								for(y = 0; y < numOfAds; y++)
								{
									tempMarkup += '<h3><a href="'+pathToJobAd+'?jobAdId='+ data.records[x].jobAds[y].jobAdId +'">'+ data.records[x].jobAds[y].adTitle +'</a></h3><p>'+ data.records[x].jobAds[y].company.name +'</p>';
								}
								if (x%2 === 0)
								{
									cssClass = 'even';
								}
								else
								{
									cssClass = 'odd';
								}
								markupArray.push('<li class="'+cssClass +'">' + tempMarkup + '<a class="showMore" href="'+pathToJobAd+'?companyId='+data.records[x].company.companyId+'">Se flere stillinger</a></li>');
							}
	
							var numOfPages = Math.ceil(totalRecords / adsPerPage);
	
							//Insert markup and animate height of container
							updateContainer(contentDiv, currentPage, adsPerPage, totalRecords, markupArray, baseDivId, numOfPages);
						}
					}
					else
					{
						hideElement(baseDivId);
					}
				}
			});
		}

		/* Insert markup in "profilerteLederstillinger"-module */
		function profilerteLederstillinger(url)
		{
			var baseDivId = '#profilerteLederstillinger';
			var contentDiv = $j('#profilerteLederstillinger .content'); //selector that will be used multiple times
			insertPreloader(contentDiv);
			var adsPerPage = 5; // number of ads to display per "page"
			var currentPage = 0; //default
			var totalRecords = 0;
			var markupArray = [];
			
			$j.ajax(
			{
				url: url,
				timeout: ajaxTimeout,
				success: function(data) 
				{
					//if (data !== null)
					if (data)
					{
						totalRecords = data.totalRecords;

						if (totalRecords === 0)
						{
							$j(baseDivId).hide();
						}
						else 
						{
							//Randomize ad-order
							data.records.sort(randomSort);
							
							var logoMarkup = '';
							for(x = 0; x < totalRecords; x++)
							{
								logoMarkup = '<a href="'+pathToJobAd+'?jobAdId='+data.records[x].jobAdId+'"><img src="'+formatLogoUrl(data.records[x].company.companyLogoPath)+'" alt="" /></a>';
								markupArray.push(
									'<li>'+
										logoMarkup+
										'<h3><a href="'+pathToJobAd+'?jobAdId='+data.records[x].jobAdId+'">'+data.records[x].adTitle+'</a></h3>'+
										'<p>'+data.records[x].adTeaserText+'</p>'+
									'</li>');
								logoMarkup = '';
							}

							var numOfPages = Math.ceil(totalRecords / adsPerPage);

							//Insert markup and animate height of container
							updateContainer(contentDiv, currentPage, adsPerPage, totalRecords, markupArray, baseDivId, numOfPages);
						}
					}
					else
					{
						hideElement(baseDivId);
					}
				}
			});
		}

		/* Insert markup in "profilerteStillinger"-module */
		function profilerteStillinger(url)
		{
			var baseDivId = '#profilerteStillinger';
			var contentDiv = $j('#profilerteStillinger .content'); //selector that will be used multiple times
			insertPreloader(contentDiv);
			var adsPerPage = 5; // number of ads to display per "page"
			var currentPage = 0; //default
			var totalRecords = 0;
			var markupArray = [];
			$j.ajax(
			{
				url: url,
				timeout: ajaxTimeout,
				success: function(data) 
				{
					if (data)
					{
						totalRecords = data.totalRecords;

						if (totalRecords === 0)
						{
							$j(baseDivId).hide();
						}
						else 
						{
							//Randomize ad-order
							data.records.sort(randomSort);
							
							var logoMarkup = '';
							for(x = 0; x < totalRecords; x++)
							{
								logoMarkup = '<a href="'+pathToJobAd+'?jobAdId='+data.records[x].jobAdId+'"><img src="'+formatLogoUrl(data.records[x].company.companyLogoPath)+'" alt="" /></a>';
								markupArray.push(
									'<li>'+
										logoMarkup+
										'<h3><a href="'+pathToJobAd+'?jobAdId='+data.records[x].jobAdId+'">'+data.records[x].adTitle+'</a></h3>'+
										'<p>'+data.records[x].adTeaserText+'</p>'+
									'</li>');
								logoMarkup = '';
							}
					
							var numOfPages = Math.ceil(totalRecords / adsPerPage);
							
							//Insert markup and animate height of container
							updateContainer(contentDiv, currentPage, adsPerPage, totalRecords, markupArray, baseDivId, numOfPages);
						}
					}
					else
					{
						hideElement(baseDivId);
					}
				}
			});
		}

		/* Insert markup in "profilerteStillinger320"-module */
		function profilerteStillinger320(url) {
			var baseDivId = '#profilerteStillinger320';
			var contentDiv = $j('#profilerteStillinger320 .content'); //selector that will be used multiple times
			insertPreloader(contentDiv);
			var adsPerPage = 5; // number of ads to display per "page"
			var currentPage = 0; //default
			var totalRecords = 0;
			var markupArray = [];
			
			$j.ajax(
			{
				url: url,
				timeout: ajaxTimeout,
				success: function(data) 
				{
					if (data)
					{
						totalRecords = data.totalRecords;

						if (totalRecords === 0)
						{
							$j(baseDivId).hide();
						}
						else 
						{
							//Randomize ad-order
							data.records.sort(randomSort);

							var logoMarkup = '';
							for(x = 0; x < totalRecords; x++)
							{
								logoMarkup = '<a href="'+pathToJobAd+'?jobAdId='+data.records[x].jobAdId+'"><img src="'+formatLogoUrl(data.records[x].company.companyLogoPath)+'" alt="" /></a>';
								markupArray.push(
									'<li>'+
										logoMarkup+
										'<h3><a href="'+pathToJobAd+'?jobAdId='+data.records[x].jobAdId+'">'+data.records[x].adTitle+'</a></h3>'+
										'<p>'+data.records[x].adTeaserText+'</p>'+
									'</li>');
								logoMarkup = '';
							}

							var numOfPages = Math.ceil(totalRecords / adsPerPage);

							//Insert markup and animate height of container
							updateContainer(contentDiv, currentPage, adsPerPage, totalRecords, markupArray, baseDivId, numOfPages);
						}
					}
					else
					{
						hideElement(baseDivId);
					}
				}
			});
		}

		function updateContainer(contentDiv, currentPage, adsPerPage, totalRecords, markupArray, baseDivId, numOfPages)
		{
			insertPreloader(contentDiv);
			var start =  currentPage * adsPerPage;
			var end = Math.min(totalRecords, ((currentPage * adsPerPage) + adsPerPage));
			var markup = '';
			for(y = start; y < end; y++)
			{
				markup += markupArray[y];
			}
			contentDiv.css('height', contentDiv.height()).html('<ul>'+markup+'</ul>').animate({height: $j(baseDivId + ' .content ul').outerHeight(true) + verticalPaddingAndMargin(contentDiv)}, 250,
				function()
				{
					$j('ul', this).animate({opacity: 1}, 250);
					//Create paginator if number of pages > 1
					var showAll = '';
					if (totalRecords > adsPerPage) 
					{
						// Add link from "Profilerte stillinger" to adressa.no/jobb/stillinger (show all job ads)
						if (baseDivId === '#profilerteStillinger')
						{
							showAll = '<a href="'+pathSeeAllAds+'">Se alle stillinger</a>';
						}
	
						var prevLink = '';
						if (currentPage > 0)
						{
							prevLink = '<span class="prev">Forrige ' + adsPerPage + '</span>';
						}
						else
						{
							prevLink = '<span class="prev inactive">Forrige ' + adsPerPage + '</span>';
						}
	
						var nextLink = '';
						if (currentPage < (numOfPages - 1))
						{
							nextLink = '<span class="next">Neste ' + adsPerPage + '</span>';
						}
						else
						{
							nextLink = '<span class="next inactive">Neste ' + adsPerPage + '</span>';
						}
	
						$j(baseDivId + ' .footer').html(prevLink +' | '+ nextLink + showAll);

						//Previous page
						if (currentPage > 0)
						{
							$j(baseDivId + ' .footer .prev').click(
								function()
								{
									if (!$j(this).hasClass('disabled')) 
									{
										$j(this).addClass('disabled');
										$j(baseDivId + ' .content ul').fadeTo(200, 0, 
											function()
											{
												currentPage -= 1;
												contentDiv.css('height', contentDiv.height());
												$j('ul', contentDiv).animate({opacity: 0}, 250, 
													function()
													{
														updateContainer(contentDiv, currentPage, adsPerPage, totalRecords, markupArray, baseDivId, numOfPages);
													}
												);
											}
										);
									}
								}
							);
						}

						//Next page
						if (currentPage < (numOfPages - 1))
						{
							$j(baseDivId + ' .footer .next').click(
								function() 
								{
									if (!$j(this).hasClass('disabled'))
									{
										$j(this).addClass('disabled');
										$j(baseDivId + ' .content ul').fadeTo(200, 0, 
											function()
											{
												currentPage += 1;
												contentDiv.css('height', contentDiv.height());
												$j('ul', contentDiv).animate({opacity: 0}, 250, 
													function()
													{
														updateContainer(contentDiv, currentPage, adsPerPage, totalRecords, markupArray, baseDivId, numOfPages);
													}
												);
											}
										);
									}
								}
							);
						}
					}
					else 
					{
						// Add link from "Profilerte stillinger" to adressa.no/jobb/stillinger (show all job ads)
						if (baseDivId === '#profilerteStillinger') 
						{
							showAll = '<a href="'+pathToJobAd+'">Se alle stillinger</a>';
							$j(baseDivId + ' .footer').html(showAll);
						}
					}
				}
			);
		}
	
		/*******************************************************
		******************* Helper functions *******************
		*******************************************************/
		
		// Hides input element. Makes it easy to specify how elements should be hidden.
		function hideElement(element)
		{
			$j(element).slideUp(250);
		}
		
		// Checks all checkboxes inside input element
		function selectAllCheckboxes(element)
		{
			element.find('input:checkbox').each(
				function()
				{
					this.checked = true;
				}
			);
		}
		
		// Unchecks all checkboxes inside input element
		function deSelectAllCheckboxes(element)
		{
			element.find('input:checkbox').each(
				function()
				{
					this.checked = false;
				}
			);
		}
		
		// Build and return url to retrieve JSON with job ad data
		function getCurrentUrl()
		{
			return baseUrl + pageSize + categoryIds + excludeCategoryIds + searchQuery + sortOrder + pageNumber + companyId + productId + countyIds/* + mediaChannelId*/;
		}
	
		// Remove class .current from all search buttons, then add class .current to the search button with id===btnId
		function setActiveSearchBtn(btnId)
		{
			$j('#jobSort li').removeClass("current");
			$j('#'+btnId).addClass("current");
			//activeSortBtnId = btnId;
		}

		// If input format is YYYY-MM-DD HH:MM:SS - returns  DD. monthName YYYY
		// Else returns the input param (or empty string if no param)
		function parseDate(dateTime)
		{
			var returnValue = '';
			if ( typeof(dateTime) !== 'undefined')
			{
				returnValue = dateTime;
			}
			
			function isANumber(input)
			{
				return !isNaN(input - 0)	
			}
			
			try
			{
				var trimmedDateTime = dateTime.slice(0, dateTime.indexOf(" ")).split('-');
				
				if (isANumber(trimmedDateTime[0]) && isANumber(trimmedDateTime[1]) && isANumber(trimmedDateTime[2]))
				{
					var months = ['januar', 'februar', 'mars', 'april', 'mai', 'juni', 'juli', 'august', 'september', 'oktober', 'november', 'desember'];
					var day = trimmedDateTime[2];
					var month = trimmedDateTime[1];
					var year = trimmedDateTime[0];
					returnValue = day+'. '+ months[month - 1] +' '+year;
				}
			}
			catch(err){}
			
			return returnValue;
		}
	
		// Inserts empty div with class .preLoader. Use CSS to style.
		function insertPreloader(selector)
		{
			selector.html('<div class="preLoader">Laster...</div>');
		}
	
		// Returns the sum of the vertical padding and margin of the input element as a number
		function verticalPaddingAndMargin(element)
		{
			var paddingTop = element.css('padding-top').replace('px', '');
			var paddingBottom = element.css('padding-bottom').replace('px', '');
			var marginTop = element.css('margin-top').replace('px', '').replace('auto', '');
			var marginBottom = element.css('margin-bottom').replace('px', '').replace('auto', '');
			var paddingAndMargin = Number(paddingTop) + Number(paddingBottom) + Number(marginTop) + Number(marginBottom);
			return paddingAndMargin;
		}
	
		//Sort function: randomize
		function randomSort(a,b)
		{
			// Get a random number between 0 and 10
			var temp = parseInt(Math.random()*10, 10);
			// Get 1 or 0, whether temp is odd or even
			var isOddOrEven = temp%2;
			// Get +1 or -1, whether temp greater or smaller than 5
			var isPosOrNeg = temp>5 ? 1 : -1;
			// Return -1, 0, or +1
			return(isOddOrEven*isPosOrNeg);
		}
		
		//Format logo url (replaces ? and & with %3F and %26)
		function formatLogoUrl(logoUrl)
		{
			var newUrl = '';
			if (logoUrl !== null)
			{
				newUrl = rootPath + '/marsellus/withoutproxy?url='+logoUrl.replace('?','%3F').replace('&', '%26');
			}
			return newUrl;
		}
		
		// Output to console if possible, else use alert
		function trace(msg, meta)
		{
			if (debug)
			{
				if (typeof(meta) !== 'undefined')
				{
					meta = meta + ': ';	
				}
				else
				{
					meta = '';	
				}
				if (this.console && typeof console.log !== 'undefined')
				{
					console.log(meta + msg);
				}
				else
				{
					alert(meta + msg);
				}
			}
        }
		
		/*******************************************************
		******************** Event handlers ********************
		*******************************************************/
		// Sort buttons on click
		$j("#btnPublished a").click(
			function()
			{
				setActiveSearchBtn($j(this).parent().attr('id'));
				sortOrder = '%26sortOrder=validFrom';
				displayAds(getCurrentUrl());
			}
		);
		$j("#btnTitle a").click(
			function()
			{
				setActiveSearchBtn($j(this).parent().attr('id'));
				sortOrder = '%26sortOrder=adTitle';
				displayAds(getCurrentUrl());
			}
		);
		$j("#btnCompany a").click(
			function() 
			{
				setActiveSearchBtn($j(this).parent().attr('id'));
				sortOrder = '%26sortOrder=company';
				displayAds(getCurrentUrl());
			}
		);
		
		// Show/hide categories
		$j('#headlineAllCategories .headline').live('click',
			function()
			{
				if ($j('#headlineAllCategories').parent().hasClass('expanded'))
				{
					$j('.catList').slideUp(250);
					$j('#headlineAllCategories').parent().removeClass('expanded');
				}
				else
				{
					$j('.catList').slideDown(250);
					$j('#headlineAllCategories').parent().addClass('expanded');
				}
			}
		);
		
		// Select all categories on click
		$j('#headlineAllCategories .showAll').live('click',
			function()
			{
				selectAllCheckboxes($j('#jobCategoryList'));
			}
		);
		
		// Show/hide counties
		$j('#headlineAllCounties .headline').live('click',
			function()
			{
				if ($j('#headlineAllCounties').parent().hasClass('expanded'))
				{
					$j('.countyList').slideUp(250);
					$j('#headlineAllCounties').parent().removeClass('expanded');
				}
				else
				{
					$j('.countyList').slideDown(250);
					$j('#headlineAllCounties').parent().addClass('expanded');
				}
			}
		);
		
		// Select all counties
		$j('#headlineAllCounties .showAll').live('click',
			function()
			{
				selectAllCheckboxes($j('#jobCountyList'));
			}
		);
		
		/*******************************************************
		************************* Init *************************
		*******************************************************/
		// For each module, check if specified element exists. If true, call associated function with URL to JSON as input.
		// "Siste stillinger"-module
		if ($j('#sisteStillinger').length) 
		{
			sisteStillinger(baseUrl+'sortOrder=datereg%26pageSize=5');
			trace('Siste stillinger url: ' + baseUrl+'sortOrder=datereg%26pageSize=5');
		}
		// "Rekrutteringsselskaper"-module
		if ($j('#rekrutteringsselskaper').length)
		{
			rekrutteringsselskaper(rootPath + '/marsellus/withoutproxy?url=http://jobbfeed.webassistenten.no/agencyListing%3FadsPerAgency=5', 10, 3, false);
			trace('Rekrutteringsselskaper: ' + rootPath + '/marsellus/withoutproxy?url=http://jobbfeed.webassistenten.no/agencyListing%3FadsPerAgency=5');
		}
		// "Rekrutteringsselskaper"-module (small version)
		if ($j('#rekrutteringsselskaperMin').length)
		{
			rekrutteringsselskaper(rootPath + '/marsellus/withoutproxy?url=http://jobbfeed.webassistenten.no/agencyListing%3FadsPerAgency=5', 2, 1, true);
			trace('Rekrutteringsselskaper liten versjon: ' + rootPath + '/marsellus/withoutproxy?url=http://jobbfeed.webassistenten.no/agencyListing%3FadsPerAgency=5');
		}
		// "Profilerte stillinger"-module
		//productId=8: Annonser som skal inn på HTG's profilerte stilling karuseller
		//mediaChannelId must be included in URL to retrieve only "profilerte stillinger" for this publication
		if ($j('#profilerteStillinger').length)
		{
			profilerteStillinger(baseUrl + 'pageSize=1000%26sortOrder=random' + profilerteStillingerId + mediaChannelId);
			trace('Profilerte stillinger: ' + baseUrl + 'pageSize=1000%26sortOrder=random' + profilerteStillingerId + mediaChannelId);
		}
		// "Profilerte stillinger"-module (to be used in #centerContainer)
		if ($j('#profilerteStillinger320').length)
		{
			profilerteStillinger320(baseUrl + 'pageSize=1000%26sortOrder=random' + profilerteStillingerId + mediaChannelId);
			trace('Profilerte stillinger 320-modul: ' + baseUrl + 'pageSize=1000%26sortOrder=random' + profilerteStillingerId + mediaChannelId);
		}
		// "Profilerte lederstillinger"-module
		if ($j('#profilerteLederstillinger').length)
		{
			profilerteLederstillinger(baseUrl + 'pageSize=1000%26categoryId=1%26sortOrder=random' + profilerteStillingerId + mediaChannelId);
			trace('Profilerte lederstillinger: ' + baseUrl + 'pageSize=1000%26categoryId=1%26sortOrder=random' + profilerteStillingerId + mediaChannelId);
		}
		// Create and insert list of categories and counties
		if ($j('#jobSearch').length)
		{
			createCategoryList(rootPath + '/marsellus/withoutproxy?url=http://jobbfeed.webassistenten.no/categories%3F' + productId, 1, false);
			createCountyList(rootPath + '/marsellus/withoutproxy?url=http://jobbfeed.webassistenten.no/categories/countytree%3F' + productId, 1, true);
			trace('Category list: ' + rootPath + '/marsellus/withoutproxy?url=http://jobbfeed.webassistenten.no/categories%3F' + productId);
			trace('County list: ' + rootPath + '/marsellus/withoutproxy?url=http://jobbfeed.webassistenten.no/categories/countytree%3F' + productId);
		}
		// "Rubrikkannonse"
		if ($j('#rubrikkannonse').length) 
		{
			// If URL contains jobAdId => show the complete job ad and hide all elements related to search results (#jobSort, #jobSortHeader, #jobAdsContainer)
			var startIndex = window.location.href.indexOf('jobAdId');
			if (startIndex > -1) 
			{
				var jobAdId = window.location.href.slice(startIndex);
				$j('#jobSortHeader').css('display','none'); //Hide when showing "rubrikkannonse"
				$j('#jobSort').css('display','none'); //Hide when showing "rubrikkannonse"
				$j('#jobAdsContainer').css('display','none'); //Hide when showing "rubrikkannonse"
				if (jobAdId.indexOf('&') > -1) 
				{
					jobAdId = jobAdId.slice(0, jobAdId.indexOf('&'));
				}
				pageIsJobAd = true;
				rubrikkannonse(rootPath + '/marsellus/withoutproxy?url=http://jobbfeed.webassistenten.no/jobad%3F' + jobAdId);
			}
		}
		
		// Check if element #jobSortHeader exists
		if ($j('#jobSortHeader').length)
		{
			var urlCategories = [], hash;
			// Check if url contains parameters
			if (window.location.href.indexOf('?') > -1)
			{
				// Get part of url behind the "?" and create array with each key/value-pair
				var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
				// Var to store 1 or more categoryIds
				//var tempCat = '';
				categoryIds = '';
				countyIds = '';
				for(i = 0; i < hashes.length; i++)
				{
					// Get key/value-pair
					hash = hashes[i].split('=');
					// Set values for the url-params
					switch(hash[0])
					{
						case 'categoryId':
							categoryIds += '%26categoryId='+hash[1];
							selectedCategories.push(hash[1]);
							break;
						case 'excludeCategoryId':
							excludeCategoryIds += '%26excludeCategoryId='+hash[1];
							//selectedCategories.push(hash[1]);
							break;
						case 'query':
							searchQuery = '%26query='+encodeURI(hash[1]);
							break;
						case 'sortOrder':
							sortOrder = '%26sortOrder='+hash[1];
							break;
						case 'page':
							pageNumber = '%26page='+hash[1];
							break;
						case 'companyId':
							companyId = '%26companyId='+hash[1];
							break;
						case 'countyId':
							countyIds += '%26countyId='+hash[1];
							break;
					}
				}
			}
			// Display list of ads if the page isn't a specific job ad
			if (!pageIsJobAd)
			{
				displayAds(getCurrentUrl());
			}
		}
	}
);
