if (typeof ak == 'undefined') {
	var ak = {};
}

ak.logger={};
ak.logger.enabled=document.location.search.match(/log=1|debug=1/)!=null || document.location.hostname.match(/dev$/) != null;

ak.logger.error=function(msg){
	if(ak.logger.enabled&&typeof console!='undefined'&&typeof console.error!='undefined'){
		if(msg instanceof Array){
			try {
				console.error.apply(this, msg);
			} catch (ex) {
				console.error(msg);
			}
		}else{
			console.error(msg);
		}
	}
}

ak.logger.info=function(msg){
	if(ak.logger.enabled&&typeof console!='undefined'&&typeof console.info!='undefined'){
		if(msg instanceof Array){
			try {
				console.info.apply(this, msg);
			} catch (ex) {
				console.info(msg);
			}
		}else{
			console.info(msg);
		}
	}
}
ak.logger.debug=function(msg){
	if(ak.logger.enabled&&typeof console!='undefined'&&typeof console.debug!='undefined'){
		if(msg instanceof Array){
			try {
				console.debug.apply(this,msg);
			} catch(ex) {
				console.debug(msg);
			}
		} else {
			console.debug(msg);
		}
	}
}


String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g,"");
}
String.prototype.ltrim = function() {
	return this.replace(/^\s+/,"");
}
String.prototype.rtrim = function() {
	return this.replace(/\s+$/,"");
}

/**
 * return this string correct to the given decimal places
 * @param int dp decimal places
 */
String.prototype.numFormat = function(dp) {
	var val = parseFloat(this);
	if (isNaN(val)) {
		val = 0.0;
	} 
	return val.toFixed(dp);
}

Number.prototype.numFormat = function(dp) {
	var val = parseFloat(this);
	if (isNaN(val)) {
		val = 0.0;
	} 
	return val.toFixed(dp);
}

ak.listners = {};
ak.listners.add = function (listnerName, aListner) {
	if (!ak.listners[listnerName]) {
		ak.listners[listnerName] = [];
	}
	ak.listners[listnerName][ak.listners[listnerName].length] = aListner;
	//ak.logger.debug(['Updated Listner', listnerName, ak.listners[listnerName]]);
}

ak.listners.fire = function (listnerName, param) {
	//ak.logger.debug(['Fireing Listner', listnerName, ak.listners[listnerName]]);
	if (ak.listners[listnerName]) {
		for (l = 0; l < ak.listners[listnerName].length; l++) {
			ak.listners[listnerName][l](param);
		}
	}
}

ak.utils = {};
ak.utils.unixTimeStamp = function(aDate) {
	if (!aDate) {
		aDate = new Date();
	}
	return parseInt(aDate.getTime().toString().substring(0, 10));
}

/**
 * a random number between min and max
 * @param {Object} min
 * @param {Object} max
 */
ak.utils.random = function (min, max) {
	var rand = Math.round((Math.random() * (max - min) ) + min);
	return rand;
}

//slideshow
ak.gallery = {};
ak.gallery.slideShow = {};
ak.gallery.slideShow._playAnimation = function(slideElSelector, imgElSelector, defaultSlide) {
	//ak.logger.debug(['slider changing', current, next]);
	var imgSel = slideElSelector + ' ' + imgElSelector;
	//if no IMGs have the show class, grab the first image
	
	var current = typeof defaultSlide == 'number' ? $(imgSel + ':eq('+defaultSlide+')') : ( 
			($(imgSel + '.show') ?  $(imgSel + '.show') : $(imgSel + ':first')) 
		);  
	
	//Get next image, if it reached the end of the slideshow, rotate it back to the first image  
	var next = ((current.next().length) ? ((current.next().hasClass('caption'))? $(imgSel + ':first') :current.next()) : $(imgSel + ':first'));     
	  
	//Get next image caption  
	var caption = next.find('img').attr('rel');   
	  
	//Set the fade in effect for the next image, show class has higher z-index  
	next.css({opacity: 0.0}).addClass('show').animate({opacity: 1.0}, 1000);  
	
	//Hide the current image  
	current.animate({opacity: 0.0}, 1000).removeClass('show');  
	  
	//Set the opacity to 0 and height to 1px  
	$(slideElSelector + ' .caption').animate(
			{opacity: 0.0}, { queue:false, duration:0 }).animate({height: '1px'}, { queue:true, duration:300 }
		);   
	  
	//Animate the caption, opacity to 0.7 and heigth to 100px, a slide up effect  
	$(slideElSelector + ' .caption').animate({opacity: 0.7},100 ).animate({height: '100px'},500 );  
	  
	//Display the content  
	$(slideElSelector + ' .content').html(caption);
}

ak.gallery.slideShow.start = function(slideElSelector, imgElSelector) {  
	//see if the slide appears more than once
	ak.logger.debug('Slide: setup selector "' + slideElSelector + '"');
	
	var slides = $(slideElSelector);
	if (slides.length > 1) {
		ak.logger.info(['Slide: Duplicate slide show objects found', slides]);
		for (var s = 0; s<slides.length; s++) {
			cn = slides[s].className;
			slides[s].className = slides[s].className + ' s' + s;
			ak.gallery.slideShow.start(slideElSelector + '.s' + s, imgElSelector);
		}	
		return;
	}
	
	if (!slides.length || slides[0].slideEffect) {
		ak.logger.error(['Slides: object not found or already sliding', slideElSelector]); 
		return; 
	} else {
		ak.logger.debug(['Slides: Starting ', slides[0]]);
	}
	slides[0].slideEffect = true;
	
	//set fixed width on the ul equl to the first image
	var aImageLi = slides.find('li:first');
	var aList = slides.find('ul');
	aList.css('width', aImageLi.width());
	aList.css('height', aImageLi.height());
	
	//Set the opacity of all images to 0  
	var imgSel = slideElSelector + ' ' + imgElSelector;
	$(imgSel).css({opacity: 0.0});  
	
	//Get the first image and display it (set it to full opacity)  
	$(imgSel + ':first').css({opacity: 1.0});  

	//Set the caption background to semi-transparent  
	//$(slideElSelector + ' .caption').css({opacity: 0.7});  
	
	//Resize the width of the caption according to the image width  
	//$(slideElSelector + ' .caption').css({width: $(imgSel).find('img').css('width')});  

	//Get the caption of the first image from REL attribute and display it  
	//$(slideElSelector + ' .content').html($(imgSel+':first').find('img').attr('rel')).animate({opacity: 0.7}, 400);
	
	//Call the gallery function to run the slideshow, 6000 = change to next image after 6 seconds  
	ak.gallery.slideShow._playAnimation(slideElSelector, imgElSelector, ak.utils.random(0, $(slideElSelector + ' ' + imgElSelector).length));
	setInterval("ak.gallery.slideShow._playAnimation('"+ slideElSelector +"', '" + imgElSelector + "')",5000);  
} 

ak.gallery.popupBubble = function (gallEl, trigEl, popupEl, popupWidth, posEl) {
	$(gallEl).each(function () {
		
		// options
		var distance = 0;
		var time = 250;
		var hideDelay = 0;
		
		var hideDelayTimer = null;
		
		// tracker
		var beingShown = false;
		var shown = false;
		
		var trigger = $(trigEl, this);
		var popup = $(popupEl, this).css('opacity', 0);
		if (posEl) {
			var posElement = $(posEl)[0];
			var posElRight = posElement.offsetLeft + posElement.clientWidth;
			var left = posElRight - this.offsetLeft;
			var top = posElement.offsetTop - this.offsetTop;
		} else {
			var left = popupWidth && this.offsetLeft && (this.offsetLeft - popupWidth - 20 > 0) ? 20 - popupWidth : 80;
			var top = popupWidth && this.offsetTop && (this.offsetTop - popupWidth + 20 > 0) ? 120 - popupWidth : 60;
		}
		
		ak.logger.debug(['Gallery Popup: Setup', trigger[0], popup[0]]);
		// set the mouseover and mouseout on both element
		$([trigger.get(0), popup.get(0)]).mouseover(function () {
			ak.logger.info(['Gallery Popup: Showing', left, top, trigger[0], popup[0]]);
			// stops the hide event if we move from the trigger to the popup element
			if (hideDelayTimer) clearTimeout(hideDelayTimer);
		
			// don't trigger the animation again if we're being shown, or already visible
			if (beingShown || shown) {
				return;
			} else {
				beingShown = true;
				// reset position of popup box
				popup.css({
						top: top,
						left: left,
						display: 'block' // brings the popup back in to view
					}).animate({ // (we're using chaining on the popup) now animate it's opacity and position
							top: '-=' + distance + 'px',
							opacity: 1
						}, time, 'swing', function(){
								// once the animation is complete, set the tracker variables
								beingShown = false;
								shown = true;
							});
			}
		}).mouseout(function () {
			// reset the timer if we get fired again - avoids double animations
			if (hideDelayTimer) clearTimeout(hideDelayTimer);
		
			// store the timer so that it can be cleared in the mouseover if required
			hideDelayTimer = setTimeout(function () {
					hideDelayTimer = null;
					popup.animate(
							{top: '-=' + distance + 'px',opacity: 0}, 
							time, 'swing', 
							function () {
									// once the animate is complete, set the tracker variables
									shown = false;
									// hide the popup entirely after the effect (opacity alone doesn't do the job)
									popup.css('display', 'none');
								}
						);
				}, hideDelay);
		});
	});
}

//stats
ak.stats = {};
ak.stats.url = document.location.href.replace(/\?.*$/, '');
ak.stats.init = function() {
	$(document.body).click( ak.stats.recordPageClick );
	if (document.location.search.match(/showClicks=1/)!=null) {
		ak.stats.plotAllClicks();
	}
}
ak.stats.recordPageClick = function(event){
	if (event.originalEvent) {
		ak.stats.topLeftPoint = $('#header')[0].getClientRects();
		ak.logger.debug(event.originalEvent);
		
		var x = event.originalEvent.clientX - ak.stats.topLeftPoint[0].left;
		var y = event.originalEvent.clientY - ak.stats.topLeftPoint[0].top;
		
		ak.logger.info( [x, ':',  y] );
		
		$.ajax({
				type:'GET',
				url:ak.siteHomeHREF + '_webService.php?site=k2&name=pageClick&url=' + ak.stats.url + '&x=' + x + '&y=' + y,
				success:function() { ak.logger.info('click recorded'); },
				contentType:'text/plain',
				error: function() { ak.logger.error('there was an error recording click'); }
			});
		//ak.stats.showClick(x, y);
	}
}
ak.stats.showClick = function(dPosX, dPosY) {
	var topLeftPoint = $('#header')[0].getClientRects();
	var i = document.createElement('IMG');
	i.src = ak.graphicsPath + 'clickPoint.png';
	ak.logger.debug(topLeftPoint[0].left);
	ak.logger.debug(dPosX);
	$(i).css({
			'z-index':'11030',
			'width':'16px',
			'position':'absolute',
			'left': Math.round(dPosX + topLeftPoint[0].left -8),
			'top':dPosY -8
		});
	
	document.body.appendChild(i);
}

ak.stats.plotAllClicks = function() {
	function _plotAllClicksReturn(data) {
		ak.logger.info(data);
		ak.logger.info(data.length);
		if (data.length) {
			for (var p = 0; p < data.length; p++) {
				ak.stats.showClick(data[p].pos_x, data[p].pos_y);
			}
		}
	}
	$.ajax({
				type:'GET',
				url:ak.siteHomeHREF + '_webService.php?site=k2&name=getPageClicks&url=' + ak.stats.url + 
						'&t=' + ak.utils.unixTimeStamp(),
				success:_plotAllClicksReturn,
				dataType:'json',
				error: function() { ak.logger.error('there was an error loading page clicks'); }
			});
} 

ak.loadjscssfile = function (filename, filetype){
       if (filetype == "js"){ //if filename is a external JavaScript file
        var fileref = document.createElement("script");
        fileref.setAttribute("type","text/javascript");
        fileref.setAttribute("src", filename);
       }
       else if (filetype == "css"){ //if filename is an external CSS file
        var fileref = document.createElement("link");
        fileref.setAttribute("rel", "stylesheet");
        fileref.setAttribute("type", "text/css");
        fileref.setAttribute("href", filename);
       }
       if (typeof fileref != "undefined")
        document.getElementsByTagName("head")[0].appendChild(fileref);
} 



