/**
 * 
 * 		title:		MINI 360 VIEWER
 * 
 *		author: 	Ovidiu Stefancu
 *					http:www.wpworks.net
 * 					http://codecanyon.net/user/wickedpixel
 *
 * 		info:		Viewer for 3d objects
 * 
 * 		ver:		1.4.1 : 	26.02.2013
 * 					- fixed bug on mobile device drag
 * 					..
 * 					- iDevices touch events enabled
 *					- autoLoop after load with options: no, forever, once
 * 					- autoLoad option that improves image loading, site traffic.
 * 					- responsive resize system
 * 					- support for settings powered by tag attributes
 * 					- auto init setting
 * 
 *  
 * 
 * 
 */




var WPW = WPW || {};
(function($) {
	//
	// MAIN OBJECT
	//
	//
	// for default settings check the bottom of the script or search "DEFAULT SETTINGS"
	
    var wpwM360 = function(theBody, options){
		
		//VARS
		var main = this;
		var cfg = $.extend({},  $.fn.wpwMiniTSZ.defaults, options);
		var tb = theBody;

		var items = [];
		var sourceImages = [];
		var tabs = [];
		var currentIndex = 0;
		var oldIndex;
		var handlerPosition = 0;
		var handlerTarget = 0;
		var i = 0;
		var loop = false;
		
		var loopTimer = 0;
		var loopPaused;
		var currentLoadingImage;
		var runningAnimation;
		var runningAnimationPaused;
		var animateObject = $({pos:handlerPosition});
		var attrCheck = function(attr, doInt){ 
				if(theBody.attr("data-"+attr)){
						cfg[attr] = theBody.attr("data-"+attr);
						if(cfg[attr] === "false"){cfg[attr] = false;}
						if(cfg[attr] === "true"){cfg[attr] = true;}
						if(doInt){cfg[attr] = parseInt(cfg[attr], 10);}
					} 
			}
			
		//preloader
		var preloader = $('<div class="wpw-preloader"><div class="wpw-preloader-anim"></div></div>');	
		var preloaderTimer = 0;

		//toolbar
		var toolbarContainer = $('<div class="wpw_360_toolbar_container"/>');
		var toolbar = $('<div class="wpw_360_toolbar round_corners"/>');
		var tabContainer = $('<div class="wpw_360_tab_container"/>');
		var tabContainerWidth = 0;
		var tabWidth = 10;

		var isTouchDevice = (/iPhone|iPod|iPad|Android/i).test(navigator.userAgent);
		attrCheck("width");	
		attrCheck("height");	
		attrCheck("toolbarMaxWidth", true);
		attrCheck("toolbarHeight", true);		
		attrCheck("toolbarDistance");		
		attrCheck("toolbarVisible");		
		attrCheck("autoLoad");	
		attrCheck("autoLoop");	
		attrCheck("loopSpeed");	
		attrCheck("show360toggle");	

		
		cfg.toolbarMaxWidth = cfg.toolbarMaxWidth || cfg.toolbarWidth;
		if(cfg.width === "0" || cfg.width === 0 || !cfg.width || cfg.width === "auto"){
			cfg.width = false;
		}
		if(cfg.height === "0" || cfg.height === 0 || !cfg.height || cfg.height === "auto"){
			cfg.height = false;
		}
		
		if(cfg.width){
			tb.css('width', cfg.width);
		}
		
		if(cfg.height){
			tb.css('height', cfg.height);
		}
		//tb.css('height', cfg.height + "px");
		
		if($.browser.msie){
			if(jQuery.browser.version == "7.0"){
				WPW.isIE7 = true;
				$('body').addClass('ie7');
			}
		}
		

		
		var container = $('<div class="wpw_360_container"/>');
		tb.append(container);
		
		$('img', tb).each(function(index){
			var img = $(this);
			sourceImages.push(img);
			var newImage = $(new Image());
			items.push(newImage);
			container.append(newImage);
			img.data('img', newImage);
			img.detach();
			
		});

		//preloader functions
		
		var showPreloader = function(){
			if(preloader.data('onScreen')) {return false;}
			clearInterval(preloaderTimer);
			preloader.data('onScreen', true);
			tb.append(preloader);
			preloader.fadeIn();
		}
		 
		var hidePreloader = function(doHide){
			if(!preloader.data('onScreen')) {return false;}
			
			
			//hide the preloader after one second if really not needed after that. will be canveled by other load inits
			if(!doHide){
				clearInterval(preloaderTimer);
				preloaderTimer = setInterval(function(){hidePreloader(true);}, 1000);
				
				return;
			}
			
			preloader.data('onScreen', 0);
			preloader.fadeOut(300, function(){});} 
		
		//

		main.showCurrentImage = function(){
			if (oldIndex != currentIndex) {
				oldIndex = currentIndex;
				
				//if current image is loaded, display it.
				if(sourceImages[currentIndex].data('loaded')){
					//change images
					for (var i = 0; i < items.length; i++) {
						var img = items[i];
						if (i == currentIndex) {
							if (img.data('visible') != true) {
								img.data('visible', true);
								img.show();
							}
						}
						else {
							if (img.data('visible') != false) {
								img.data('visible', false);
								img.hide();
							}						
						}
					}
					
					if(runningAnimation && runningAnimationPaused){
						runningAnimationPaused = 0;
						animateHandler();
						return;
					}
						
						
					if(loopPaused){
						loopPaused = 0;
						loop = true;
						main.loopImages();
						return;
					}

	
				} else {

					
					if(runningAnimation){
						runningAnimationPaused = true;
						animateObject.stop();
					}
					
					if(loop){
						loopPaused = true;
						loop = false;
					}
					
					
					//else load image
					oldIndex = "-1";
					loadImages();
				}
			}
		}
		


		var loadImage = function(sourceImage){
			
			if(currentLoadingImage){
				return false;
			}
			
			var img = sourceImage.data('img');
			currentLoadingImage = img;
			img.data('source', sourceImage);
			showPreloader();
			img.load(function(){
				sourceImage.data('loaded', true);
				img.data('loaded', true);
				currentLoadingImage = 0;
				hidePreloader();
				main.showCurrentImage();
				loadImages();
				updateToolbarTabs();
			}).error(function () {
					container.append(img);
					img.data('loaded', true);
					currentLoadingImage = 0;
					sourceImage.data('loaded', true);
					hidePreloader();
					main.showCurrentImage();
					alert("Error:\nImage not found on this path: " + sourceImage.attr('src'));
					loadImages();
					updateToolbarTabs();
			}).attr('src', sourceImage.attr('src') || sourceImage.attr('data-src'));
		}
		
		var loadimageTimer = 0;
		var loadImageTimerTest = function(pic){
			clearInterval(loadimageTimer);
			loadimageTimer = setInterval(function(){
				if(currentLoadingImage){
					return false;
				}
				clearInterval(loadimageTimer);
				loadImage(pic);
			}, 40);
		} 
		
		var loadImages = function(){
			var imageToLoad;
			
			
			//if another pic is loading, don't continue.
			if(currentLoadingImage){
				return false;
			}			
			
			//if autoLoop, then we need to change the autoLoad to true
			if(cfg.autoLoop != "no"){
				cfg.autoLoad = true;
			}
			
			//load the current selected image first
			if(!sourceImages[currentIndex].data("loaded")){
				imageToLoad = sourceImages[currentIndex];
				loadImageTimerTest(imageToLoad);
				return false;
			}
			
			if(!cfg.autoLoad){
				return false;
			}
			
			//load all images in order
			for(var i = 0; i<sourceImages.length; i++){
				var img = sourceImages[i];
				if(img.data('loaded') != true){
					loadImageTimerTest(img);
					return;
					break;
				}
			}
			
			if(sourceImages.length > 0){
				if(cfg.autoLoop != "no"){
					clearInterval(loopTimer);
					loop = true;
					loopTimer = setInterval(main.loopImages, cfg.loopSpeed);
				}
			}
		}
		

		
		var oldMx = 0;
		var oldMY = 0;
		var mX = 0;
		var mY = 0;
		var distanceX = 0;
		var distanceY = 0;
		//handles the mouse drag&rotate events
		var touchEventsPreset = function(){
			container.bind("touchstart", function(e){
				var touchStart = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
				
				oldMx = touchStart.pageX;
				oldMy = touchStart.pageY;
				
				loop = false;	
				
				tabContainerWidth = tabContainer.width();		
				
				distanceX = 0;
				distanceY = 0;
				
				container.bind("touchmove", function(e){
	      			var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
					mX = -oldMx + touch.pageX;
					mY = -oldMy + touch.pageY;
					oldMx = touch.pageX;
					oldMy = touch.pageY;
					
					distanceX += Math.abs(mX);
					distanceY += Math.abs(mY);
	
	
					handlerPosition = handlerPosition + mX;
					
					
					if(handlerPosition < 0)handlerPosition = tabContainerWidth + handlerPosition;
					if(handlerPosition > tabContainerWidth) handlerPosition = handlerPosition - tabContainerWidth;

					checkIndex();
					
					if(distanceX > 10 && distanceX > distanceY){
						e.preventDefault();
						return false;
					}
			
				});	
				
				container.bind("touchend", function(e){
					container.unbind('touchmove');
					container.unbind('touchend');
	
				});
				container.bind("touchcancel", function(e){
					container.unbind('touchmove');
					container.unbind('touchend');
				});
			});
		};
		
		
		
		if(isTouchDevice == true){touchEventsPreset();}
		
		if(cfg.onHover){
			container.mouseenter(function(e){
				oldMx = e.pageX;
				
				tabContainerWidth = tabContainer.width();			
				
				container.mousemove(function(e){
					mX = -oldMx + e.pageX;
					oldMx = e.pageX;
					
					handlerPosition = handlerPosition + mX;
					
					if(handlerPosition < 0)handlerPosition = tabContainerWidth + handlerPosition;
					if(handlerPosition > tabContainerWidth) {
						handlerPosition = handlerPosition - tabContainerWidth;
					}
	
					checkIndex();
					return false;
				});

				return false;
			}).mouseleave(function(){container.unbind('mousemove');});			
		} else {		
		
			container.mousedown(function(e){
				oldMx = e.pageX;
				loop = false;
				
				tabContainerWidth = tabContainer.width();			
				
				container.mousemove(function(e){
					mX = -oldMx + e.pageX;
					oldMx = e.pageX;
					
					handlerPosition = handlerPosition + mX;
					
					if(handlerPosition < 0)handlerPosition = tabContainerWidth + handlerPosition;
					if(handlerPosition > tabContainerWidth) handlerPosition = handlerPosition - tabContainerWidth;
	
					checkIndex();
					return false;
				});
				
				$('html, body').mouseup(function(){
					container.unbind('mouseup');
					container.unbind('mousemove');
					$('html, body').unbind('mouseup');
					return false;
				});
				container.mouseup(function(){
					container.unbind('mouseup');
					container.unbind('mousemove');
					$('html, body').unbind('mouseup');
					return false;
				});
				return false;
			});
		
		}

		main.resizeEvent = function(){
			var toolbarWidth = 0.8 * tb.width();
			if(toolbarWidth > cfg.toolbarMaxWidth){
				toolbarWidth = cfg.toolbarMaxWidth;
			}			
						
			tabWidth = toolbarWidth/items.length;
			tabWidth = parseInt(tabWidth, 10);
			
			if(WPW.isIE7){
				tabContainer.css('left', parseInt((tb.width() - toolbarWidth)/2, 10));
			}
			
			$('.wpw_360_img_tab', tb).css("width", tabWidth);
		}
		
		//TOOLBAR PRESET
		tb.append(toolbarContainer);
		toolbarContainer.append(toolbar);
		toolbar.append(tabContainer);
		tabContainer.css('height', parseInt(cfg.toolbarHeight, 10));		
		if(cfg.toolbarVisible != true)toolbar.css("visibility", "hidden");
		
		//tabContainer.css('width', tabContainerWidth + "px");
		
		for(i = 0; i<items.length; i++){
			var tab = $('<div class="wpw_360_img_tab"/>');
			tab.data('index', i);
			tabContainer.append(tab);
			tabs.push(tab);
			tab.css('height', cfg.toolbarHeight + "px");
			tab.click(function(){
				loop = false;
				currentIndex = $(this).data('index');
				handlerTarget = parseInt($(this).position().left + tabWidth/2);
				animateHandler();
				main.showCurrentImage();
			});
		}
			
		//displays what images are loaded and what are not - the tab colors
		var updateToolbarTabs = function(){
			for(i = 0; i<items.length; i++){
				var img = items[i];
				if(img.data('loaded') != true){tabs[i].addClass('wpw_tab_not_loaded');} else {tabs[i].removeClass('wpw_tab_not_loaded');}
			}
			toolbarContainer.css('bottom', parseInt(cfg.toolbarDistance));
		}
		
		//animates the sellection of a tab
		var animateHandler = function(){
			runningAnimationPaused = 0;
			if(cfg.autoLoad){
				runningAnimation = true;
				//animateObject.data("pos", handlerPosition);
				animateObject = $({pos:handlerPosition});
				animateObject.animate({
					pos: handlerTarget
				}, {
					duration: 1000,
					easing: "easeInOutQuad",
					step: function(){
						handlerPosition = this.pos;
						checkIndex();
					},
					complete: function(){
						runningAnimation = false;
						handlerPosition = this.pos;
						checkIndex();
					}
				});
			} else {
				handlerPosition = handlerTarget;
				checkIndex();
			}
		}
		
		//highlights what image tab is selected and updates the selected image index 
		var checkIndex = function(){
			var pos = handlerPosition + tabs[0].position().left + tabWidth/2;
			var tab;
			var tab_pos;
			for(var i = 0; i<tabs.length; i++){
				tab = tabs[i];
				tab_pos = tab.position().left + tabs[0].position().left;
				if(pos >= tab_pos && pos <= tab_pos + tabWidth){
					if(tab.data('selected') != true){
						tab.data('selected', true);
						tab.addClass('wpw_tab_selected');
					}
					currentIndex = i;
				} else {
					if(tab.data('selected') != false){
						tab.data('selected', false);
						tab.removeClass('wpw_tab_selected');
					}					
				}
			}
			main.showCurrentImage();
		}
		
		
		//checks to see if it can display the toggle loop button
		if(cfg.show360toggle == true){
			var icon = $('<div class="wpw_360_icon"/>');
			tb.append(icon);

			icon.click(function(){
				cfg.autoLoad = true;
				
				if(loop == false){
					loop = true;
					loopPaused = 0;
				} else {
					loop = false;
				}
				
				if(loop == true){
					clearInterval(loopTimer);
					loopTimer = setInterval(main.loopImages, cfg.loopSpeed);
				}
			});
		}
		
		//loops between images
		main.loopImages = function(){
			clearInterval(loopTimer);
			if(loop == true){
				loopPaused = 0;
				currentIndex++;
				if(currentIndex > items.length - 1){
					currentIndex = 0;
					if(cfg.autoLoop == "once"){
						cfg.autoLoop = "no";
						loop = false;
					}
				}
				handlerPosition = tabs[currentIndex].position().left + tabWidth/2;
				checkIndex();
				
				
				loopTimer = setInterval(main.loopImages, cfg.loopSpeed);
			}
		}
		
		$('body').bind("WindowResized", main.resizeEvent);		
		main.resizeEvent();
		
		updateToolbarTabs();
		checkIndex();
	
	//
	// END
	//		
	
		tb.bind("DESTROY", function(){
			$('*', tb).each(function(){
				var item = $(this);
				item.stop();
				item.unbind();
				item.clearQueue();
			});
			clearInterval(loopTimer);
			loop = false;
		});		
	
			
    };
       
    $.fn.wpwMiniTSZ = function(options) {
        return this.each(function(){
            var element = $(this);
            if (element.data('wpwm360')) {return;}
			element.data('wpwm360', true);
            var plugin = new wpwM360(element, options);
            $('body').data('wpwm360', plugin);
        });
	};
	
	//
	//	DEFAULT SETTINGS
	//
	
	$.fn.wpwMiniTSZ.defaults = {
		width:"auto",
		height:"auto",
		toolbarMaxWidth:300,
		toolbarHeight:16,
		toolbarDistance:10,
		onHover:false,
		loopSpeed:100,
		autoLoop:"no", //once, no, forever
		toolbarVisible:true,
		autoLoad:false,
		show360toggle:true
	};	
	

})(jQuery);



//RESIZE ENGINE
if(!WPW.ResizeEngine){
	var $ = jQuery;
	WPW.ResizeEngine = {};
	//RESIZE EVENT

	WPW.ResizeEngine.resizeTimer = 0;
	WPW.ResizeEngine.resizeEvent = function(){
		var $ = jQuery;
		clearInterval(WPW.ResizeEngine.resizeTimer);
		WPW.ResizeEngine.resizeTimer = setInterval(function(){
			if(!WPW.body){
				if($('body').length){WPW.body = $('body');}
			}
			
			
			WPW.body.trigger('WindowResized');
			clearInterval(WPW.ResizeEngine.resizeTimer);
		}, 100);
	}
	
	jQuery(window).resize( function() {WPW.ResizeEngine.resizeEvent();});		
};	

jQuery(document).ready(function($){jQuery(".wpw-auto-init-3dv").wpwMiniTSZ();});	


// function to make compatibility with the older jquery 1.8 codes. 
function wpwBrowser(){if(jQuery.browser){return}var e,t;jQuery.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}};e=jQuery.uaMatch(navigator.userAgent);t={};if(e.browser){t[e.browser]=true;t.version=e.version}if(t.chrome){t.webkit=true}else if(t.webkit){t.safari=true}jQuery.browser=t;jQuery.sub=function(){function e(t,n){return new e.fn.init(t,n)}jQuery.extend(true,e,this);e.superclass=this;e.fn=e.prototype=this();e.fn.constructor=e;e.sub=this.sub;e.fn.init=function(r,i){if(i&&i instanceof jQuery&&!(i instanceof e)){i=e(i)}return jQuery.fn.init.call(this,r,i,t)};e.fn.init.prototype=e.fn;var t=e(document);return e}}wpwBrowser();
