(function ($) {
	'use strict';

	// Template Helper Function
	$.fn.hasAttr = function(attribute) {
		var obj = this;

		if (obj.attr(attribute) !== undefined) {
			return true;
		} else {
			return false;
		}
	};

	var Base64 = {
	    _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
	    encode: function(e) {
	        var t = "";
	        var n, r, i, s, o, u, a;
	        var f = 0;
	        e = Base64._utf8_encode(e);
	        while (f < e.length) {
	            n = e.charCodeAt(f++);
	            r = e.charCodeAt(f++);
	            i = e.charCodeAt(f++);
	            s = n >> 2;
	            o = (n & 3) << 4 | r >> 4;
	            u = (r & 15) << 2 | i >> 6;
	            a = i & 63;
	            if (isNaN(r)) {
	                u = a = 64
	            } else if (isNaN(i)) {
	                a = 64
	            }
	            t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a)
	        }
	        return t
	    },
	    decode: function(e) {
	        var t = "";
	        var n, r, i;
	        var s, o, u, a;
	        var f = 0;
	        e = e.replace(/[^A-Za-z0-9+/=]/g, "");
	        while (f < e.length) {
	            s = this._keyStr.indexOf(e.charAt(f++));
	            o = this._keyStr.indexOf(e.charAt(f++));
	            u = this._keyStr.indexOf(e.charAt(f++));
	            a = this._keyStr.indexOf(e.charAt(f++));
	            n = s << 2 | o >> 4;
	            r = (o & 15) << 4 | u >> 2;
	            i = (u & 3) << 6 | a;
	            t = t + String.fromCharCode(n);
	            if (u != 64) {
	                t = t + String.fromCharCode(r)
	            }
	            if (a != 64) {
	                t = t + String.fromCharCode(i)
	            }
	        }
	        t = Base64._utf8_decode(t);
	        return t
	    },
	    _utf8_encode: function(e) {
	        e = e.replace(/rn/g, "n");
	        var t = "";
	        for (var n = 0; n < e.length; n++) {
	            var r = e.charCodeAt(n);
	            if (r < 128) {
	                t += String.fromCharCode(r)
	            } else if (r > 127 && r < 2048) {
	                t += String.fromCharCode(r >> 6 | 192);
	                t += String.fromCharCode(r & 63 | 128)
	            } else {
	                t += String.fromCharCode(r >> 12 | 224);
	                t += String.fromCharCode(r >> 6 & 63 | 128);
	                t += String.fromCharCode(r & 63 | 128)
	            }
	        }
	        return t
	    },
	    _utf8_decode: function(e) {
	        var t = "";
	        var n = 0;
	        var r = 0;
	        var c1 = 0;
	        var c2 = 0;
	        while (n < e.length) {
	            r = e.charCodeAt(n);
	            if (r < 128) {
	                t += String.fromCharCode(r);
	                n++
	            } else if (r > 191 && r < 224) {
	                c2 = e.charCodeAt(n + 1);
	                t += String.fromCharCode((r & 31) << 6 | c2 & 63);
	                n += 2
	            } else {
	                c2 = e.charCodeAt(n + 1);
	                c3 = e.charCodeAt(n + 2);
	                t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
	                n += 3
	            }
	        }
	        return t
	    }
	}

	var teslaThemes = {

		statisticsCounterVisible: false,
		progressCounter: false,

		init: function () {
			this.checkVisible();
			this.isotopeInit();
			this.carouselInit();
			this.noUiInit();
			this.toggles();
			this.googleMaps();
		},

		checkVisible: function () {
			var $w = $(window);
		    $.fn.visible = function(partial,hidden,direction){

		        if (this.length < 1)
		            return;

		        var $t        = this.length > 1 ? this.eq(0) : this,
		            t         = $t.get(0),
		            vpWidth   = $w.width(),
		            vpHeight  = $w.height(),
		            direction = (direction) ? direction : 'both',
		            clientSize = hidden === true ? t.offsetWidth * t.offsetHeight : true;

		        if (typeof t.getBoundingClientRect === 'function'){

		            var rec = t.getBoundingClientRect(),
		                tViz = rec.top    >= 0 && rec.top    <  vpHeight,
		                bViz = rec.bottom >  0 && rec.bottom <= vpHeight,
		                lViz = rec.left   >= 0 && rec.left   <  vpWidth,
		                rViz = rec.right  >  0 && rec.right  <= vpWidth,
		                vVisible   = partial ? tViz || bViz : tViz && bViz,
		                hVisible   = partial ? lViz || rViz : lViz && rViz;

		            if(direction === 'both')
		                return clientSize && vVisible && hVisible;
		            else if(direction === 'vertical')
		                return clientSize && vVisible;
		            else if(direction === 'horizontal')
		                return clientSize && hVisible;
		        } else {

		            var viewTop         = $w.scrollTop(),
		                viewBottom      = viewTop + vpHeight,
		                viewLeft        = $w.scrollLeft(),
		                viewRight       = viewLeft + vpWidth,
		                offset          = $t.offset(),
		                _top            = offset.top,
		                _bottom         = _top + $t.height(),
		                _left           = offset.left,
		                _right          = _left + $t.width(),
		                compareTop      = partial === true ? _bottom : _top,
		                compareBottom   = partial === true ? _top : _bottom,
		                compareLeft     = partial === true ? _right : _left,
		                compareRight    = partial === true ? _left : _right;

		            if(direction === 'both')
		                return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop)) && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
		            else if(direction === 'vertical')
		                return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop));
		            else if(direction === 'horizontal')
		                return !!clientSize && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
		        }
		    };
		},

		isotopeInit: function () {
		    var isotopeContainer = $('.isotope-container'),
				defaultSelection = $('.isotope-container').attr('data-default-selection');
			
			isotopeContainer.imagesLoaded(function () {
				isotopeContainer.isotope({
					filter: defaultSelection,
					itemSelector: '.isotope-item',
				    hiddenStyle: {
				      opacity: 0,
				      transform: 'scale(0.001)'
				    },
				    visibleStyle: {
				      opacity: 1,
				      transform: 'scale(1)'
				    },
				    transitionDuration: '0.8s'
				});
			});

			$('.isotope-filters a').on('click', function () {
				$('.isotope-filters .current').removeClass('current');
				$(this).addClass('current');

				var selector = $(this).attr('data-filter');
					isotopeContainer.isotope({
						filter: selector
					});
				return false;
			});
		},

		carouselInit: function () {
			var i = $(".slick-carousel"),
				j = $(".slick-slider");

            i.each(function() {
                var e = $(this),
                    a = e.find(".carousel-items");
                a.slick({
                    focusOnSelect: !0,
                    speed: e.hasAttr("data-speed") ? e.data("speed") : 600,
                    slidesToShow: e.hasAttr("data-items-desktop") ? e.data("items-desktop") : 4,
                    arrows: e.hasAttr("data-arrows") ? e.data("arrows") : !0,
                    appendArrows: e, 
                    dots: e.hasAttr("data-dots") ? e.data("dots") : !0,
                    infinite: e.hasAttr("data-infinite") ? e.data("infinite") : !1,
                    slidesToScroll: e.hasAttr("data-items-to-slide") ? e.data("items-to-slide") : 1,
                    initialSlide: e.hasAttr("data-start") ? e.data("start") : 0,
                    asNavFor: e.hasAttr("data-as-nav-for") ? e.data("as-nav-for") : "",
                    centerMode: e.hasAttr("data-center-mode") ? e.data("center-mode") : "",
                    fade: e.hasAttr("data-fade") ? e.data("fade") : false,
                    easing: e.hasAttr("data-easing") ? e.data("easing") : "linear",
                    responsive: [
					    {
					      breakpoint: 992,
					      settings: {
					        slidesToShow: e.hasAttr("data-items-desktop") ? e.data("items-desktop") : 2,
					        slidesToScroll: e.hasAttr("data-items-desktop") ? e.data("items-desktop") : 2,
					        infinite: true,
					      }
					    },
					    {
					      breakpoint: 768,
					      settings: {
					        slidesToShow: e.hasAttr("data-items-tablet") ? e.data("items-tablet") : 1,
					        slidesToScroll: e.hasAttr("data-items-tablet") ? e.data("items-tablet") : 1
					      }
					    },
					    {
					      breakpoint: 620,
					      settings: {
					        slidesToShow: e.hasAttr("data-items-mobile") ? e.data("items-mobile") : 1,
					        slidesToScroll: e.hasAttr("data-items-mobile") ? e.data("items-mobile") : 1
					      }
					    },
					    {
					      breakpoint: 470,
					      settings: {
					        slidesToShow: e.hasAttr("data-items-xs-mobile") ? e.data("items-xs-mobile") : 1,
					        slidesToScroll: e.hasAttr("data-items-xs-mobile") ? e.data("items-xs-mobile") : 1
					      }
					    }
					]
                })
            });

			j.each(function () {
				var obj = $(this),
					items = obj.find('.slides-list');

				items.slick({
					slidesToShow: 1,
					slidesToScroll: 1,
					focusOnSelect: true,
					fade: obj.hasAttr('data-fade') ? obj.data('fade') : false,
					dots: obj.hasAttr('data-dots') ? obj.data('dots') : true,
					speed: obj.hasAttr('data-speed') ? obj.data('speed') : 500,
					arrows: obj.hasAttr('data-arrows') ? obj.data('arrows') : true,
					infinite: obj.hasAttr('data-infinite') ? obj.data('infinite') : false,
					initialSlide: obj.hasAttr('data-start') ? obj.data('start') : 0,
					asNavFor: obj.hasAttr('data-as-nav-for') ? obj.data('as-nav-for') : ''					
				});
			});
		},

		noUiInit: function () {
			var priceSlider = $('.widget_pricefilter .price-slider .slider')[0],
				step = $(priceSlider).data('step'),
				start = $(priceSlider).data('start'),
				stop = $(priceSlider).data('stop'),
				min = $(priceSlider).data('min'),
				max = $(priceSlider).data('max');

			function setPosition () {
				var valuesContainer = $('.price-slider .values-wrapper'),
					containerOffset = $('.price-slider').offset().left;
			}

			if ($('.widget_pricefilter .price-slider').length) {
				noUiSlider.create(priceSlider, {
					start: [start, stop],
					connect: true,
					step: step,
					range: {
						'min': min,
						'max': max
					}
				});
				setTimeout(function () {
					setPosition();
				}, 100);

				var snapValues = [
					document.getElementsByClassName('slider-snap-value-lower')[0],
					document.getElementsByClassName('slider-snap-value-upper')[0]
				];

				priceSlider.noUiSlider.on('update', function( values, handle ) {
					snapValues[handle].innerHTML = parseFloat(values[handle]);
					setPosition();
				});
			}
		},

		toggles: function () {
			// Stats Counter
			function runStats() {
				if ($('.stats-item').visible( true ) && !teslaThemes.statisticsCounterVisible) {
	            	teslaThemes.statisticsCounterVisible = true;
					$('.stats-item .number').each(function () {
					 	var $this = $(this);
					  	jQuery({ Counter: 0 }).animate({ Counter: parseInt($this.find('span').html(), 10) }, {
					    	duration: 3000,
					    	easing: 'swing',
					    	step: function (now) {
					      		$this.find('span').text(Math.ceil(now));
					    	}
					  	});
					});
				}
			
				if ($('.progress-item').visible( true ) && !teslaThemes.progressCounter) {
					teslaThemes.progressCounter = true;
					$('.progress-item .number').each(function () {
					 	var $this = $(this);
					  	jQuery({ Counter: 0 }).animate({ Counter: parseInt($this.html(), 10) }, {
					    	duration: 3000,
					    	easing: 'swing',
					    	step: function (now) {
					      		$this.text(Math.ceil(now));
					      		$this.parent('.heading').parent('.progress-bar').width(Math.ceil(now) + '%');
					    	}
					  	});
					});
				}	
			}

			runStats();

			$(document).scroll(function () {
	            runStats();
			});

			// Sticky header
			if ($('header').hasClass('sticky')) {
				$(window).on('scroll', function () {
					var st = $(this).scrollTop();

					if (st > $('header').outerHeight(true) + 70) {
						$('header').addClass('fixed');
					} else {
						$('header').removeClass('fixed');
					}
				});
			}

			// Mobile Nav Toggle
			$('.mobile-menu-toggle').on('click', function () {
				$('body').toggleClass('mobile-menu-visible');
				return false;
			});

			$('header .main-nav').on('click', function (e) {
				if ($(window).width() < 992) {
					e.stopPropagation();
				}
			});

			$(document).on('click', function () {
				$('body').removeClass('mobile-menu-visible');
			});

			$('.close-mobile-menu').on('click', function(){
				$('body').removeClass('mobile-menu-visible');
			});

			// Mobile Submenus
			$('header .main-nav li.menu-item-has-children > a').on('click', function (e) {
				var obj = $(this);

				if (($(window).width() < 992)) {
					e.preventDefault();
					obj.parent().toggleClass('active');
					obj.next().slideToggle(250);
				}
			});

			// Share Block Toggle
			$('.share-block .block-toggle').on('click', function () {
				$('.share-block').toggleClass('options-visible');
			});

			// Shop Cart
			$('.shopping-cart-wrapper .cart-toggle').on('click', function () {
				$('.shopping-cart-wrapper').toggleClass('active');
				$('.header-profile-form').removeClass( 'form-visible' );
				return false;
			});

			$('html').on('click', function (e) {
				var target = e.target;
				if($(target).hasClass('no-js-action') || $(target).parents().hasClass('no-js-action')) {}
				else {
					$('.shopping-cart-wrapper').removeClass('active');
					$( '.header-profile-form' ).removeClass( 'form-visible' );
					$('.main-header .main-search-form' ).removeClass( 'form-open' );
				}
			});

			// Main Search Form Toggle
			$( '.main-header .search-form-toggle' ).on( 'click', function() {
				$('.main-header .main-search-form' ).addClass( 'form-open' );
				$('.header-profile-form').removeClass( 'form-visible' );
				$('.shopping-cart-wrapper').removeClass('active');
				$('.main-header .main-search-form .input-line' ).focus();

				return false;
			});

			$( '.main-search-form .close-search-form' ).on( 'click', function() {
				$( '.main-header .main-search-form' ).removeClass( 'form-open' );
			});

			// Header Login Form
			$( '.user-profile-block .profile-block-toggle' ).on( 'click', function() {
				// Close forms if any open
				$('.header-profile-form').removeClass( 'form-visible' );
				$('.shopping-cart-wrapper').removeClass('active');

				// Open required form
				$( '.header-profile-form.login-form' ).addClass( 'form-visible' );

				return false;
			});

			$( '.header-profile-form a.forgot-password' ).on( 'click', function( e ) {
				e.preventDefault();

				$( '.header-profile-form' ).removeClass( 'form-visible' );
				$( '.header-profile-form.forgot-password-form' ).addClass( 'form-visible' );

				return false;
			});

			$( '.header-profile-form a.register-form' ).on( 'click', function( e ) {
				e.preventDefault();

				$( '.header-profile-form' ).removeClass( 'form-visible' );
				$( '.header-profile-form.register-form' ).addClass( 'form-visible' );

				return false;
			});

			$( '.header-profile-form .close-form-btn' ).on( 'click', function() {
				$( '.header-profile-form' ).removeClass( 'form-visible' );
			});

			$('.hero-section .scroll-next').on('click', function () {
				var index = $(this).closest('.hero-section').index();
			    $("body").animate({
			         scrollTop: $('.content-wrapper').find('section').eq(index + 1).offset().top
			    }, 900);
			});

			var tabbed = $('.tabbed-content');

			tabbed.each(function (i, val){
				$(this).find('.tabs li').on('click', function(){
					var tab_id = $(this).attr('data-tab');

					$(val).find('.tabs li').removeClass('current');
					$(val).find('.tab-content').fadeOut(0).removeClass('current');

					$(this).fadeIn(800).addClass('current');
					$(val).find("#"+tab_id).fadeIn(800).addClass('current');
				});
			});
		},

		googleMaps: function () {
			function initialize_contact_map (customOptions) {
                var mapOptions = {
                        center: new google.maps.LatLng(customOptions.map_center.lat, customOptions.map_center.lon),
                        zoom: parseInt(customOptions.zoom),
                        scrollwheel: false,
                        disableDefaultUI: true,
                        mapTypeId: google.maps.MapTypeId.ROADMAP,
                        styles: [{ stylers: [{saturation: -100}]}]
                    };
                var contact_map = new google.maps.Map($('#map-canvas')[0], mapOptions),
                    marker = new google.maps.Marker({
                        map: contact_map,
                        position: new google.maps.LatLng(customOptions.marker_coord.lat, customOptions.marker_coord.lon),
                        animation: google.maps.Animation.DROP,
                        icon: customOptions.marker,
                    });
            }

            if ($('#map-canvas').length) {
            	var customOptions = $('#map-canvas').data('options');

                setTimeout(function(){
					google.maps.event.addDomListener(window, 'load', initialize_contact_map(customOptions));
				}, 1000);
            }
		},
	};

	$(document).ready(function(){
		teslaThemes.init();

		setTimeout(function(){
			$('body').addClass('dom-ready');
		}, 300);
	});
}(jQuery));