(function($) {
	
	$.bgSlideshow = function(data) {
		
		// ***********************
		// begin class constructor
		// ***********************
		
		var doc = $(document);
		if(doc.find("#bg-images").length === 0) return;
		var current_image;
		var autoPlay = data.autoPlay, 
		transDelay = data.transitionDelay, 
		activeOpacity = data.activeNumOpacity,
		catOpacity = data.nonActiveCatOpacity,
		randomImg = data.randomizeImages,
		
		play, 
		pause,
		prev,
		next, 
		playOn, 
		iLeg, 
		leg, 
		timer,
		runTime,
		oWidth,
		oHeight,
		winWide,
		winTall,
		imgOne,
		imgTwo,
		list,
		hash,
		pre,
		numbers,
		images,
		bgImages,
		centered,
		stretched,
		useArrows = true,
		useBgNumbers,
		usePlayPause,
		isOn, 
		
		bgOn = 0,
		catCount = 0,
		catOn = 0,
		time = 750,
		 
		runOn = false,
		readyToFire = false,
		isLoading = false,
		noControls = false,
		running = false, 
		firstRun = true,
		firstTime = true,
		
		win = $(window), 
		bodies = $("body"),
		bgs = $("#bg-images"), 
		bgOne = $("<div />"),
		bgTwo = $("<div />"),
		bgUL = bgs.find("ul"),
		
		cats = [],
		titles = [],
		titleText = [],
		ulist = [];
		
		var ie = (function(){
		 
			var undef,
				v = 3,
				div = document.createElement('div'),
				all = div.getElementsByTagName('i');
		 
			while (
				div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
				all[0]
			);
		 
			return v > 4 ? v : undef;
		 
		}());
		
		if(data.disableRightClick) {
			doc.bind("contextmenu", function(event) {event.preventDefault()});	
		}
		
		if(doc.find("#preloader").length > 0) {
			pre = $("#preloader");	
		}
		
		(autoPlay) ? playOn = true : playOn = false;
		
		if(bgUL.length > 0) {
			
			var cat, items, pusher, catalog = $("#categories"), st, str, centr, txt;
			
			bgUL.each(function() {
				
				items = [];
				pusher = 0;
				
				$(this).children("li").each(function() {
				
					items[pusher] = $(this);
					pusher++;
					
				});
				
				if($(this).attr("class")) {
					
					st = $(this).attr("class");
					
					if(st === "stretch") {
						str = true;
						centr = false;
					}
					else if(st === "stretch-center") {
						str = true;
						centr = true;
					}
					else {
						str = false;
						centr = false;	
					}
					
				}
				else {
					
					str = true;
					centr = false;

				}
				
				txt = $(this).attr("title");
				$(this).removeAttr("title");
				titleText[catCount] = txt.toLowerCase();

				cat = $("<p />");
				cat.html(txt).data({"id": catCount, "stretch": str, "center": centr});
				catalog.append(cat);
				
				ulist[catCount] = $(this);
				titles[catCount] = cat;
				cats[catCount] = items;
				catCount++;
				
			});
			
			if(bgUL.length === 1) {
			
				titles[0].css("visibility", "hidden");
				
			}
			
			items = null;
			cat = null;
			catalog = null;
			pusher = null;
			st = null;
			str = null;
			centr = null;
			txt = null;
			
		}
		else {
			
			return;
				
		}
		
		data = null;
		bgUL = null;
		
		if(doc.find("#music").length === 0 || doc.find(".volume").length === 0) {
				
			titles[0].css("margin-left", parseInt(titles[0].css("margin-left")) * 2);
				
		}
					
		if(doc.find(".play-button").length > 0 && doc.find(".pause-button").length > 0) {
								
			play = $(".play-button");	
			pause = $(".pause-button");	
								
			play.click(handlePlay);
			pause.click(handlePlay);
			
			if(autoPlay) {
				play.css("display", "none");
			}
			else {
				pause.css("display", "none");
			}
			
			usePlayPause = true;
								
		}
						
		else {
			
			usePlayPause = false;
								
		}
		
		if(doc.find(".prev-button").length > 0 && doc.find(".next-button").length > 0) {
								
			prev = $(".prev-button");	
			next = $(".next-button");	
			
			useArrows = true;
								
		}
						
		else {
			
			usePlayPause = false;
								
		}
		
		bgs.css("display", "block");
		bgOne.css({position: "fixed", zIndex: -10000});
		bgTwo.css({position: "fixed", zIndex: -10000});
		
		winWide = win.width();
		winTall = win.height();
		
		$.address.internalChange(insideChange);
		$.address.externalChange(browserChange);
		win.resize(sizer);
		
		// *********************
		// end class constructor
		// *********************
		
		function browserChange(event) {
			
			event.stopPropagation();
			
			if(timer) clearTimeout(timer);
			if(runTime) clearTimeout(runTime);
			
			if(isLoading) {
				
				if(imgOne) imgOne.unbind("load", loaded);
				if(imgTwo) imgTwo.unbind("load", loaded);
				
				detatch();
				isLoading = false;
					
			}
			
			getHash(event.value);
			
			if(!firstTime) {
				
				disableClicks();
				runTime = setTimeout(changeHash, 750);
				
			}
			else {
				
				changeHash();
				firstTime = false;	
				
			}
		}
		
		function insideChange(event) {
			
			event.stopPropagation();
			
			if(timer) clearTimeout(timer);
			if(runTime) clearTimeout(runTime);
			disableClicks();
			
			getHash(event.value);
			changeHash();
			
		}
		
		function getHash(val) {

			if(val !== "/") {
				
				var ars = val.split("/");
				var lgs = ars.length;
				
				if(ars.length === 3) {
					
					isOn = parseInt(ars[2]) - 1;
					hash = ars[1];
					
				}
				else {
					
					if(isNaN(ars[1])) {
						isOn = 0;
						hash = ars[1];
					}
					else {
						isOn = parseInt(ars[1]) - 1;
						hash = "/";
					}
					
				}
				
			}
			else {
			
				hash = "/";
				isOn = 0;
				
			}
			
		}
		
		function changeHash() {
			
			var i;
			
			if(hash !== "/") {
				
				i = catCount;
				
				while(i--) {
				
					if(titleText[i] == hash) {
					
						catOn = i;
						break;
						
					}
					
				}
				
			}
			else {
				catOn = 0;
			}
			
			i = catCount;
			
			while(i--) {
				
				if(i !== catOn) {
					
					ulist[i].css("display", "none");
					titles[i].css({"opacity": catOpacity, "cursor": "pointer"});
					
				}
				else {
				
					titles[catOn].css({"opacity": 1, "cursor": "default"})
					
					if(!firstRun) {
						ulist[catOn].fadeIn(500);
					}
					else {
						firstRun = false;
					}
					
				}
				
			}
			
			if(pre) pre.fadeIn(300);
			
			getList();
			loadBG(list[isOn]);
			
		}
		
		function disableClicks() {
		
			runOn = true;
			readyToFire = false;
			
			var i = catCount;
				
			while(i--) {
			
				titles[i].unbind("click", categoryClick);
					
			}
				
			if(useBgNumbers) {
							
				i = leg;
							
				while(i--) {	
					if(numbers[i]) numbers[i].unbind("click", numberClick);
				}
				
			}

			prev.unbind("click", handleLeft);
			next.unbind("click", handleRight);
			
			prev.click(function(){ return false;});
			next.click(function(){ return false;});
		}
		
		function getList() {
			
			var foundHTML = true;
			images = cats[catOn];
			leg = images.length;

			
			iLeg = leg - 1;
			list = [];
			numbers = [];
			bgImages = [];

			if(isOn > iLeg) isOn = 0;
		
			for(var i = 0; i < leg; i++) {
							
				if(images[i].html() !== "") {
										
					if(i !== isOn) {
						images[i].css({"cursor": "pointer", "opacity": 1}).removeClass('cur');
					}
					else {
						images[i].css({"cursor": "default", "opacity": 1}).addClass('cur');		
						current_image = i;
					}
						
					images[i].data("id", i);
					numbers[i] = images[i];
					useBgNumbers = true;
										
				}
								
				else {
									
					images[i].css("display", "none");
					useBgNumbers = false;
					foundHTML = false;
										
				}
								
				if(images[i].attr("title")) {
						
					images[i].data("url", images[i].attr("title"));
					bgImages[i] = images[i].attr("title");
					images[i].removeAttr("title");
					
				}
				else {
					
					bgImages[i] = images[i].data("url");
						
				}
				
			}
			
			if(leg > 1) {
				
				if(foundHTML) {
					ulist[catOn].css("display", "block");
				}
				else {
					ulist[catOn].css("display", "none");	
				}
				
				if(noControls) {
				
					if(usePlayPause) {
						
						$("#play-pause").css("display", "block");
						
					}
					
					if(useArrows) {
						
						$(".prev-next").css("display", "block");
						
					}
					
					noControls = false;
					
				}
				
			}
			else {
			
				ulist[catOn].css("display", "none");
				
				if(usePlayPause) {
				
					$("#play-pause").css("display", "none");
					
				}
				
				if(useArrows) {
				
					$(".prev-next").css("display", "none");
					
				}
				
				noControls = true;
				
			}
						
			if(randomImg) {
						
				var shuf = [], placer;
						   
				for(var i = 0; i < leg; i++) {
					shuf[i] = bgImages[i];
				}
								
				while(shuf.length > 0) { 
								
					placer = Math.floor(Math.random() * shuf.length);
					list[list.length] = shuf[placer];
					shuf.splice(placer, 1);
								
				}
							
			}
						
			else {
				
				list = bgImages;
				
			}
			
			stretched = titles[catOn].data("stretch");
			centered = titles[catOn].data("center");
			
		}
		
		function loadBG(url) {
			
			isLoading = true;
			
			if(bgOn === 0) {
					
				bodies.prepend(bgOne);
				bgOne.css("z-index", parseInt(bgTwo.css("z-index")) + 1);
				
				imgOne = $("<img />").css({display: "none", position: "fixed"}).load(loaded).appendTo(bgOne);
				imgOne.attr("src", url).addClass('myBGImage');
	
			}
			else {

				bodies.prepend(bgTwo);
				bgTwo.css("z-index", parseInt(bgOne.css("z-index")) + 1);
			
				imgTwo = $("<img />").css({display: "none", position: "fixed"}).load(loaded).appendTo(bgTwo);
				imgTwo.attr("src", url).addClass('myBGImage');
			}
					
		}
		
		function loaded(event) {                                          
			
			event.stopPropagation();
			isLoading = false;
			
			oWidth = $(event.target).width();
			oHeight = $(event.target).height();
			
			if(bgOn === 0) {
				imgOne.unbind("load", loaded);
				bgOn = 1;
			}
			else {
				imgTwo.unbind("load", loaded);
				bgOn = 0;
			}
			
			if(pre) pre.fadeOut(300);
			
			sizer();
			fadeImage();

			//load other stuff along with the images
			var attached_content = $('ul#services-features > li.cur > div.attached-content'); //current services for homepage. quote, images, etc
			var client_slides = $('#client-features > li.cur > .client-box'); // current featured client 
			$('#myFooter > #bottom-content > li').hide(); //homepage footer quotes
			$('#content_wrap > .thumbs').remove(); //client footer icons
			$('img.quote, img.title').fadeOut(100,function(){$(this).remove();});
			$('span.caption').hide();

			if(catOn == 0){//homepage
				//remove
				$('.prev, .next, #content_wrap > .thumbs').hide(); //thumbs and next/prev arrows
				$('#client-overlay .client-box').empty(); //remove curent feature from screen
				$('ul#services-features li > div.attached-content, #myFooter > #bottom-content > li').fadeOut(100);
				$('ul#services-features > li.cur > div.attached-content > img.title,ul#services-features > li.cur > div.attached-content > img.quote').fadeOut(100, function(){$(this).remove()});
				$('#myFooter').height('115px');
				$('#wrap img.para').hide();
				
				//add
				$('#myFooter > #bottom-content').show();
				attached_content.prepend('<img src="" class="title" style="display:none;" /><img src="" class="quote" style="display:none;" />');
					
				attached_content.children('img.title').attr('src',  attached_content.children('span.title').attr('title') );
				
				
				if(winWide >1024 && winTall > 800 ) {
					attached_content.children('img.quote').attr('src',  attached_content.children('span.quote').attr('title') ).css('width', attached_content.children('span.quote').attr('data-init-w') + 'px').css('height', attached_content.children('span.quote').attr('data-init-h') + 'px');
				}else{
					attached_content.children('img.quote').attr('src',  attached_content.children('span.quote').attr('title') ).css('width', attached_content.children('span.quote').attr('data-init-w') * .85 + 'px').css('height', attached_content.children('span.quote').attr('data-init-h') * .85 + 'px');
				}

				$('ul#services-features > li.cur > div.attached-content > img.title, ul#services-features > li.cur > div.attached-content > img.quote,li.cur > div.attached-content > span.caption, ul#services-features > li.cur > div.attached-content, #myFooter > #bottom-content > li:eq('+current_image+')').fadeIn(1250);
				
				$(window).bind('resize scroll', function() {
					if(winWide >1024 && winTall > 800 ) {
						attached_content.children('img.quote').attr('src',  attached_content.children('span.quote').attr('title') ).css('width', attached_content.children('span.quote').attr('data-init-w') + 'px').css('height', attached_content.children('span.quote').attr('data-init-h') + 'px');
					}else{
						attached_content.children('img.quote').attr('src',  attached_content.children('span.quote').attr('title') ).css('width', attached_content.children('span.quote').attr('data-init-w') * .85 + 'px').css('height', attached_content.children('span.quote').attr('data-init-h') * .85 + 'px');
					}
				}); 
			}else if(catOn == 1){//clients
				//remove
				$('#myFooter #bottom-content').hide(); // footer quotes
				$('#myFooter').height('50px'); // change height
				$('#client-overlay .client-box').empty(); //remove curent feature from screen
				$('#wrap > img.para').remove();

				if(timer) clearTimeout(timer); playOn = false; //disable automatic loop through features.
				
				//add
				$('.prev, .next').show(); // show next/prev arrows
				$('#client-overlay .client-box').html(client_slides.html()); // add curent feature to scree
					
				//replace with images
				$('#client-overlay > div.client-box').prepend('<img src="" class="logo" />');
					
				$('#client-overlay > div.client-box').children('img.logo').attr('src', $('#client-overlay > div.client-box').children('span.logo').attr('title') );

				//add thumbnails
				$('#content_wrap').append( $('#client-overlay .client-box .thumbs') );
				
				//$('#content_wrap > .thumbs').width( $('#content_wrap > .thumbs a').length * 45 + 'px').css('top', winTall - 98 + 'px').fadeIn(1250);
				$('#content_wrap > .thumbs').css('top', winTall - 98 + 'px');
								
				//add parallax		
				var count = 0;
				
				$('#client-features li.cur .para').each(function(){
					var pos = $(this).attr('data-pos');
					var paraY = $(this).attr('data-para-y');
					var paraX = $(this).attr('data-para-x');

					$('#wrap').prepend('<img src="" class="para '+count+'" />');
	
					$('#wrap > img.'+count).attr('src', $(this).attr('title')).css('height',winTall*1.1);
					$('#wrap > img.'+count).imagesLoaded(function(){	
						pw = $(this).width()
						//console.log(pw);
						ratio = (winWide - pw) * pos/100;
						
						$(this).css('left',ratio + 'px' ).fadeIn(250);
						
						$(this).attr('data-pos', pos);
						$(this).attr('data-para-y', paraY);
						$(this).attr('data-para-x', paraX);
						$(this).attr('data-init-left', ratio);
						
						//if(!ie || ie >= 9)
						$(this).plaxify({"xRange":paraX,"yRange":paraY})	
					});
					count ++;
				});
				//if(!ie  || ie >= 9)
				
				$('#content_wrap > .thumbs, #client-overlay .client-box').fadeIn(1000);
				$.plax.enable()
				
				$(window).bind('resize scroll', function() { // not quite right
					$('#wrap > img.para').each(function(){
						var pos = $(this).attr('data-pos');
						var paraY = $(this).attr('data-para-y');
						var paraX = $(this).attr('data-para-x');
						var initLeft = $(this).attr('data-init-left');
						
						pw = $(this).width();
						ratio = (winWide - pw) * pos/100;

						$(this).height(winTall*1.1).css('margin-left',(ratio-initLeft) + 'px' )
					});
				}); 
				
				//startPlax();
			}
		}
		
		function startPlax(){
			//console.log($('#wrap > img.para').attr('class'))
			//console.log($('#wrap > img.para').attr('data-para-x'))
			$('#wrap > img.para').plaxify({"xRange":80,"yRange":0})
			$.plax.enable()
		}
		
		function fadeImage() {
				
			running = true;
			
			if(!stretched) detatch();
			
			if(bgOn === 1) {
				imgOne.fadeIn(time, afterTrans);
			}
			else {
				imgTwo.fadeIn(time, afterTrans);	
			}
				
		}

		
		function detatch() {
		
			if(bgOn === 1) {
			
				if(imgTwo) {
				
					imgTwo.remove();
					bgTwo.detach();
					
				}
				
			}
			else {
			
				if(imgOne) {
					
					imgOne.remove();
					bgOne.detach();
					
				}
				
			}
			
		}
		
		// cleans up the previous image after the transition is complete, also fired callback if used
		function afterTrans() {
				
			running = false;
			
			if(stretched) detatch();
														  
			bgFired();
													  
		}
		
		function changeBG() {
					
			disableClicks();
						
			if(useBgNumbers) {
					
				numbers[isOn].css({"cursor": "pointer", "opacity": 1});
					
				(isOn < iLeg) ? isOn++ : isOn = 0;
					
				numbers[isOn].css({"cursor": "default", "opacity": activeOpacity});
					
			}
			else {
				
				(isOn < iLeg) ? isOn++ : isOn = 0;
					
			}
			
			$.address.value(hash + "/" + (isOn + 1).toString());
					
		}
				
		function bgFired() {
			
			if(timer) clearTimeout(timer);
			
			var i = catCount;
				
			while(i--) {
			
				if(i !== catOn) titles[i].click(categoryClick);
					
			}
			
			if(leg > 1) {		
			
				if(useBgNumbers) {
							
					i = leg;
							
					while(i--) {		
						if(i !== isOn && numbers[i]) numbers[i].click(numberClick);
					}
							
				}
				
				if(useArrows) {
					
					prev.click(handleLeft);
					next.click(handleRight);	
					
				}
				
				if(autoPlay) {
					
					if(playOn) {
						timer = setTimeout(changeBG, transDelay);
					}
							
					else {
						readyToFire = true;	
					}
					
				}
				else {
					readyToFire = true;
				}
				
			}
			else {
				readyToFire = true;	
			}
			
			runOn = false;
					
		}
		
		function categoryClick() {
			
			if(!runOn) {
				
				$.address.value(titleText[$(this).data("id")]);
				
			}
			
		}
				
		function numberClick() {
					
			if(!runOn) {
						
				if(timer) clearTimeout(timer);
				disableClicks();
				$.address.value(hash + "/" + (parseInt($(this).data("id")) + 1).toString());
						
			}
						
		}
		
		function handleLeft() {
			
			if(timer) clearTimeout(timer);
			disableClicks();
			
			if(useBgNumbers) numbers[isOn].css({"cursor": "pointer", "opacity": 1});
			
			(isOn > 0) ? isOn-- : isOn = iLeg;
			
			if(useBgNumbers) numbers[isOn].css({"cursor": "default", "opacity": activeOpacity});
			
			$.address.value(hash + "/" + (isOn + 1).toString());
			return false;
		}
		
		function handleRight() {
			
			if(timer) clearTimeout(timer);
			disableClicks();
			
			if(useBgNumbers) numbers[isOn].css({"cursor": "pointer", "opacity": 1});
			
			(isOn < iLeg) ? isOn++ : isOn = 0;
			
			if(useBgNumbers) numbers[isOn].css({"cursor": "default", "opacity": activeOpacity});
			
			$.address.value(hash + "/" + (isOn + 1).toString());
			return false;
		}
		
		function handlePlay() {
					
			if(playOn) {
						
				if(timer) clearTimeout(timer);
						
				pause.css("display", "none");
				play.css("display", "block");
						
				playOn = false;
						
				if(!runOn) readyToFire = true;	
						
			}
					
			else {
						
				play.css("display", "none");
				pause.css("display", "block");
						
				playOn = true;
				if(readyToFire) changeBG();	
						
			}
					
		}
		$.bgSlideshow.pause = function(){if(timer) clearTimeout(timer); playOn = false;};		
		function sizer(fromLoad) {
			
				
				winWide = win.width();
				winTall = win.height();
					
			
			if(imgOne == undefined) return false;
			
			if(fromLoad != undefined && running) {
				
				running = false;
				
				if(bgOn === 1) {
					imgOne.stop(true, true);
				}
				else {
					imgTwo.stop(true, true);	
				}
					
			}
			
			var wide = winWide / oWidth, tall = winTall / oHeight, perc, w, h, x, y;
			
			if(stretched) {
				
				perc = (wide > tall) ? wide : tall;
				w = Math.ceil(oWidth * perc);
				h = Math.ceil(oHeight * perc);
				
				if(centered) {
					
					(w > winWide) ? x = Math.floor((w - winWide) / 2) : x = 0;
					(h > winTall) ? y = Math.floor((h - winTall) / 2) : y = 0;
						
				}
				else {
					
					x = 0;
					y = 0;
						
				}
				
			}
			else {
				
				perc = (wide > tall) ? tall : wide;
				w = Math.ceil(oWidth * perc);
				h = Math.ceil(oHeight * perc);
				
				(winWide > w) ? x = -(Math.floor((winWide - w) / 2)) : x = 0;
				(winTall > h) ? y = -(Math.floor((winTall - h) / 2)) : y = 0;
				
			}
			
			if(bgOn === 1) {	
				
				imgOne.width(w).height(h);
				imgOne.offset({top: -y, left: -x});
				
			}
			else {
				
				imgTwo.width(w).height(h);
				imgTwo.offset({top: -y, left: -x});
				
			}
			
		}
		
	}
	
})(jQuery);














